rename MonoSlicer to Monoslicer (lower-case s)

This commit is contained in:
Armin 2026-07-22 00:33:03 +02:00
commit 9b7c973622
8 changed files with 78 additions and 58 deletions

View file

@ -1,17 +1,17 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.22)
project(MonoSlicer VERSION 1.0.0 LANGUAGES C CXX) project(Monoslicer VERSION 1.0.0 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(lib/JUCE) add_subdirectory(lib/JUCE)
juce_add_plugin(MonoSlicer juce_add_plugin(Monoslicer
COMPANY_NAME "MonoSlicer" COMPANY_NAME "Monoslicer"
PLUGIN_MANUFACTURER_CODE RcSp PLUGIN_MANUFACTURER_CODE RcSp
PLUGIN_CODE MsP1 PLUGIN_CODE MsP1
FORMATS AU VST3 Standalone FORMATS AU VST3 Standalone
PRODUCT_NAME "MonoSlicer" PRODUCT_NAME "Monoslicer"
IS_SYNTH TRUE IS_SYNTH TRUE
NEEDS_MIDI_INPUT TRUE NEEDS_MIDI_INPUT TRUE
NEEDS_MIDI_OUTPUT FALSE NEEDS_MIDI_OUTPUT FALSE
@ -21,7 +21,7 @@ juce_add_plugin(MonoSlicer
VST3_CATEGORIES Instrument Sampler VST3_CATEGORIES Instrument Sampler
) )
target_sources(MonoSlicer PRIVATE target_sources(Monoslicer PRIVATE
Source/PluginProcessor.cpp Source/PluginProcessor.cpp
Source/PluginEditor.cpp Source/PluginEditor.cpp
Source/SliceManager.cpp Source/SliceManager.cpp
@ -29,13 +29,13 @@ target_sources(MonoSlicer PRIVATE
Source/PianoRollDisplay.cpp Source/PianoRollDisplay.cpp
) )
target_compile_definitions(MonoSlicer PUBLIC target_compile_definitions(Monoslicer PUBLIC
JUCE_WEB_BROWSER=0 JUCE_WEB_BROWSER=0
JUCE_USE_CURL=0 JUCE_USE_CURL=0
JUCE_VST3_CAN_REPLACE_VST2=0 JUCE_VST3_CAN_REPLACE_VST2=0
) )
target_link_libraries(MonoSlicer target_link_libraries(Monoslicer
PRIVATE PRIVATE
juce::juce_audio_utils juce::juce_audio_utils
juce::juce_audio_processors juce::juce_audio_processors

View file

@ -20,18 +20,18 @@ configure: fetch
cmake -B $(BUILD_DIR) -S . $(CMAKE_ARGS) cmake -B $(BUILD_DIR) -S . $(CMAKE_ARGS)
build: configure build: configure
@echo ">>> Building MonoSlicer..." @echo ">>> Building Monoslicer..."
cmake --build $(BUILD_DIR) -j$$(sysctl -n hw.ncpu) cmake --build $(BUILD_DIR) -j$$(sysctl -n hw.ncpu)
install: build install: build
@echo ">>> Installing plugins..." @echo ">>> Installing plugins..."
mkdir -p ~/Library/Audio/Plug-Ins/Components mkdir -p ~/Library/Audio/Plug-Ins/Components
mkdir -p ~/Library/Audio/Plug-Ins/VST3 mkdir -p ~/Library/Audio/Plug-Ins/VST3
cp -R $(BUILD_DIR)/MonoSlicer_artefacts/Release/AU/MonoSlicer.component ~/Library/Audio/Plug-Ins/Components/ cp -R $(BUILD_DIR)/Monoslicer_artefacts/Release/AU/Monoslicer.component ~/Library/Audio/Plug-Ins/Components/
cp -R $(BUILD_DIR)/MonoSlicer_artefacts/Release/VST3/MonoSlicer.vst3 ~/Library/Audio/Plug-Ins/VST3/ cp -R $(BUILD_DIR)/Monoslicer_artefacts/Release/VST3/Monoslicer.vst3 ~/Library/Audio/Plug-Ins/VST3/
@echo ">>> Rescanning Audio Units..." @echo ">>> Rescanning Audio Units..."
killall -9 AudioComponentRegistrar 2>/dev/null; true killall -9 AudioComponentRegistrar 2>/dev/null; true
@echo ">>> Done. MonoSlicer installed as AU and VST3." @echo ">>> Done. Monoslicer installed as AU and VST3."
clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)

View file

@ -1,4 +1,4 @@
# MonoSlicer # Monoslicer
A monophonic sample slicer and sampler instrument built with [JUCE](https://juce.com/) and CMake. A monophonic sample slicer and sampler instrument built with [JUCE](https://juce.com/) and CMake.
@ -6,7 +6,7 @@ Load an audio file, slice it into regions (automatically via onset detection or
## Screenshot ## Screenshot
![MonoSlicer](monoslicershot.png) ![Monoslicer](monoslicershot.png)
## Features ## Features
@ -31,7 +31,7 @@ Requires CMake 3.22+ and a C++17 compiler.
make # Fetch JUCE, configure, build, and install (AU + VST3) make # Fetch JUCE, configure, build, and install (AU + VST3)
``` ```
Running `make` with no arguments will fetch JUCE, build MonoSlicer in Release mode, copy the AU and VST3 plugins to your system directories, and trigger an Audio Unit rescan. Running `make` with no arguments will fetch JUCE, build Monoslicer in Release mode, copy the AU and VST3 plugins to your system directories, and trigger an Audio Unit rescan.
Individual targets are also available: Individual targets are also available:

View file

@ -1,6 +1,6 @@
#include "PluginEditor.h" #include "PluginEditor.h"
MonoSlicerEditor::MonoSlicerEditor(MonoSlicerProcessor& p) MonoslicerEditor::MonoslicerEditor(MonoslicerProcessor& p)
: AudioProcessorEditor(p), : AudioProcessorEditor(p),
processorRef(p), processorRef(p),
waveformDisplay(p.getSliceManager()) waveformDisplay(p.getSliceManager())
@ -16,6 +16,7 @@ MonoSlicerEditor::MonoSlicerEditor(MonoSlicerProcessor& p)
}; };
setupTitleBtn(loadSampleButton, "Load audio file"); setupTitleBtn(loadSampleButton, "Load audio file");
setupTitleBtn(clearSampleButton, "Clear loaded sample");
setupTitleBtn(prevSampleButton, "Previous sample in folder"); setupTitleBtn(prevSampleButton, "Previous sample in folder");
setupTitleBtn(nextSampleButton, "Next sample in folder"); setupTitleBtn(nextSampleButton, "Next sample in folder");
setupTitleBtn(undoButton, "Undo"); setupTitleBtn(undoButton, "Undo");
@ -182,12 +183,13 @@ MonoSlicerEditor::MonoSlicerEditor(MonoSlicerProcessor& p)
startTimerHz(30); startTimerHz(30);
} }
MonoSlicerEditor::~MonoSlicerEditor() MonoslicerEditor::~MonoslicerEditor()
{ {
autoSliceButton.removeListener(this); autoSliceButton.removeListener(this);
clearSlicesButton.removeListener(this); clearSlicesButton.removeListener(this);
scaleComboBox.removeListener(this); scaleComboBox.removeListener(this);
loadSampleButton.removeListener(this); loadSampleButton.removeListener(this);
clearSampleButton.removeListener(this);
prevSampleButton.removeListener(this); prevSampleButton.removeListener(this);
nextSampleButton.removeListener(this); nextSampleButton.removeListener(this);
undoButton.removeListener(this); undoButton.removeListener(this);
@ -198,7 +200,7 @@ MonoSlicerEditor::~MonoSlicerEditor()
stretchButton.removeListener(this); stretchButton.removeListener(this);
} }
void MonoSlicerEditor::setupSlider(juce::Slider& slider, juce::Label& label, const juce::String& name) void MonoslicerEditor::setupSlider(juce::Slider& slider, juce::Label& label, const juce::String& name)
{ {
addAndMakeVisible(slider); addAndMakeVisible(slider);
addAndMakeVisible(label); addAndMakeVisible(label);
@ -208,14 +210,14 @@ void MonoSlicerEditor::setupSlider(juce::Slider& slider, juce::Label& label, con
label.setFont(juce::Font(juce::FontOptions(13.0f))); label.setFont(juce::Font(juce::FontOptions(13.0f)));
} }
void MonoSlicerEditor::attachSlider(juce::Slider& slider, juce::Label& label, const juce::String& name, void MonoslicerEditor::attachSlider(juce::Slider& slider, juce::Label& label, const juce::String& name,
const juce::String& paramId, std::unique_ptr<SliderAttachment>& attachment) const juce::String& paramId, std::unique_ptr<SliderAttachment>& attachment)
{ {
setupSlider(slider, label, name); setupSlider(slider, label, name);
attachment = std::make_unique<SliderAttachment>(processorRef.getAPVTS(), paramId, slider); attachment = std::make_unique<SliderAttachment>(processorRef.getAPVTS(), paramId, slider);
} }
void MonoSlicerEditor::paint(juce::Graphics& g) void MonoslicerEditor::paint(juce::Graphics& g)
{ {
g.fillAll(juce::Colour(0xff0f0f1a)); g.fillAll(juce::Colour(0xff0f0f1a));
@ -232,7 +234,7 @@ void MonoSlicerEditor::paint(juce::Graphics& g)
g.drawHorizontalLine(40, 0.0f, static_cast<float>(getWidth())); g.drawHorizontalLine(40, 0.0f, static_cast<float>(getWidth()));
} }
void MonoSlicerEditor::resized() void MonoslicerEditor::resized()
{ {
float scaleX = static_cast<float>(getWidth()) / static_cast<float>(baseWidth); float scaleX = static_cast<float>(getWidth()) / static_cast<float>(baseWidth);
float scaleY = static_cast<float>(getHeight()) / static_cast<float>(baseHeight); float scaleY = static_cast<float>(getHeight()) / static_cast<float>(baseHeight);
@ -249,6 +251,7 @@ void MonoSlicerEditor::resized()
}; };
placeBtn(loadSampleButton, 44); placeBtn(loadSampleButton, 44);
placeBtn(clearSampleButton, 44);
placeBtn(prevSampleButton, 24); placeBtn(prevSampleButton, 24);
placeBtn(nextSampleButton, 24); placeBtn(nextSampleButton, 24);
@ -339,7 +342,7 @@ void MonoSlicerEditor::resized()
waveformDisplay.setBounds(mainArea); waveformDisplay.setBounds(mainArea);
} }
void MonoSlicerEditor::timerCallback() void MonoslicerEditor::timerCallback()
{ {
if (processorRef.stateRestored.exchange(false)) if (processorRef.stateRestored.exchange(false))
{ {
@ -362,7 +365,7 @@ void MonoSlicerEditor::timerCallback()
} }
} }
void MonoSlicerEditor::buttonClicked(juce::Button* button) void MonoslicerEditor::buttonClicked(juce::Button* button)
{ {
if (button == &loadSampleButton) if (button == &loadSampleButton)
{ {
@ -378,6 +381,11 @@ void MonoSlicerEditor::buttonClicked(juce::Button* button)
} }
}); });
} }
else if (button == &clearSampleButton)
{
processorRef.clearSample();
waveformDisplay.setSampleBuffer(&processorRef.getSampleBuffer(), processorRef.getSampleRateLoaded());
}
else if (button == &prevSampleButton) else if (button == &prevSampleButton)
{ {
processorRef.loadPreviousSample(); processorRef.loadPreviousSample();
@ -440,7 +448,7 @@ void MonoSlicerEditor::buttonClicked(juce::Button* button)
} }
} }
void MonoSlicerEditor::comboBoxChanged(juce::ComboBox* comboBoxThatHasChanged) void MonoslicerEditor::comboBoxChanged(juce::ComboBox* comboBoxThatHasChanged)
{ {
if (comboBoxThatHasChanged == &scaleComboBox) if (comboBoxThatHasChanged == &scaleComboBox)
{ {
@ -454,7 +462,7 @@ void MonoSlicerEditor::comboBoxChanged(juce::ComboBox* comboBoxThatHasChanged)
} }
} }
bool MonoSlicerEditor::isInterestedInFileDrag(const juce::StringArray& files) bool MonoslicerEditor::isInterestedInFileDrag(const juce::StringArray& files)
{ {
for (const auto& f : files) for (const auto& f : files)
if (f.endsWithIgnoreCase(".wav") || f.endsWithIgnoreCase(".aiff") || if (f.endsWithIgnoreCase(".wav") || f.endsWithIgnoreCase(".aiff") ||
@ -463,7 +471,7 @@ bool MonoSlicerEditor::isInterestedInFileDrag(const juce::StringArray& files)
return false; return false;
} }
void MonoSlicerEditor::filesDropped(const juce::StringArray& files, int, int) void MonoslicerEditor::filesDropped(const juce::StringArray& files, int, int)
{ {
for (const auto& f : files) for (const auto& f : files)
{ {

View file

@ -3,15 +3,15 @@
#include "PluginProcessor.h" #include "PluginProcessor.h"
#include "WaveformDisplay.h" #include "WaveformDisplay.h"
class MonoSlicerEditor : public juce::AudioProcessorEditor, class MonoslicerEditor : public juce::AudioProcessorEditor,
private juce::FileDragAndDropTarget, private juce::FileDragAndDropTarget,
private juce::Button::Listener, private juce::Button::Listener,
private juce::ComboBox::Listener, private juce::ComboBox::Listener,
private juce::Timer private juce::Timer
{ {
public: public:
MonoSlicerEditor(MonoSlicerProcessor&); MonoslicerEditor(MonoslicerProcessor&);
~MonoSlicerEditor() override; ~MonoslicerEditor() override;
void paint(juce::Graphics&) override; void paint(juce::Graphics&) override;
void resized() override; void resized() override;
@ -23,7 +23,7 @@ public:
void timerCallback() override; void timerCallback() override;
private: private:
MonoSlicerProcessor& processorRef; MonoslicerProcessor& processorRef;
WaveformDisplay waveformDisplay; WaveformDisplay waveformDisplay;
@ -33,6 +33,7 @@ private:
// Title bar buttons // Title bar buttons
juce::TextButton loadSampleButton { "Load" }; juce::TextButton loadSampleButton { "Load" };
juce::TextButton clearSampleButton { "Clear" };
juce::TextButton prevSampleButton { "<" }; juce::TextButton prevSampleButton { "<" };
juce::TextButton nextSampleButton { ">" }; juce::TextButton nextSampleButton { ">" };
juce::TextButton undoButton { "Undo" }; juce::TextButton undoButton { "Undo" };
@ -94,5 +95,5 @@ private:
int keyClickNote = -1; int keyClickNote = -1;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MonoSlicerEditor) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MonoslicerEditor)
}; };

View file

@ -1,7 +1,7 @@
#include "PluginProcessor.h" #include "PluginProcessor.h"
#include "PluginEditor.h" #include "PluginEditor.h"
MonoSlicerProcessor::MonoSlicerProcessor() MonoslicerProcessor::MonoslicerProcessor()
: AudioProcessor(BusesProperties() : AudioProcessor(BusesProperties()
.withInput("Input", juce::AudioChannelSet::stereo(), true) .withInput("Input", juce::AudioChannelSet::stereo(), true)
.withOutput("Output", juce::AudioChannelSet::stereo(), true)), .withOutput("Output", juce::AudioChannelSet::stereo(), true)),
@ -10,9 +10,9 @@ MonoSlicerProcessor::MonoSlicerProcessor()
formatManager.registerBasicFormats(); formatManager.registerBasicFormats();
} }
MonoSlicerProcessor::~MonoSlicerProcessor() {} MonoslicerProcessor::~MonoslicerProcessor() {}
juce::AudioProcessorValueTreeState::ParameterLayout MonoSlicerProcessor::createParameterLayout() juce::AudioProcessorValueTreeState::ParameterLayout MonoslicerProcessor::createParameterLayout()
{ {
juce::AudioProcessorValueTreeState::ParameterLayout layout; juce::AudioProcessorValueTreeState::ParameterLayout layout;
@ -88,15 +88,15 @@ juce::AudioProcessorValueTreeState::ParameterLayout MonoSlicerProcessor::createP
return layout; return layout;
} }
void MonoSlicerProcessor::prepareToPlay(double sampleRate, int samplesPerBlock) void MonoslicerProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
{ {
currentSampleRate = sampleRate; currentSampleRate = sampleRate;
juce::ignoreUnused(samplesPerBlock); juce::ignoreUnused(samplesPerBlock);
} }
void MonoSlicerProcessor::releaseResources() {} void MonoslicerProcessor::releaseResources() {}
void MonoSlicerProcessor::computeBiquadCoeffs(FilterType type, float cutoff, float resonance, void MonoslicerProcessor::computeBiquadCoeffs(FilterType type, float cutoff, float resonance,
float sampleRate, float& b0, float& b1, float& b2, float sampleRate, float& b0, float& b1, float& b2,
float& a1, float& a2) float& a1, float& a2)
{ {
@ -163,7 +163,7 @@ void MonoSlicerProcessor::computeBiquadCoeffs(FilterType type, float cutoff, flo
} }
} }
void MonoSlicerProcessor::advanceAmpEnvelope(Voice& voice, int samples) void MonoslicerProcessor::advanceAmpEnvelope(Voice& voice, int samples)
{ {
float attack = apvts.getRawParameterValue("ampAttack")->load(); float attack = apvts.getRawParameterValue("ampAttack")->load();
float decay = apvts.getRawParameterValue("ampDecay")->load(); float decay = apvts.getRawParameterValue("ampDecay")->load();
@ -221,7 +221,7 @@ void MonoSlicerProcessor::advanceAmpEnvelope(Voice& voice, int samples)
} }
} }
void MonoSlicerProcessor::advanceFilterEnvelope(Voice& voice, int samples) void MonoslicerProcessor::advanceFilterEnvelope(Voice& voice, int samples)
{ {
float attack = apvts.getRawParameterValue("filterAttack")->load(); float attack = apvts.getRawParameterValue("filterAttack")->load();
float decay = apvts.getRawParameterValue("filterDecay")->load(); float decay = apvts.getRawParameterValue("filterDecay")->load();
@ -273,7 +273,7 @@ void MonoSlicerProcessor::advanceFilterEnvelope(Voice& voice, int samples)
} }
} }
void MonoSlicerProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages) void MonoslicerProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{ {
juce::ScopedNoDenormals noDenormals; juce::ScopedNoDenormals noDenormals;
buffer.clear(); buffer.clear();
@ -446,7 +446,7 @@ void MonoSlicerProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::M
currentPlaybackSample.store(-1); currentPlaybackSample.store(-1);
} }
void MonoSlicerProcessor::handleNoteOn(int noteNumber, float velocity) void MonoslicerProcessor::handleNoteOn(int noteNumber, float velocity)
{ {
int offset = static_cast<int>(apvts.getRawParameterValue("octaveOffset")->load()) * 12; int offset = static_cast<int>(apvts.getRawParameterValue("octaveOffset")->load()) * 12;
int sliceIdx = noteNumber - 60 + offset; int sliceIdx = noteNumber - 60 + offset;
@ -479,7 +479,7 @@ void MonoSlicerProcessor::handleNoteOn(int noteNumber, float velocity)
} }
} }
void MonoSlicerProcessor::handleNoteOff() void MonoslicerProcessor::handleNoteOff()
{ {
for (auto& voice : voices) for (auto& voice : voices)
{ {
@ -491,7 +491,7 @@ void MonoSlicerProcessor::handleNoteOff()
} }
} }
void MonoSlicerProcessor::loadAudioFile(const juce::File& file) void MonoslicerProcessor::loadAudioFile(const juce::File& file)
{ {
std::unique_ptr<juce::AudioFormatReader> reader(formatManager.createReaderFor(file)); std::unique_ptr<juce::AudioFormatReader> reader(formatManager.createReaderFor(file));
if (reader) if (reader)
@ -507,7 +507,17 @@ void MonoSlicerProcessor::loadAudioFile(const juce::File& file)
} }
} }
void MonoSlicerProcessor::refreshFolderList() void MonoslicerProcessor::clearSample()
{
sampleBuffer.setSize(0, 0);
currentFile = juce::File{};
folderFiles.clear();
currentFileIndex = -1;
sliceManager.setSampleBuffer(&sampleBuffer, loadedSampleRate);
selectedSlice.store(-1);
}
void MonoslicerProcessor::refreshFolderList()
{ {
folderFiles.clear(); folderFiles.clear();
currentFileIndex = -1; currentFileIndex = -1;
@ -527,37 +537,37 @@ void MonoSlicerProcessor::refreshFolderList()
} }
} }
void MonoSlicerProcessor::loadNextSample() void MonoslicerProcessor::loadNextSample()
{ {
if (folderFiles.isEmpty()) return; if (folderFiles.isEmpty()) return;
int nextIdx = (currentFileIndex + 1) % folderFiles.size(); int nextIdx = (currentFileIndex + 1) % folderFiles.size();
loadAudioFile(folderFiles[nextIdx]); loadAudioFile(folderFiles[nextIdx]);
} }
void MonoSlicerProcessor::loadPreviousSample() void MonoslicerProcessor::loadPreviousSample()
{ {
if (folderFiles.isEmpty()) return; if (folderFiles.isEmpty()) return;
int prevIdx = (currentFileIndex - 1 + folderFiles.size()) % folderFiles.size(); int prevIdx = (currentFileIndex - 1 + folderFiles.size()) % folderFiles.size();
loadAudioFile(folderFiles[prevIdx]); loadAudioFile(folderFiles[prevIdx]);
} }
void MonoSlicerProcessor::triggerSlice(int sliceIndex, float velocity) void MonoslicerProcessor::triggerSlice(int sliceIndex, float velocity)
{ {
int noteNumber = sliceIndex + 60; int noteNumber = sliceIndex + 60;
handleNoteOn(noteNumber, velocity); handleNoteOn(noteNumber, velocity);
} }
void MonoSlicerProcessor::releaseSlice() void MonoslicerProcessor::releaseSlice()
{ {
handleNoteOff(); handleNoteOff();
} }
juce::AudioProcessorEditor* MonoSlicerProcessor::createEditor() juce::AudioProcessorEditor* MonoslicerProcessor::createEditor()
{ {
return new MonoSlicerEditor(*this); return new MonoslicerEditor(*this);
} }
void MonoSlicerProcessor::getStateInformation(juce::MemoryBlock& destData) void MonoslicerProcessor::getStateInformation(juce::MemoryBlock& destData)
{ {
auto state = apvts.copyState(); auto state = apvts.copyState();
@ -592,7 +602,7 @@ void MonoSlicerProcessor::getStateInformation(juce::MemoryBlock& destData)
} }
} }
void MonoSlicerProcessor::setStateInformation(const void* data, int sizeInBytes) void MonoslicerProcessor::setStateInformation(const void* data, int sizeInBytes)
{ {
auto stream = juce::MemoryInputStream(data, static_cast<size_t>(sizeInBytes), false); auto stream = juce::MemoryInputStream(data, static_cast<size_t>(sizeInBytes), false);
auto state = juce::ValueTree::readFromStream(stream); auto state = juce::ValueTree::readFromStream(stream);
@ -661,10 +671,10 @@ void MonoSlicerProcessor::setStateInformation(const void* data, int sizeInBytes)
juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{ {
return new MonoSlicerProcessor(); return new MonoslicerProcessor();
} }
void MonoSlicerProcessor::stretchToBeats(int numBeats, float bpm) void MonoslicerProcessor::stretchToBeats(int numBeats, float bpm)
{ {
if (sampleBuffer.getNumSamples() == 0 || bpm <= 0.0f || numBeats <= 0) return; if (sampleBuffer.getNumSamples() == 0 || bpm <= 0.0f || numBeats <= 0) return;

View file

@ -4,11 +4,11 @@
#include <juce_dsp/juce_dsp.h> #include <juce_dsp/juce_dsp.h>
#include "SliceManager.h" #include "SliceManager.h"
class MonoSlicerProcessor : public juce::AudioProcessor class MonoslicerProcessor : public juce::AudioProcessor
{ {
public: public:
MonoSlicerProcessor(); MonoslicerProcessor();
~MonoSlicerProcessor() override; ~MonoslicerProcessor() override;
void prepareToPlay(double sampleRate, int samplesPerBlock) override; void prepareToPlay(double sampleRate, int samplesPerBlock) override;
void releaseResources() override; void releaseResources() override;
@ -34,6 +34,7 @@ public:
void setStateInformation(const void* data, int sizeInBytes) override; void setStateInformation(const void* data, int sizeInBytes) override;
void loadAudioFile(const juce::File& file); void loadAudioFile(const juce::File& file);
void clearSample();
void loadNextSample(); void loadNextSample();
void loadPreviousSample(); void loadPreviousSample();
void triggerSlice(int sliceIndex, float velocity = 0.8f); void triggerSlice(int sliceIndex, float velocity = 0.8f);
@ -123,5 +124,5 @@ private:
void computeBiquadCoeffs(FilterType type, float cutoff, float resonance, float sampleRate, void computeBiquadCoeffs(FilterType type, float cutoff, float resonance, float sampleRate,
float& b0, float& b1, float& b2, float& a1, float& a2); float& b0, float& b1, float& b2, float& a1, float& a2);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MonoSlicerProcessor) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MonoslicerProcessor)
}; };

View file

@ -208,7 +208,7 @@ void WaveformDisplay::paint(juce::Graphics& g)
auto textArea = bounds.withTrimmedBottom(scrollbarHeight); auto textArea = bounds.withTrimmedBottom(scrollbarHeight);
g.setColour(juce::Colours::grey); g.setColour(juce::Colours::grey);
g.setFont(14.0f); g.setFont(14.0f);
g.drawText("Drop or load an audio file", textArea, juce::Justification::centred); g.drawText("No audio file loaded.", textArea, juce::Justification::centred);
hScrollBar.setBounds(bounds.removeFromBottom(scrollbarHeight).toNearestInt()); hScrollBar.setBounds(bounds.removeFromBottom(scrollbarHeight).toNearestInt());
return; return;
} }