diff --git a/Source/FilePicker.cpp b/Source/FilePicker.cpp index 38517c0..6ddf8ab 100644 --- a/Source/FilePicker.cpp +++ b/Source/FilePicker.cpp @@ -6,24 +6,26 @@ #include "MyColours.h" FilePicker::FilePicker( - FluidSynthModel* fluidSynthModel + AudioProcessorValueTreeState& valueTreeState, + FluidSynthModel& fluidSynthModel ) -: fileChooser( - "File", - File(), - true, - false, - false, - "*.sf2;*.sf3", - String(), - "Choose a Soundfont file to load into the synthesizer" -), - fluidSynthModel(fluidSynthModel), - currentPath() { +: fileChooser{ + "File", + File(), + true, + false, + false, + "*.sf2;*.sf3", + String(), + "Choose a Soundfont file to load into the synthesizer"} +, valueTreeState{valueTreeState} +, fluidSynthModel{fluidSynthModel} +// , currentPath{} +{ // faster (rounded edges introduce transparency) setOpaque (true); - setDisplayedFilePath(fluidSynthModel->getCurrentSoundFontAbsPath()); + setDisplayedFilePath(fluidSynthModel.getCurrentSoundFontAbsPath()); addAndMakeVisible (fileChooser); fileChooser.addListener (this); @@ -47,7 +49,7 @@ void FilePicker::paint(Graphics& g) void FilePicker::filenameComponentChanged (FilenameComponent*) { currentPath = fileChooser.getCurrentFile().getFullPathName(); - fluidSynthModel->onFileNameChanged(fileChooser.getCurrentFile().getFullPathName(), -1, -1); + fluidSynthModel.onFileNameChanged(fileChooser.getCurrentFile().getFullPathName(), -1, -1); } void FilePicker::setDisplayedFilePath(const String& path) { diff --git a/Source/FilePicker.h b/Source/FilePicker.h index 8a1c3bc..c187724 100644 --- a/Source/FilePicker.h +++ b/Source/FilePicker.h @@ -14,7 +14,8 @@ class FilePicker: public Component, { public: FilePicker( - FluidSynthModel* fluidSynthModel + AudioProcessorValueTreeState& valueTreeState, + FluidSynthModel& fluidSynthModel ); ~FilePicker(); @@ -25,7 +26,8 @@ public: private: FilenameComponent fileChooser; - FluidSynthModel* fluidSynthModel; + AudioProcessorValueTreeState& valueTreeState; + FluidSynthModel& fluidSynthModel; String currentPath; diff --git a/Source/FluidSynthModel.cpp b/Source/FluidSynthModel.cpp index 085323f..27ab5fd 100644 --- a/Source/FluidSynthModel.cpp +++ b/Source/FluidSynthModel.cpp @@ -3,33 +3,46 @@ // #include +#include #include "FluidSynthModel.h" #include "MidiConstants.h" +#include "Util.h" using namespace std; -FluidSynthModel::FluidSynthModel(shared_ptr sharedParams) - : sharedParams{sharedParams}, - synth{nullptr}, - settings{nullptr}, - currentSoundFontAbsPath{}, - currentSampleRate{44100}, - initialised{false}, - sfont_id{0}, - channel{0}/*, - mod(nullptr)*/ +FluidSynthModel::FluidSynthModel( + AudioProcessorValueTreeState& valueTreeState, + SharesParams& sharedParams + ) +: valueTreeState{valueTreeState} +, sharedParams{sharedParams} +//, synth{nullptr} +, settings{nullptr, nullptr} +, currentSoundFontAbsPath{} +, currentSampleRate{44100} +, initialised{false} +, sfont_id{0} +, channel{0}/*, +mod(nullptr)*/ {} -FluidSynthModel::~FluidSynthModel() { - if (initialised) { +// FluidSynthModel::~FluidSynthModel() { + // if (initialised) { // delete_fluid_audio_driver(driver); - delete_fluid_synth(synth); - delete_fluid_settings(settings); + // delete_fluid_synth(synth); +// delete_fluid_settings(settings); // delete driver; // delete settings; // delete_fluid_mod(mod); - } + // } +// } + +int FluidSynthModel::handleMidiEvent(void* data, fluid_midi_event_t* event) +{ +// DEBUG_PRINT(fluid_midi_event_get_type(event)); + // printf("event type: %d\n", fluid_midi_event_get_type(event)); + return 0; } void FluidSynthModel::initialise() { @@ -37,26 +50,47 @@ void FluidSynthModel::initialise() { // delete_fluid_synth(synth); // delete_fluid_settings(settings); // } + settings = { new_fluid_settings(), delete_fluid_settings }; + // deactivate all audio drivers in fluidsynth to avoid FL Studio deadlock when initialising CoreAudio // after all: we only use fluidsynth to render blocks of audio. it doesn't output to audio driver. - const char *DRV[] = {NULL}; + const char *DRV[] {NULL}; fluid_audio_driver_register(DRV); + +// handle_midi_event_func_t handler = [](void* data, fluid_midi_event_t* event) -> int { +// +// }; + +// midiDriver = unique_ptr( +// new_fluid_midi_driver( +// settings.get(), +// [](void* data, fluid_midi_event_t* event) -> int { +// +// }, +// nullptr), +// delete_fluid_midi_driver); - settings = new_fluid_settings(); + // https://sourceforge.net/p/fluidsynth/wiki/FluidSettings/ #if JUCE_DEBUG - fluid_settings_setint(settings, "synth.verbose", 1); + fluid_settings_setint(settings.get(), "synth.verbose", 1); #endif - synth = new_fluid_synth(settings); - fluid_synth_set_sample_rate(synth, currentSampleRate); + synth = { new_fluid_synth(settings.get()), delete_fluid_synth }; + fluid_synth_set_sample_rate(synth.get(), currentSampleRate); - if (sharedParams->getSoundFontPath().isNotEmpty()) { - loadFont(sharedParams->getSoundFontPath()); - changePreset(sharedParams->getBank(), sharedParams->getPreset()); + valueTreeState.getParameter("soundFontPath")->getValue(); + // RangedAudioParameter *param {valueTreeState.getParameter("release")}; + // jassert(dynamic_cast (param) != nullptr); + // AudioParameterInt* castParam {dynamic_cast (param)}; + // *castParam = m.getControllerValue(); + + if (sharedParams.getSoundFontPath().isNotEmpty()) { + loadFont(sharedParams.getSoundFontPath()); +// changePreset(sharedParams->getBank(), sharedParams->getPreset()); } - fluid_synth_set_gain(synth, 2.0); + fluid_synth_set_gain(synth.get(), 2.0); for(int i{SOUND_CTRL1}; i <= SOUND_CTRL10; i++) { @@ -81,90 +115,84 @@ void FluidSynthModel::initialise() { // all SOUND_CTRL are inited with value of 64, not zero. // "Just like panning, a value of 64 indicates no change for sound ctrls" - fluid_mod_t *mod(new_fluid_mod()); + unique_ptr mod{new_fluid_mod(), delete_fluid_mod}; // - fluid_mod_set_source1(mod, + fluid_mod_set_source1(mod.get(), static_cast(SOUND_CTRL2), // MIDI CC 71 Timbre/Harmonic Intensity (filter resonance) FLUID_MOD_CC | FLUID_MOD_UNIPOLAR | FLUID_MOD_CONCAVE | FLUID_MOD_POSITIVE); - fluid_mod_set_source2(mod, 0, 0); - fluid_mod_set_dest(mod, GEN_FILTERQ); - fluid_mod_set_amount(mod, FLUID_PEAK_ATTENUATION); - fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD); - delete_fluid_mod(mod); + fluid_mod_set_source2(mod.get(), 0, 0); + fluid_mod_set_dest(mod.get(), GEN_FILTERQ); + fluid_mod_set_amount(mod.get(), FLUID_PEAK_ATTENUATION); + fluid_synth_add_default_mod(synth.get(), mod.get(), FLUID_SYNTH_ADD); - mod = new_fluid_mod(); - fluid_mod_set_source1(mod, + mod = {new_fluid_mod(), delete_fluid_mod}; + fluid_mod_set_source1(mod.get(), static_cast(SOUND_CTRL3), // MIDI CC 72 Release time FLUID_MOD_CC | FLUID_MOD_UNIPOLAR | FLUID_MOD_LINEAR | FLUID_MOD_POSITIVE); - fluid_mod_set_source2(mod, 0, 0); - fluid_mod_set_dest(mod, GEN_VOLENVRELEASE); -// fluid_mod_set_amount(mod, 15200.0f); - fluid_mod_set_amount(mod, env_amount); - fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD); - delete_fluid_mod(mod); + fluid_mod_set_source2(mod.get(), 0, 0); + fluid_mod_set_dest(mod.get(), GEN_VOLENVRELEASE); +// fluid_mod_set_amount(mod.get(), 15200.0f); + fluid_mod_set_amount(mod.get(), env_amount); + fluid_synth_add_default_mod(synth.get(), mod.get(), FLUID_SYNTH_ADD); - mod = new_fluid_mod(); - fluid_mod_set_source1(mod, + mod = {new_fluid_mod(), delete_fluid_mod}; + fluid_mod_set_source1(mod.get(), static_cast(SOUND_CTRL4), // MIDI CC 73 Attack time FLUID_MOD_CC | FLUID_MOD_UNIPOLAR | FLUID_MOD_LINEAR | FLUID_MOD_POSITIVE); - fluid_mod_set_source2(mod, 0, 0); - fluid_mod_set_dest(mod, GEN_VOLENVATTACK); - fluid_mod_set_amount(mod, env_amount); - fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD); - delete_fluid_mod(mod); + fluid_mod_set_source2(mod.get(), 0, 0); + fluid_mod_set_dest(mod.get(), GEN_VOLENVATTACK); + fluid_mod_set_amount(mod.get(), env_amount); + fluid_synth_add_default_mod(synth.get(), mod.get(), FLUID_SYNTH_ADD); // soundfont spec says that if cutoff is >20kHz and resonance Q is 0, then no filtering occurs - mod = new_fluid_mod(); - fluid_mod_set_source1(mod, + mod = {new_fluid_mod(), delete_fluid_mod}; + fluid_mod_set_source1(mod.get(), static_cast(SOUND_CTRL5), // MIDI CC 74 Brightness (cutoff frequency, FILTERFC) FLUID_MOD_CC | FLUID_MOD_LINEAR | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE); - fluid_mod_set_source2(mod, 0, 0); - fluid_mod_set_dest(mod, GEN_FILTERFC); - fluid_mod_set_amount(mod, -2400.0f); - fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD); - delete_fluid_mod(mod); + fluid_mod_set_source2(mod.get(), 0, 0); + fluid_mod_set_dest(mod.get(), GEN_FILTERFC); + fluid_mod_set_amount(mod.get(), -2400.0f); + fluid_synth_add_default_mod(synth.get(), mod.get(), FLUID_SYNTH_ADD); - mod = new_fluid_mod(); - fluid_mod_set_source1(mod, + mod = {new_fluid_mod(), delete_fluid_mod}; + fluid_mod_set_source1(mod.get(), static_cast(SOUND_CTRL6), // MIDI CC 75 Decay Time FLUID_MOD_CC | FLUID_MOD_UNIPOLAR | FLUID_MOD_LINEAR | FLUID_MOD_POSITIVE); - fluid_mod_set_source2(mod, 0, 0); - fluid_mod_set_dest(mod, GEN_VOLENVDECAY); - fluid_mod_set_amount(mod, env_amount); - fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD); - delete_fluid_mod(mod); + fluid_mod_set_source2(mod.get(), 0, 0); + fluid_mod_set_dest(mod.get(), GEN_VOLENVDECAY); + fluid_mod_set_amount(mod.get(), env_amount); + fluid_synth_add_default_mod(synth.get(), mod.get(), FLUID_SYNTH_ADD); - mod = new_fluid_mod(); - fluid_mod_set_source1(mod, + mod = {new_fluid_mod(), delete_fluid_mod}; + fluid_mod_set_source1(mod.get(), static_cast(SOUND_CTRL10), // MIDI CC 79 undefined FLUID_MOD_CC | FLUID_MOD_UNIPOLAR | FLUID_MOD_CONCAVE | FLUID_MOD_POSITIVE); - fluid_mod_set_source2(mod, 0, 0); - fluid_mod_set_dest(mod, GEN_VOLENVSUSTAIN); + fluid_mod_set_source2(mod.get(), 0, 0); + fluid_mod_set_dest(mod.get(), GEN_VOLENVSUSTAIN); // fluice_voice.c#fluid_voice_update_param() // clamps the range to between 0 and 1000, so we'll copy that - fluid_mod_set_amount(mod, 1000.0f); - fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD); - delete_fluid_mod(mod); + fluid_mod_set_amount(mod.get(), 1000.0f); + fluid_synth_add_default_mod(synth.get(), mod.get(), FLUID_SYNTH_ADD); - initialised = true; + // initialised = true; } void FluidSynthModel::setControllerValue(int controller, int value) { @@ -173,7 +201,7 @@ void FluidSynthModel::setControllerValue(int controller, int value) { fluid_midi_event_set_channel(midi_event, channel); fluid_midi_event_set_control(midi_event, controller); fluid_midi_event_set_value(midi_event, value); - fluid_synth_handle_midi_event(synth, midi_event); + fluid_synth_handle_midi_event(synth.get(), midi_event); delete_fluid_midi_event(midi_event); // fluid_channel_set_cc(channel, i, 0); } @@ -189,16 +217,16 @@ void FluidSynthModel::changePreset(int bank, int preset) { preset = bankAndPreset->getPreset(); } changePresetImpl(bank, preset); - sharedParams->setPreset(preset); - sharedParams->setBank(bank); +// sharedParams->setPreset(preset); +// sharedParams->setBank(bank); } void FluidSynthModel::changePresetImpl(int bank, int preset) { - fluid_synth_program_select(synth, channel, sfont_id, static_cast(bank), static_cast(preset)); + fluid_synth_program_select(synth.get(), channel, sfont_id, static_cast(bank), static_cast(preset)); } fluid_preset_t* FluidSynthModel::getFirstPreset() { - fluid_sfont_t* sfont = fluid_synth_get_sfont_by_id(synth, sfont_id); + fluid_sfont_t* sfont = fluid_synth_get_sfont_by_id(synth.get(), sfont_id); jassert(sfont != nullptr); fluid_sfont_iteration_start(sfont); @@ -209,7 +237,7 @@ fluid_preset_t* FluidSynthModel::getFirstPreset() { unique_ptr FluidSynthModel::getFirstBankAndPreset() { fluid_preset_t* preset = getFirstPreset(); - int offset = fluid_synth_get_bank_offset(synth, sfont_id); + int offset = fluid_synth_get_bank_offset(synth.get(), sfont_id); return make_unique(fluid_preset_get_banknum(preset) + offset, fluid_preset_get_num(preset)); }; @@ -217,7 +245,7 @@ unique_ptr FluidSynthModel::getFirstBankAndPreset() { void FluidSynthModel::selectFirstPreset() { fluid_preset_t* preset = getFirstPreset(); - int offset = fluid_synth_get_bank_offset(synth, sfont_id); + int offset = fluid_synth_get_bank_offset(synth.get(), sfont_id); changePreset(fluid_preset_get_banknum(preset) + offset, fluid_preset_get_num(preset)); } @@ -225,14 +253,14 @@ void FluidSynthModel::selectFirstPreset() { BanksToPresets FluidSynthModel::getBanks() { BanksToPresets banksToPresets; - int soundfontCount = fluid_synth_sfcount(synth); + int soundfontCount = fluid_synth_sfcount(synth.get()); if (soundfontCount == 0) { // no soundfont selected return banksToPresets; } - fluid_sfont_t* sfont = fluid_synth_get_sfont_by_id(synth, sfont_id); + fluid_sfont_t* sfont = fluid_synth_get_sfont_by_id(synth.get(), sfont_id); if(sfont == nullptr) { // no soundfont found by that ID // the above guard (soundfontCount) protects us for the @@ -240,7 +268,7 @@ BanksToPresets FluidSynthModel::getBanks() { return banksToPresets; } - int offset = fluid_synth_get_bank_offset(synth, sfont_id); + int offset = fluid_synth_get_bank_offset(synth.get(), sfont_id); fluid_sfont_iteration_start(sfont); @@ -259,7 +287,7 @@ BanksToPresets FluidSynthModel::getBanks() { return banksToPresets; } -fluid_synth_t* FluidSynthModel::getSynth() { +shared_ptr FluidSynthModel::getSynth() { // https://msdn.microsoft.com/en-us/library/hh279669.aspx // You can pass a shared_ptr to another function in the following ways: // Pass the shared_ptr by value. This invokes the copy constructor, increments the reference count, and makes the callee an owner. @@ -272,14 +300,14 @@ void FluidSynthModel::onFileNameChanged(const String &absPath, int bank, int pre } unloadAndLoadFont(absPath); changePreset(bank, preset); - sharedParams->setSoundFontPath(absPath); + sharedParams.setSoundFontPath(absPath); eventListeners.call(&FluidSynthModel::Listener::fontChanged, this, absPath); } void FluidSynthModel::unloadAndLoadFont(const String &absPath) { // in the base case, there is no font loaded - if (fluid_synth_sfcount(synth) > 0) { - fluid_synth_sfunload(synth, sfont_id, 1); + if (fluid_synth_sfcount(synth.get()) > 0) { + fluid_synth_sfunload(synth.get(), sfont_id, 1); } loadFont(absPath); } @@ -287,7 +315,7 @@ void FluidSynthModel::unloadAndLoadFont(const String &absPath) { void FluidSynthModel::loadFont(const String &absPath) { currentSoundFontAbsPath = absPath; sfont_id++; - fluid_synth_sfload(synth, absPath.toStdString().c_str(), 1); + fluid_synth_sfload(synth.get(), absPath.toStdString().c_str(), 1); } FluidSynthModel::Listener::~Listener() { @@ -323,9 +351,11 @@ void FluidSynthModel::removeListener (FluidSynthModel::Listener* const listener) void FluidSynthModel::setSampleRate(float sampleRate) { currentSampleRate = sampleRate; - if (!initialised) { + // https://stackoverflow.com/a/40856043/5257399 + // test if a smart pointer is null + if (!synth) { // don't worry; we'll do this in initialise phase regardless return; } - fluid_synth_set_sample_rate(synth, sampleRate); + fluid_synth_set_sample_rate(synth.get(), sampleRate); } diff --git a/Source/FluidSynthModel.h b/Source/FluidSynthModel.h index 7785306..85a0b94 100644 --- a/Source/FluidSynthModel.h +++ b/Source/FluidSynthModel.h @@ -19,10 +19,13 @@ using namespace std; class FluidSynthModel { public: - FluidSynthModel(shared_ptr sharedParams); - ~FluidSynthModel(); + FluidSynthModel( + AudioProcessorValueTreeState& valueTreeState, + SharesParams& sharedParams + ); + // ~FluidSynthModel(); - fluid_synth_t* getSynth(); + shared_ptr getSynth(); void initialise(); BanksToPresets getBanks(); @@ -65,11 +68,14 @@ public: const String& getCurrentSoundFontAbsPath(); private: - shared_ptr sharedParams; + int handleMidiEvent(void* data, fluid_midi_event_t* event); - fluid_synth_t* synth; - fluid_settings_t* settings; -// fluid_audio_driver_t* driver; + AudioProcessorValueTreeState& valueTreeState; + SharesParams& sharedParams; + + shared_ptr synth; + unique_ptr settings; + // unique_ptr midiDriver; String currentSoundFontAbsPath; diff --git a/Source/Params.cpp b/Source/Params.cpp index a29b722..88c0046 100644 --- a/Source/Params.cpp +++ b/Source/Params.cpp @@ -14,73 +14,73 @@ using namespace std; -Params::Params() noexcept : - uiWidth{GuiConstants::minWidth}, - uiHeight{GuiConstants::minHeight}, - soundFontPath{String()}, - preset{-1}, - bank{-1}, - attack{0}, - decay{0}, - sustain{0}, - release{0}, - filterCutOff{0}, - filterResonance{0} +Params::Params() noexcept +: uiWidth{GuiConstants::minWidth} +, uiHeight{GuiConstants::minHeight} +, soundFontPath{String()} +// , preset{-1} +// , bank{-1} +// , attack{0} +// , decay{0} +// , sustain{0} +// , release{0} +// , filterCutOff{0} +// .filterResonance{0} { } -void Params::setAttributesOnXml(XmlElement& xml) { - xml.setAttribute("uiWidth", uiWidth); - xml.setAttribute("uiHeight", uiHeight); - xml.setAttribute("soundFontPath", soundFontPath); - xml.setAttribute("preset", preset); - xml.setAttribute("bank", bank); - xml.setAttribute("attack", attack); - xml.setAttribute("decay", decay); - xml.setAttribute("sustain", sustain); - xml.setAttribute("release", release); - xml.setAttribute("filterCutOff", filterCutOff); - xml.setAttribute("filterResonance", filterResonance); +void Params::setAttributesOnXml(shared_ptr xml) { + xml->setAttribute("uiWidth", uiWidth); + xml->setAttribute("uiHeight", uiHeight); + xml->setAttribute("soundFontPath", soundFontPath); + // xml.setAttribute("preset", preset); + // xml.setAttribute("bank", bank); + // xml.setAttribute("attack", attack); + // xml.setAttribute("decay", decay); + // xml.setAttribute("sustain", sustain); + // xml.setAttribute("release", release); + // xml.setAttribute("filterCutOff", filterCutOff); + // xml.setAttribute("filterResonance", filterResonance); } void Params::loadAttributesFromXml(shared_ptr xmlState) { uiWidth = jmin(jmax(xmlState->getIntAttribute("uiWidth", uiWidth), GuiConstants::minWidth), GuiConstants::maxWidth); uiHeight = jmin(jmax(xmlState->getIntAttribute("uiHeight", uiHeight), GuiConstants::minHeight), GuiConstants::maxHeight); soundFontPath = xmlState->getStringAttribute("soundFontPath", soundFontPath); - preset = xmlState->getIntAttribute("preset", preset); - bank = xmlState->getIntAttribute("bank", bank); - attack = jmin(jmax(xmlState->getIntAttribute("attack", attack), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); - decay = jmin(jmax(xmlState->getIntAttribute("decay", decay), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); - sustain = jmin(jmax(xmlState->getIntAttribute("sustain", sustain), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); - release = jmin(jmax(xmlState->getIntAttribute("release", release), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); - filterCutOff = jmin(jmax(xmlState->getIntAttribute("filterCutOff", filterCutOff), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); - filterResonance = jmin(jmax(xmlState->getIntAttribute("filterResonance", filterResonance), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); + // preset = xmlState->getIntAttribute("preset", preset); + // bank = xmlState->getIntAttribute("bank", bank); + // attack = jmin(jmax(xmlState->getIntAttribute("attack", attack), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); + // decay = jmin(jmax(xmlState->getIntAttribute("decay", decay), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); + // sustain = jmin(jmax(xmlState->getIntAttribute("sustain", sustain), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); + // release = jmin(jmax(xmlState->getIntAttribute("release", release), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); + // filterCutOff = jmin(jmax(xmlState->getIntAttribute("filterCutOff", filterCutOff), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); + // filterResonance = jmin(jmax(xmlState->getIntAttribute("filterResonance", filterResonance), MidiConstants::midiMinValue), MidiConstants::midiMaxValue); } -void Params::acceptMidiControlEvent(int controller, int value) { - switch(static_cast(controller)) { - case SOUND_CTRL2: // MIDI CC 71 Timbre/Harmonic Intensity (filter resonance) - filterResonance = value; - break; - case SOUND_CTRL3: // MIDI CC 72 Release time - release = value; - break; - case SOUND_CTRL4: // MIDI CC 73 Attack time - attack = value; - break; - case SOUND_CTRL5: // MIDI CC 74 Brightness (cutoff frequency, FILTERFC) - filterCutOff = value; - break; - case SOUND_CTRL6: // MIDI CC 75 Decay Time - decay = value; - break; - case SOUND_CTRL10: // MIDI CC 79 undefined - sustain = value; - break; - default: - break; - } -} +//void Params::acceptMidiControlEvent(int controller, int value) { +// switch(static_cast(controller)) { +// case SOUND_CTRL2: // MIDI CC 71 Timbre/Harmonic Intensity (filter resonance) +// filterResonance = value; +// break; +// case SOUND_CTRL3: // MIDI CC 72 Release time +// release = value; +// break; +// case SOUND_CTRL4: // MIDI CC 73 Attack time +// attack = value; +// break; +// case SOUND_CTRL5: // MIDI CC 74 Brightness (cutoff frequency, FILTERFC) +// filterCutOff = value; +// break; +// case SOUND_CTRL6: // MIDI CC 75 Decay Time +// decay = value; +// break; +// case SOUND_CTRL10: // MIDI CC 79 undefined +// sustain = value; +// break; +// default: +// break; +// } +//} void Params::setSoundFontPath(const String& value) { soundFontPath = value; @@ -89,64 +89,64 @@ void Params::setSoundFontPath(const String& value) { String& Params::getSoundFontPath() { return soundFontPath; } -int Params::getPreset() { - return preset; -} -int Params::getBank() { - return bank; -} +//int Params::getPreset() { +// return preset; +//} +//int Params::getBank() { +// return bank; +//} int Params::getUiWidth() { return uiWidth; } int Params::getUiHeight() { return uiHeight; } -int Params::getAttack() { - return attack; -} -int Params::getDecay() { - return decay; -} -int Params::getSustain() { - return sustain; -} -int Params::getRelease() { - return release; -} -int Params::getFilterCutOff() { - return filterCutOff; -} -int Params::getFilterResonance() { - return filterResonance; -} +//int Params::getAttack() { +// return attack; +//} +//int Params::getDecay() { +// return decay; +//} +//int Params::getSustain() { +// return sustain; +//} +//int Params::getRelease() { +// return release; +//} +//int Params::getFilterCutOff() { +// return filterCutOff; +//} +//int Params::getFilterResonance() { +// return filterResonance; +//} -void Params::setPreset(int value) { - preset = value; -} -void Params::setBank(int value) { - bank = value; -} +//void Params::setPreset(int value) { +// preset = value; +//} +//void Params::setBank(int value) { +// bank = value; +//} void Params::setUiWidth(int value) { uiWidth = value; } void Params::setUiHeight(int value) { uiHeight = value; } -void Params::setAttack(int value) { - attack = value; -} -void Params::setDecay(int value) { - decay = value; -} -void Params::setSustain(int value) { - sustain = value; -} -void Params::setRelease(int value) { - release = value; -} -void Params::setFilterCutOff(int value) { - filterCutOff = value; -} -void Params::setFilterResonance(int value) { - filterResonance = value; -} +//void Params::setAttack(int value) { +// attack = value; +//} +//void Params::setDecay(int value) { +// decay = value; +//} +//void Params::setSustain(int value) { +// sustain = value; +//} +//void Params::setRelease(int value) { +// release = value; +//} +//void Params::setFilterCutOff(int value) { +// filterCutOff = value; +//} +//void Params::setFilterResonance(int value) { +// filterResonance = value; +//} diff --git a/Source/Params.h b/Source/Params.h index e6979f4..7452da2 100644 --- a/Source/Params.h +++ b/Source/Params.h @@ -9,51 +9,51 @@ class Params: public SharesParams { public: Params() noexcept; - virtual void setAttributesOnXml(XmlElement& xml) override; + virtual void setAttributesOnXml(shared_ptr xml) override; virtual void loadAttributesFromXml(shared_ptr xmlState) override; - virtual void acceptMidiControlEvent(int controller, int value) override; +// virtual void acceptMidiControlEvent(int controller, int value) override; virtual void setSoundFontPath(const String& value) override; virtual String& getSoundFontPath() override; - virtual int getPreset() override; - virtual void setPreset(int value) override; - virtual int getBank() override; - virtual void setBank(int value) override; + // virtual int getPreset() override; + // virtual void setPreset(int value) override; + // virtual int getBank() override; + // virtual void setBank(int value) override; virtual int getUiWidth() override; virtual void setUiWidth(int value) override; virtual int getUiHeight() override; virtual void setUiHeight(int value) override; - virtual int getAttack() override; - virtual void setAttack(int value) override; - virtual int getDecay() override; - virtual void setDecay(int value) override; - virtual int getSustain() override; - virtual void setSustain(int value) override; - virtual int getRelease() override; - virtual void setRelease(int value) override; + // virtual int getAttack() override; + // virtual void setAttack(int value) override; + // virtual int getDecay() override; + // virtual void setDecay(int value) override; + // virtual int getSustain() override; + // virtual void setSustain(int value) override; + // virtual int getRelease() override; + // virtual void setRelease(int value) override; - virtual int getFilterCutOff() override; - virtual void setFilterCutOff(int value) override; - virtual int getFilterResonance() override; - virtual void setFilterResonance(int value) override; + // virtual int getFilterCutOff() override; + // virtual void setFilterCutOff(int value) override; + // virtual int getFilterResonance() override; + // virtual void setFilterResonance(int value) override; private: int uiWidth; int uiHeight; String soundFontPath; - int preset; - int bank; + // int preset; + // int bank; - int attack; - int decay; - int sustain; - int release; + // int attack; + // int decay; + // int sustain; + // int release; - int filterCutOff; - int filterResonance; + // int filterCutOff; + // int filterResonance; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Params) }; diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 42b0f63..f6d5355 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -17,11 +17,11 @@ JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor(JuicySFAudioProcessor& : AudioProcessorEditor{&p}, processor{p}, valueTreeState{valueTreeState}, - sharedParams{p.sharedParams}, + sharedParams{p.getSharedParams()}, midiKeyboard{p.keyboardState, SurjectiveMidiKeyboardComponent::horizontalKeyboard}, - tablesComponent{p.getFluidSynthModel()}, - filePicker{p.getFluidSynthModel()}, - slidersComponent{p.sharedParams, valueTreeState, p.getFluidSynthModel()} + tablesComponent{valueTreeState, p.getFluidSynthModel()}, + filePicker{valueTreeState, p.getFluidSynthModel()}, + slidersComponent{p.getSharedParams(), valueTreeState, p.getFluidSynthModel()} { // set resize limits for this plug-in setResizeLimits( @@ -30,7 +30,7 @@ JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor(JuicySFAudioProcessor& GuiConstants::maxWidth, GuiConstants::maxHeight); - setSize(sharedParams->getUiWidth(), sharedParams->getUiHeight()); + setSize(sharedParams.getUiWidth(), sharedParams.getUiHeight()); // processor.subscribeToStateChanges(this); @@ -104,8 +104,8 @@ void JuicySFAudioProcessorEditor::resized() tablesComponent.setBounds(rContent); - sharedParams->setUiWidth(getWidth()); - sharedParams->setUiHeight(getHeight()); + sharedParams.setUiWidth(getWidth()); + sharedParams.setUiHeight(getHeight()); // Rectangle r2 (getLocalBounds()); // r2.reduce(0, padding); diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 10ada3a..51255ef 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -28,7 +28,10 @@ class JuicySFAudioProcessorEditor : public AudioProcessorEditor, public StateChangeSubscriber*/ { public: - JuicySFAudioProcessorEditor (JuicySFAudioProcessor&, AudioProcessorValueTreeState& state); + JuicySFAudioProcessorEditor( + JuicySFAudioProcessor&, + AudioProcessorValueTreeState& state + ); ~JuicySFAudioProcessorEditor(); //============================================================================== @@ -50,7 +53,7 @@ private: JuicySFAudioProcessor& processor; AudioProcessorValueTreeState& valueTreeState; - shared_ptr sharedParams; + SharesParams& sharedParams; SurjectiveMidiKeyboardComponent midiKeyboard; TablesComponent tablesComponent; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index e2ddf59..0a3716f 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -26,14 +26,16 @@ AudioProcessor* JUCE_CALLTYPE createPluginFilter(); //============================================================================== +//, sharedParams{static_pointer_cast(make_shared())} JuicySFAudioProcessor::JuicySFAudioProcessor() : AudioProcessor{getBusesProperties()} -, sharedParams{static_pointer_cast(make_shared())} -, valueTreeState{*this, nullptr, - { "PARAMETERS" /* MYPLUGINSETTINGS */ }, - createParameterLayout() - } -, fluidSynthModel{sharedParams} +, sharedParams{} +, valueTreeState{ + *this, + nullptr, + { "MYPLUGINSETTINGS" }, + createParameterLayout()} +, fluidSynthModel{valueTreeState, sharedParams} //, fluidSynthModel{*this} //, pluginEditor(nullptr) { @@ -45,9 +47,15 @@ AudioProcessorValueTreeState::ParameterLayout JuicySFAudioProcessor::createParam // for (int i = 1; i < 9; ++i) // params.push_back (std::make_unique (String (i), String (i), 0, i, 0)); + + +// make_unique("soundfontPath", "filepath to soundfont", 0, 127, 0, "A" ), // https://stackoverflow.com/a/8469002/5257399 unique_ptr params[] { + make_unique("bank", "which bank is selected in the soundfont", 0, 127, 0, "Bank" ), + // note: banks may be sparse, and lack a 0th preset. so defend against this. + make_unique("preset", "which patch (aka patch, program, instrument) is selected in the soundfont", 0, 127, 0, "Preset" ), make_unique("attack", "volume envelope attack time", 0, 127, 0, "A" ), make_unique("decay", "volume envelope sustain attentuation", 0, 127, 0, "D" ), make_unique("sustain", "volume envelope decay time", 0, 127, 0, "S" ), @@ -70,7 +78,7 @@ JuicySFAudioProcessor::~JuicySFAudioProcessor() void JuicySFAudioProcessor::initialiseSynth() { fluidSynthModel.initialise(); - fluidSynth = fluidSynthModel.getSynth(); +// fluidSynth = fluidSynthModel.getSynth(); const int numVoices = 8; @@ -352,8 +360,11 @@ void JuicySFAudioProcessor::getStateInformation (MemoryBlock& destData) // as intermediaries to make it easy to save and load complex data. // Create an outer XML element.. - XmlElement xml{"MYPLUGINSETTINGS"}; - sharedParams->setAttributesOnXml(xml); +// XmlElement xml{"MYPLUGINSETTINGS"}; +// sharedParams->setAttributesOnXml(xml); + auto state{valueTreeState.copyState()}; + shared_ptr xml{state.createXml()}; + sharedParams.setAttributesOnXml(xml); // list::iterator p; // for(p = stateChangeSubscribers.begin(); p != stateChangeSubscribers.end(); p++) { @@ -361,12 +372,12 @@ void JuicySFAudioProcessor::getStateInformation (MemoryBlock& destData) // } // Store the values of all our parameters, using their param ID as the XML attribute - for (auto* param : getParameters()) - if (auto* p = dynamic_cast (param)) - xml.setAttribute (p->paramID, p->getValue()); + // for (auto* param : getParameters()) + // if (auto* p = dynamic_cast (param)) + // xml->setAttribute (p->paramID, p->getValue()); // then use this helper function to stuff it into the binary blob and return it.. - copyXmlToBinary (xml, destData); + copyXmlToBinary (*xml, destData); } void JuicySFAudioProcessor::setStateInformation (const void* data, int sizeInBytes) @@ -375,40 +386,42 @@ void JuicySFAudioProcessor::setStateInformation (const void* data, int sizeInByt // whose contents will have been created by the getStateInformation() call. // This getXmlFromBinary() helper function retrieves our XML from the binary blob.. shared_ptr xmlState{getXmlFromBinary(data, sizeInBytes)}; +// unique_ptr xmlState{getXmlFromBinary(data, sizeInBytes)}; - if (xmlState != nullptr) - { + if (xmlState.get() != nullptr) { // make sure that it's actually our type of XML object.. - if (xmlState->hasTagName ("MYPLUGINSETTINGS")) - { +// if (xmlState->hasTagName ("MYPLUGINSETTINGS")) { + if (xmlState->hasTagName(valueTreeState.state.getType())) { + valueTreeState.replaceState(ValueTree::fromXml(*xmlState)); // list::iterator p; // for(p = stateChangeSubscribers.begin(); p != stateChangeSubscribers.end(); p++) { // (*p)->setStateInformation(xmlState); // } // ok, now pull out our last window size.. - sharedParams->loadAttributesFromXml(xmlState); + sharedParams.loadAttributesFromXml(xmlState); // Now reload our parameters.. - for (auto* param : getParameters()) - if (auto* p = dynamic_cast (param)) - p->setValue ((float) xmlState->getDoubleAttribute (p->paramID, p->getValue())); - - fluidSynthModel.onFileNameChanged( - sharedParams->getSoundFontPath(), - sharedParams->getBank(), - sharedParams->getPreset()); - - AudioProcessorEditor* editor{getActiveEditor()}; - if (editor != nullptr) { - editor->setSize( - sharedParams->getUiWidth(), - sharedParams->getUiHeight()); - - jassert(dynamic_cast (editor) != nullptr); - ExposesComponents* exposesComponents = dynamic_cast (editor); - exposesComponents->getFilePicker().setDisplayedFilePath(sharedParams->getSoundFontPath()); - } + +// for (auto* param : getParameters()) +// if (auto* p = dynamic_cast (param)) +// p->setValue ((float) xmlState->getDoubleAttribute (p->paramID, p->getValue())); +// +// fluidSynthModel.onFileNameChanged( +// sharedParams->getSoundFontPath(), +// sharedParams->getBank(), +// sharedParams->getPreset()); +// +// AudioProcessorEditor* editor{getActiveEditor()}; +// if (editor != nullptr) { +// editor->setSize( +// sharedParams->getUiWidth(), +// sharedParams->getUiHeight()); +// +// jassert(dynamic_cast (editor) != nullptr); +// ExposesComponents* exposesComponents = dynamic_cast (editor); +// exposesComponents->getFilePicker().setDisplayedFilePath(sharedParams->getSoundFontPath()); +// } // const String& currentSoundFontAbsPath = fluidSynthModel->getCurrentSoundFontAbsPath(); // if (currentSoundFontAbsPath.isNotEmpty()) { @@ -431,8 +444,12 @@ bool JuicySFAudioProcessor::supportsDoublePrecisionProcessing() const { return false; } -FluidSynthModel* JuicySFAudioProcessor::getFluidSynthModel() { - return &fluidSynthModel; +FluidSynthModel& JuicySFAudioProcessor::getFluidSynthModel() { + return fluidSynthModel; +} + +SharesParams& JuicySFAudioProcessor::getSharedParams() { + return sharedParams; } //============================================================================== diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index a0599f8..33b3a37 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -14,6 +14,7 @@ #include "FluidSynthModel.h" #include "StateChangeSubscriber.h" #include "SharesParams.h" +#include "Params.h" #include using namespace std; @@ -62,18 +63,18 @@ public: bool supportsDoublePrecisionProcessing() const override; - FluidSynthModel* getFluidSynthModel(); + FluidSynthModel& getFluidSynthModel(); + SharesParams& getSharedParams(); MidiKeyboardState keyboardState; - shared_ptr sharedParams; - // void subscribeToStateChanges(StateChangeSubscriber* subscriber); // void unsubscribeFromStateChanges(StateChangeSubscriber* subscriber); private: void initialiseSynth(); + Params sharedParams; AudioProcessorValueTreeState valueTreeState; FluidSynthModel fluidSynthModel; diff --git a/Source/PresetsToBanks.h b/Source/PresetsToBanks.h index ea70353..bbfcdba 100644 --- a/Source/PresetsToBanks.h +++ b/Source/PresetsToBanks.h @@ -1,6 +1,6 @@ -// -// Created by Alex Birch on 17/09/2017. -// +// http://www.synthfont.com/Tutorial6.html +// a bank can hold many (128) presets +// bank 128 is reserved for percussion #pragma once diff --git a/Source/SharesParams.h b/Source/SharesParams.h index 1f25d0b..5b9621c 100644 --- a/Source/SharesParams.h +++ b/Source/SharesParams.h @@ -13,35 +13,35 @@ class SharesParams { public: virtual ~SharesParams() {} - virtual void setAttributesOnXml(XmlElement& xml) = 0; + virtual void setAttributesOnXml(shared_ptr xml) = 0; virtual void loadAttributesFromXml(shared_ptr xmlState) = 0; - virtual void acceptMidiControlEvent(int controller, int value) = 0; +// virtual void acceptMidiControlEvent(int controller, int value) = 0; virtual void setSoundFontPath(const String& value) = 0; virtual String& getSoundFontPath() = 0; - virtual int getPreset() = 0; - virtual void setPreset(int value) = 0; - virtual int getBank() = 0; - virtual void setBank(int value) = 0; + // virtual int getPreset() = 0; + // virtual void setPreset(int value) = 0; + // virtual int getBank() = 0; + // virtual void setBank(int value) = 0; virtual int getUiWidth() = 0; virtual void setUiWidth(int value) = 0; virtual int getUiHeight() = 0; virtual void setUiHeight(int value) = 0; - virtual int getAttack() = 0; - virtual void setAttack(int value) = 0; - virtual int getDecay() = 0; - virtual void setDecay(int value) = 0; - virtual int getSustain() = 0; - virtual void setSustain(int value) = 0; - virtual int getRelease() = 0; - virtual void setRelease(int value) = 0; + // virtual int getAttack() = 0; + // virtual void setAttack(int value) = 0; + // virtual int getDecay() = 0; + // virtual void setDecay(int value) = 0; + // virtual int getSustain() = 0; + // virtual void setSustain(int value) = 0; + // virtual int getRelease() = 0; + // virtual void setRelease(int value) = 0; - virtual int getFilterCutOff() = 0; - virtual void setFilterCutOff(int value) = 0; - virtual int getFilterResonance() = 0; - virtual void setFilterResonance(int value) = 0; + // virtual int getFilterCutOff() = 0; + // virtual void setFilterCutOff(int value) = 0; + // virtual int getFilterResonance() = 0; + // virtual void setFilterResonance(int value) = 0; }; diff --git a/Source/SlidersComponent.cpp b/Source/SlidersComponent.cpp index 789e696..196ce1f 100644 --- a/Source/SlidersComponent.cpp +++ b/Source/SlidersComponent.cpp @@ -24,7 +24,7 @@ std::function SlidersComponent::makeSliderListener(Slider& slider, int c s << slider.getComponentID() << ", controller " << controller << ", value " << slider.getValue() << ", xmlReleaseValue " << value; DEBUG_PRINT(s); // slider.setValue(slider.getValue(), NotificationType::dontSendNotification); - fluidSynthModel->setControllerValue(controller, slider.getValue()); + fluidSynthModel.setControllerValue(controller, slider.getValue()); // callback(); }; } @@ -115,9 +115,9 @@ void SlidersComponent::acceptMidiControlEvent(int controller, int value) { // } SlidersComponent::SlidersComponent( - shared_ptr sharedParams, + SharesParams& sharedParams, AudioProcessorValueTreeState& valueTreeState, - FluidSynthModel* fluidSynthModel) + FluidSynthModel& fluidSynthModel) : sharedParams{sharedParams} , valueTreeState{valueTreeState} , fluidSynthModel{fluidSynthModel} diff --git a/Source/SlidersComponent.h b/Source/SlidersComponent.h index 613182c..c2c9d4e 100644 --- a/Source/SlidersComponent.h +++ b/Source/SlidersComponent.h @@ -13,9 +13,9 @@ class SlidersComponent : public Component, { public: SlidersComponent( - shared_ptr sharedParams, + SharesParams& sharedParams, AudioProcessorValueTreeState& valueTreeState, - FluidSynthModel* fluidSynthModel); + FluidSynthModel& fluidSynthModel); ~SlidersComponent(); void resized() override; @@ -35,9 +35,9 @@ public: private: std::function makeSliderListener(Slider& slider, int controller); - shared_ptr sharedParams; + SharesParams& sharedParams; AudioProcessorValueTreeState& valueTreeState; - FluidSynthModel* fluidSynthModel; + FluidSynthModel& fluidSynthModel; GroupComponent envelopeGroup; diff --git a/Source/SoundfontSynthVoice.cpp b/Source/SoundfontSynthVoice.cpp index 652b995..60590c1 100644 --- a/Source/SoundfontSynthVoice.cpp +++ b/Source/SoundfontSynthVoice.cpp @@ -6,13 +6,15 @@ #include "SoundfontSynthSound.h" #include "Util.h" -SoundfontSynthVoice::SoundfontSynthVoice(fluid_synth_t* synth) -: tailOff (0.0), -level(0.0), -currentAngle(0.0), -angleDelta(0.0), -midiNoteNumber(0), -synth(synth) +using namespace std; + +SoundfontSynthVoice::SoundfontSynthVoice(shared_ptr synth) +: tailOff(0.0) +, level(0.0) +, currentAngle(0.0) +, angleDelta(0.0) +, midiNoteNumber(0) +, synth(synth) { } @@ -26,7 +28,7 @@ void SoundfontSynthVoice::startNote( int /*currentPitchWheelPosition*/) { this->midiNoteNumber = midiNoteNumber; DEBUG_PRINT ( juce::String::formatted("JUCE noteon: %d, %d\n", midiNoteNumber, velocity) ); - fluid_synth_noteon(synth, 0, midiNoteNumber, static_cast(velocity * 127)); + fluid_synth_noteon(synth.get(), 0, midiNoteNumber, static_cast(velocity * 127)); // currentAngle = 0.0; // level = velocity * 0.15; @@ -59,7 +61,7 @@ void SoundfontSynthVoice::stopNote (float /*velocity*/, bool allowTailOff) { // } DEBUG_PRINT ( juce::String("JUCE noteoff\n") ); clearCurrentNote(); - fluid_synth_noteoff(synth, 0, this->midiNoteNumber); + fluid_synth_noteoff(synth.get(), 0, this->midiNoteNumber); } // receives input as MIDI 0 to 16383, with 8192 being center diff --git a/Source/SoundfontSynthVoice.h b/Source/SoundfontSynthVoice.h index e920882..291ac3d 100644 --- a/Source/SoundfontSynthVoice.h +++ b/Source/SoundfontSynthVoice.h @@ -8,11 +8,11 @@ #include #include "../JuceLibraryCode/JuceHeader.h" -using std::shared_ptr; +using namespace std; class SoundfontSynthVoice : public SynthesiserVoice { public: - SoundfontSynthVoice(fluid_synth_t* synth); + SoundfontSynthVoice(shared_ptr synth); bool canPlaySound (SynthesiserSound* sound) override; void startNote ( @@ -35,5 +35,5 @@ private: double angleDelta; int midiNoteNumber; - fluid_synth_t* synth; + shared_ptr synth; }; diff --git a/Source/TablesComponent.cpp b/Source/TablesComponent.cpp index 67f40de..c64bddf 100644 --- a/Source/TablesComponent.cpp +++ b/Source/TablesComponent.cpp @@ -8,10 +8,13 @@ using namespace std; using namespace placeholders; TablesComponent::TablesComponent( - FluidSynthModel* fluidSynthModel -) : fluidSynthModel(fluidSynthModel), - banksToPresets(fluidSynthModel->getBanks()), - initialised(false) + AudioProcessorValueTreeState& valueTreeState, + FluidSynthModel& fluidSynthModel +) +: valueTreeState{valueTreeState} +, fluidSynthModel{fluidSynthModel} +, banksToPresets{fluidSynthModel.getBanks()} +, initialised{false} { fluid_preset_t* currentPreset = getCurrentPreset(); selectedBank = -1; @@ -59,13 +62,13 @@ TablesComponent::TablesComponent( initialised = true; - fluidSynthModel->addListener(this); + fluidSynthModel.addListener(this); } fluid_preset_t* TablesComponent::getCurrentPreset() { - fluid_synth_t* synth = fluidSynthModel->getSynth(); + shared_ptr synth {fluidSynthModel.getSynth()}; - return fluid_synth_get_channel_preset(synth, fluidSynthModel->getChannel()); + return fluid_synth_get_channel_preset(synth.get(), fluidSynthModel.getChannel()); } Preset TablesComponent::getFirstPresetInBank(int bank) { @@ -108,13 +111,13 @@ void TablesComponent::onPresetSelected(int preset) { } cout << "Preset " << preset << endl; // selectedPreset = preset; - fluidSynthModel->changePreset(selectedBank, preset); + fluidSynthModel.changePreset(selectedBank, preset); } TablesComponent::~TablesComponent() { delete presetTable; delete banks; - fluidSynthModel->removeListener(this); + fluidSynthModel.removeListener(this); } vector TablesComponent::mapBanks(const BanksToPresets &banksToPresets) { @@ -165,7 +168,7 @@ bool TablesComponent::keyPressed(const KeyPress &key) { } void TablesComponent::fontChanged(FluidSynthModel *, const String &) { - banksToPresets = fluidSynthModel->getBanks(); + banksToPresets = fluidSynthModel.getBanks(); fluid_preset_t* currentPreset = getCurrentPreset(); diff --git a/Source/TablesComponent.h b/Source/TablesComponent.h index d86e7d9..9f57815 100644 --- a/Source/TablesComponent.h +++ b/Source/TablesComponent.h @@ -20,7 +20,8 @@ class TablesComponent : public Component, { public: TablesComponent( - FluidSynthModel* fluidSynthModel + AudioProcessorValueTreeState& valueTreeState, + FluidSynthModel& fluidSynthModel ); ~TablesComponent(); @@ -30,7 +31,8 @@ public: void fontChanged(FluidSynthModel *, const String &) override; private: - FluidSynthModel* fluidSynthModel; + AudioProcessorValueTreeState& valueTreeState; + FluidSynthModel& fluidSynthModel; int selectedBank; Pills* banks;