diff --git a/Builds/MacOSX/juicysfplugin.xcodeproj/project.pbxproj b/Builds/MacOSX/juicysfplugin.xcodeproj/project.pbxproj index 54de6c0..1dc4892 100644 --- a/Builds/MacOSX/juicysfplugin.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/juicysfplugin.xcodeproj/project.pbxproj @@ -33,7 +33,6 @@ 21AC354419419A4D80ADE43A /* include_juce_audio_plugin_client_AU_2.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7E47C0A828016F7D0D63C0D6 /* include_juce_audio_plugin_client_AU_2.mm */; }; 2918F46AFD2AB89F9FA847DC /* include_juce_events.mm in Sources */ = {isa = PBXBuildFile; fileRef = 373EF982A53046CE00BECE68 /* include_juce_events.mm */; }; 2E77C6FAF1BCDB9EB29D20B9 /* PluginProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D53CAB963D5051C786D3A52D /* PluginProcessor.cpp */; }; - 305606C42BB0F2A12D382D34 /* SoundfontSynthVoice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A057FEC371053E83A73E47 /* SoundfontSynthVoice.cpp */; }; 35099D9322CAA87D00CD4523 /* Params.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35099D9122CAA87D00CD4523 /* Params.cpp */; }; 358E458C22BEE5090087ED8D /* RecentFilesMenuTemplate.nib in Resources */ = {isa = PBXBuildFile; fileRef = 78CC5234CCFE3B170585DDAD /* RecentFilesMenuTemplate.nib */; }; 358E458D22BEE5090087ED8D /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1616112041466F7324D7E19 /* Accelerate.framework */; }; @@ -128,7 +127,6 @@ 9C107CE4B586E4B097D9D04E /* SurjectiveMidiKeyboardComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4119A8200AC54674C00EFE66 /* SurjectiveMidiKeyboardComponent.cpp */; }; 9C2580F953071AD611EB6166 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28CA077CDD21D0FEC66FC290 /* AudioToolbox.framework */; }; AC5E4EF988D864A298E3650D /* TablesComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0DD5458189C039F5A4FAD62D /* TablesComponent.cpp */; }; - B66EBD76F6051D97D56C97AB /* SoundfontSynthSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7D7B71BE20CA213D2FCD7FEE /* SoundfontSynthSound.cpp */; }; B92F6EAB1D5ACC13AF0CD750 /* CoreAudioKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A67D09546C4E4831438F7DBD /* CoreAudioKit.framework */; }; BB7C2221DA61425A1AC65694 /* include_juce_gui_extra.mm in Sources */ = {isa = PBXBuildFile; fileRef = 44FB953DA425CBBA8AC21417 /* include_juce_gui_extra.mm */; }; BFD9EF2D67067FC1E5BA3546 /* MyColours.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29F2CE1B40FAE1467C7876C5 /* MyColours.cpp */; }; @@ -331,11 +329,9 @@ 6FA795817D2F3B3119FDD754 /* juce_core */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_core; path = /Applications/JUCE/modules/juce_core; sourceTree = ""; }; 6FEF19AE08ED1DC1E3D9DF43 /* AppConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = SOURCE_ROOT; }; 706FF998202761F30811FA6B /* juce_audio_devices */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_devices; path = /Applications/JUCE/modules/juce_audio_devices; sourceTree = ""; }; - 76724E30D8976FC4C2EE56FF /* SoundfontSynthSound.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SoundfontSynthSound.h; path = ../../Source/SoundfontSynthSound.h; sourceTree = SOURCE_ROOT; }; 78CC5234CCFE3B170585DDAD /* RecentFilesMenuTemplate.nib */ = {isa = PBXFileReference; lastKnownFileType = file.nib; path = RecentFilesMenuTemplate.nib; sourceTree = SOURCE_ROOT; }; 7C699A8B65F3F9FB5004F22D /* juce_gui_extra */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_gui_extra; path = /Applications/JUCE/modules/juce_gui_extra; sourceTree = ""; }; 7D2457AD994644752178FC82 /* include_juce_audio_plugin_client_VST_utils.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_audio_plugin_client_VST_utils.mm; path = ../../JuceLibraryCode/include_juce_audio_plugin_client_VST_utils.mm; sourceTree = SOURCE_ROOT; }; - 7D7B71BE20CA213D2FCD7FEE /* SoundfontSynthSound.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SoundfontSynthSound.cpp; path = ../../Source/SoundfontSynthSound.cpp; sourceTree = SOURCE_ROOT; }; 7E47C0A828016F7D0D63C0D6 /* include_juce_audio_plugin_client_AU_2.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_audio_plugin_client_AU_2.mm; path = ../../JuceLibraryCode/include_juce_audio_plugin_client_AU_2.mm; sourceTree = SOURCE_ROOT; }; 88ADEBF51BD04FEA9422D276 /* FilePickerFragment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilePickerFragment.h; path = ../../Source/FilePickerFragment.h; sourceTree = SOURCE_ROOT; }; 8990F3EAFFBBD6A42247C663 /* PluginEditor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PluginEditor.h; path = ../../Source/PluginEditor.h; sourceTree = SOURCE_ROOT; }; @@ -348,8 +344,6 @@ ADC93C26314F163B963461E2 /* include_juce_audio_utils.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_audio_utils.mm; path = ../../JuceLibraryCode/include_juce_audio_utils.mm; sourceTree = SOURCE_ROOT; }; AE397302E7E3F3A14A0C5F3C /* Preset.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Preset.h; path = ../../Source/Preset.h; sourceTree = SOURCE_ROOT; }; B000E7A360C0C86ADD3C911D /* BankAndPreset.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BankAndPreset.h; path = ../../Source/BankAndPreset.h; sourceTree = SOURCE_ROOT; }; - B40B7F24646CBA708718DE82 /* SoundfontSynthVoice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SoundfontSynthVoice.h; path = ../../Source/SoundfontSynthVoice.h; sourceTree = SOURCE_ROOT; }; - B5A057FEC371053E83A73E47 /* SoundfontSynthVoice.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SoundfontSynthVoice.cpp; path = ../../Source/SoundfontSynthVoice.cpp; sourceTree = SOURCE_ROOT; }; B6D37AD919F9E83688578941 /* SurjectiveMidiKeyboardComponent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SurjectiveMidiKeyboardComponent.h; path = ../../Source/SurjectiveMidiKeyboardComponent.h; sourceTree = SOURCE_ROOT; }; BFB39134DE6876F9005CFA61 /* Pills.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Pills.h; path = ../../Source/Pills.h; sourceTree = SOURCE_ROOT; }; BFF57868318157F12F087F07 /* Info-AU.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-AU.plist"; sourceTree = SOURCE_ROOT; }; @@ -543,10 +537,6 @@ 59F9FEC807012C10B8A1FA07 /* Preset.cpp */, AE397302E7E3F3A14A0C5F3C /* Preset.h */, 69DB3A0FB3D21F87D1E4B0C1 /* PresetsToBanks.h */, - 7D7B71BE20CA213D2FCD7FEE /* SoundfontSynthSound.cpp */, - 76724E30D8976FC4C2EE56FF /* SoundfontSynthSound.h */, - B5A057FEC371053E83A73E47 /* SoundfontSynthVoice.cpp */, - B40B7F24646CBA708718DE82 /* SoundfontSynthVoice.h */, 4119A8200AC54674C00EFE66 /* SurjectiveMidiKeyboardComponent.cpp */, B6D37AD919F9E83688578941 /* SurjectiveMidiKeyboardComponent.h */, CE8C41308A31A71A1177D0D5 /* TableComponent.cpp */, @@ -953,8 +943,6 @@ BFD9EF2D67067FC1E5BA3546 /* MyColours.cpp in Sources */, 8502F736BECFB9CB752AC72F /* Pills.cpp in Sources */, DF84F5E7E386AF7A38854939 /* Preset.cpp in Sources */, - B66EBD76F6051D97D56C97AB /* SoundfontSynthSound.cpp in Sources */, - 305606C42BB0F2A12D382D34 /* SoundfontSynthVoice.cpp in Sources */, 9C107CE4B586E4B097D9D04E /* SurjectiveMidiKeyboardComponent.cpp in Sources */, 4AE057561AEA78489D9E50F0 /* TableComponent.cpp in Sources */, AC5E4EF988D864A298E3650D /* TablesComponent.cpp in Sources */, diff --git a/Source/FluidSynthModel.cpp b/Source/FluidSynthModel.cpp index 052bf28..f7092a8 100644 --- a/Source/FluidSynthModel.cpp +++ b/Source/FluidSynthModel.cpp @@ -675,9 +675,9 @@ void FluidSynthModel::processBlock(AudioBuffer& buffer, MidiBuffer& midiM break; } case SOUND_CTRL10: { // MIDI CC 79 undefined - RangedAudioParameter *param {valueTreeState.getParameter("sustain")}; + RangedAudioParameter *param{valueTreeState.getParameter("sustain")}; jassert(dynamic_cast(param) != nullptr); - AudioParameterInt* castParam {dynamic_cast (param)}; + AudioParameterInt* castParam{dynamic_cast(param)}; *castParam = m.getControllerValue(); break; } @@ -692,8 +692,8 @@ void FluidSynthModel::processBlock(AudioBuffer& buffer, MidiBuffer& midiM m.getProgramChangeNumber())}; if (result == FLUID_OK) { RangedAudioParameter *param{valueTreeState.getParameter("preset")}; - jassert(dynamic_cast (param) != nullptr); - AudioParameterInt* castParam {dynamic_cast (param)}; + jassert(dynamic_cast(param) != nullptr); + AudioParameterInt* castParam{dynamic_cast(param)}; *castParam = m.getProgramChangeNumber(); } } else if (m.isPitchWheel()) { @@ -740,3 +740,63 @@ void FluidSynthModel::processBlock(AudioBuffer& buffer, MidiBuffer& midiM buffer.getNumChannels(), buffer.getArrayOfWritePointers()); } + +int FluidSynthModel::getNumPrograms() +{ + return 128; // NB: some hosts don't cope very well if you tell them there are 0 programs, + // so this should be at least 1, even if you're not really implementing programs. +} + +int FluidSynthModel::getCurrentProgram() +{ + RangedAudioParameter *param{valueTreeState.getParameter("preset")}; + jassert(dynamic_cast(param) != nullptr); + AudioParameterInt* castParam{dynamic_cast(param)}; + return castParam->get(); +} + +void FluidSynthModel::setCurrentProgram(int index) +{ + RangedAudioParameter *param{valueTreeState.getParameter("preset")}; + jassert(dynamic_cast(param) != nullptr); + AudioParameterInt* castParam{dynamic_cast(param)}; + *castParam = index; +} + +const String FluidSynthModel::getProgramName(int index) +{ + fluid_sfont_t* sfont{ + sfont_id == -1 + ? nullptr + : fluid_synth_get_sfont_by_id(synth.get(), sfont_id) + }; + if (!sfont) { + return {}; + } + int bank, presetNum; + { + RangedAudioParameter *param {valueTreeState.getParameter("bank")}; + jassert(dynamic_cast (param) != nullptr); + AudioParameterInt* castParam {dynamic_cast (param)}; + bank = castParam->get(); + } + { + RangedAudioParameter *param {valueTreeState.getParameter("preset")}; + jassert(dynamic_cast (param) != nullptr); + AudioParameterInt* castParam {dynamic_cast (param)}; + presetNum = castParam->get(); + } + fluid_preset_t *preset{fluid_sfont_get_preset( + sfont, + bank, + presetNum)}; + if (!preset) { + return {}; + } + return {fluid_preset_get_name(preset)}; +} + +void FluidSynthModel::changeProgramName(int index, const String& newName) +{ + // no-op; we don't support modifying the soundfont, so let's not support modification of preset names. +} diff --git a/Source/FluidSynthModel.h b/Source/FluidSynthModel.h index c0df803..30440b0 100644 --- a/Source/FluidSynthModel.h +++ b/Source/FluidSynthModel.h @@ -11,10 +11,6 @@ #include "BankAndPreset.h" #include "PresetsToBanks.h" - -// https://stackoverflow.com/a/13446565/5257399 -//using std::shared_ptr; - using namespace std; class FluidSynthModel @@ -23,55 +19,21 @@ class FluidSynthModel public: FluidSynthModel( AudioProcessorValueTreeState& valueTreeState - // SharesParams& sharedParams - // ValueTree& valueTree ); ~FluidSynthModel(); - shared_ptr getSynth(); void initialise(); - -// BanksToPresets getBanks(); - -// void changePreset(int bank, int preset); + int getChannel(); -// void onFileNameChanged(const String &absPath, int bank, int preset); void setControllerValue(int controller, int value); void processBlock(AudioBuffer& buffer, MidiBuffer& midiMessages); - //============================================================================== - /** - Used to receive callbacks when a button is clicked. - - @see Button::addListener, Button::removeListener - */ - // class Listener - // { - // public: - // /** Destructor. */ - // virtual ~Listener(); - - // /** Called when the button is clicked. */ - // virtual void fontChanged (FluidSynthModel*, const String &absPath); - // }; - - /** Registers a listener to receive events when this button's state changes. - If the listener is already registered, this will not register it again. - @see removeListener - */ - // void addListener (Listener* newListener); - - /** Removes a previously-registered button listener - @see addListener - */ - // void removeListener (Listener* listener); void setSampleRate(float sampleRate); - -// const String& getCurrentSoundFontAbsPath(); + //============================================================================== virtual void parameterChanged (const String& parameterID, float newValue) override; virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, @@ -86,35 +48,18 @@ public: inline virtual void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) override {}; inline virtual void valueTreeRedirected (ValueTree& treeWhichHasBeenChanged) override {}; -private: -// class ValueTreeListener: public ValueTree::Listener { -// public: -//// ValueTreeListener(); -//// ~ValueTreeListener(); -// virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, -// const Identifier& property) override; -// inline virtual void valueTreeChildAdded (ValueTree& parentTree, -// ValueTree& childWhichHasBeenAdded) override {}; -// inline virtual void valueTreeChildRemoved (ValueTree& parentTree, -// ValueTree& childWhichHasBeenRemoved, -// int indexFromWhichChildWasRemoved) override {}; -// inline virtual void valueTreeChildOrderChanged (ValueTree& parentTreeWhoseChildrenHaveMoved, -// int oldIndex, int newIndex) override {}; -// inline virtual void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) override {}; -// inline virtual void valueTreeRedirected (ValueTree& treeWhichHasBeenChanged) override {}; -// JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueTreeListener) -// }; + //============================================================================== + int getNumPrograms(); + int getCurrentProgram(); + void setCurrentProgram(int index); + const String getProgramName(int index); + void changeProgramName(int index, const String& newName); +private: int handleMidiEvent(void* data, fluid_midi_event_t* event); void refreshBanks(); - // void refreshPresets(); - // void refreshBanksAndPresets(); - -// ValueTreeListener valueTreeListener; AudioProcessorValueTreeState& valueTreeState; - // SharesParams& sharedParams; - // ValueTree& valueTree; // https://stackoverflow.com/questions/38980315/is-stdunique-ptr-deletion-order-guaranteed // members are destroyed in reverse of the order they're declared @@ -125,8 +70,6 @@ private: shared_ptr synth; // unique_ptr midiDriver; -// String currentSoundFontAbsPath; - float currentSampleRate; fluid_preset_t* getFirstPreset(); @@ -135,17 +78,11 @@ private: void unloadAndLoadFont(const String &absPath); void loadFont(const String &absPath); -// bool shouldLoadFont(const String &absPath); void changePresetImpl(int bank, int preset); - -// bool initialised; + int sfont_id; unsigned int channel; -// fluid_mod_t* mod; - - // ListenerList eventListeners; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FluidSynthModel) }; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 3b6aaee..40794b4 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -10,8 +10,6 @@ #include "PluginProcessor.h" #include "PluginEditor.h" -#include "SoundfontSynthVoice.h" -#include "SoundfontSynthSound.h" #include "ExposesComponents.h" #include "MidiConstants.h" #include "Util.h" @@ -26,18 +24,14 @@ AudioProcessor* JUCE_CALLTYPE createPluginFilter(); //============================================================================== -//, sharedParams{static_pointer_cast(make_shared())} JuicySFAudioProcessor::JuicySFAudioProcessor() : AudioProcessor{getBusesProperties()} -// , sharedParams{} , valueTreeState{ *this, nullptr, "MYPLUGINSETTINGS", createParameterLayout()} , fluidSynthModel{valueTreeState} -//, fluidSynthModel{*this} -//, pluginEditor(nullptr) { valueTreeState.state.appendChild({ "uiState", { { "width", GuiConstants::minWidth }, @@ -47,32 +41,14 @@ JuicySFAudioProcessor::JuicySFAudioProcessor() { "path", "" }, }, {} }, nullptr); // no properties, no subtrees (yet) - // valueTreeState.state.appendChild({ "presets", {}, {} }, nullptr); - // no properties, no subtrees (yet) valueTreeState.state.appendChild({ "banks", {}, {} }, nullptr); - // valueTreeState.state.setProperty("soundFontPath", "", nullptr); -// valueTreeState.state.appendChild({ "soundFontPath", {} }, nullptr); initialiseSynth(); } AudioProcessorValueTreeState::ParameterLayout JuicySFAudioProcessor::createParameterLayout() { - // std::vector> params; - - // 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("uiWidthPersist", "width of this plugin's GUI. Editor listens for changes (e.g. on load)", GuiConstants::minWidth, GuiConstants::maxWidth, GuiConstants::minWidth, "UI Width Persist" ), - // make_unique("uiHeightPersist", "height of this plugin's GUI. Editor listens for changes (e.g. on load)", GuiConstants::minHeight, GuiConstants::maxHeight, GuiConstants::minHeight, "UI Height Persist" ), - // make_unique("uiWidthTemp", "width of this plugin's GUI. Editor writes here on change (e.g. on window resize). Processor copies this into Persist before any save.", GuiConstants::minWidth, GuiConstants::maxWidth, GuiConstants::minWidth, "UI Width Temp" ), - // make_unique("uiHeightTemp", "height of this plugin's GUI. Editor writes here on change (e.g. on window resize). Processor copies this into Persist before any save.", GuiConstants::minHeight, GuiConstants::maxHeight, GuiConstants::minHeight, "UI Height Temp" ), - // make_unique("uiWidth", "width of this plugin's GUI", GuiConstants::minWidth, GuiConstants::maxWidth, GuiConstants::minWidth, "UI Width" ), - // make_unique("uiHeight", "height of this plugin's GUI", GuiConstants::minHeight, GuiConstants::maxHeight, GuiConstants::minHeight, "UI Height" ), // SoundFont 2.4 spec section 7.2: zero through 127, or 128. make_unique("bank", "which bank is selected in the soundfont", MidiConstants::midiMinValue, 128, MidiConstants::midiMinValue, "Bank" ), // note: banks may be sparse, and lack a 0th preset. so defend against this. @@ -93,22 +69,10 @@ AudioProcessorValueTreeState::ParameterLayout JuicySFAudioProcessor::createParam JuicySFAudioProcessor::~JuicySFAudioProcessor() { -// delete fluidSynthModel; } void JuicySFAudioProcessor::initialiseSynth() { fluidSynthModel.initialise(); - -// fluidSynth = fluidSynthModel.getSynth(); - - // const int numVoices = 8; - - // Add some voices... - // for (int i = numVoices; --i >= 0;) - // synth.addVoice(new SoundfontSynthVoice(fluidSynthModel.getSynth())); - - // ..and give the synth a sound to play - // synth.addSound(new SoundfontSynthSound()); } //============================================================================== @@ -142,22 +106,23 @@ double JuicySFAudioProcessor::getTailLengthSeconds() const int JuicySFAudioProcessor::getNumPrograms() { - return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs, + return fluidSynthModel.getNumPrograms(); // NB: some hosts don't cope very well if you tell them there are 0 programs, // so this should be at least 1, even if you're not really implementing programs. } int JuicySFAudioProcessor::getCurrentProgram() { - return 0; + return fluidSynthModel.getCurrentProgram(); } -void JuicySFAudioProcessor::setCurrentProgram (int index) +void JuicySFAudioProcessor::setCurrentProgram(int index) { + fluidSynthModel.setCurrentProgram(index); } -const String JuicySFAudioProcessor::getProgramName (int index) +const String JuicySFAudioProcessor::getProgramName(int index) { - return {}; + return fluidSynthModel.getProgramName(index); } void JuicySFAudioProcessor::changeProgramName (int index, const String& newName) @@ -208,11 +173,10 @@ AudioProcessor::BusesProperties JuicySFAudioProcessor::getBusesProperties() { void JuicySFAudioProcessor::processBlock(AudioBuffer& buffer, MidiBuffer& midiMessages) { jassert (!isUsingDoublePrecision()); - const int numSamples{buffer.getNumSamples()}; // Now pass any incoming midi messages to our keyboard state object, and let it // add messages to the buffer if the user is clicking on the on-screen keys - keyboardState.processNextMidiBuffer(midiMessages, 0, numSamples, true); + keyboardState.processNextMidiBuffer(midiMessages, 0, buffer.getNumSamples(), true); fluidSynthModel.processBlock(buffer, midiMessages); @@ -418,14 +382,6 @@ void JuicySFAudioProcessor::setStateInformation (const void* data, int sizeInByt } } -//void JuicySFAudioProcessor::subscribeToStateChanges(StateChangeSubscriber* subscriber) { -// stateChangeSubscribers.push_back(subscriber); -//} -// -//void JuicySFAudioProcessor::unsubscribeFromStateChanges(StateChangeSubscriber* subscriber) { -// stateChangeSubscribers.remove(subscriber); -//} - // FluidSynth only supports float in its process function, so that's all we can support. bool JuicySFAudioProcessor::supportsDoublePrecisionProcessing() const { return false; @@ -435,10 +391,6 @@ FluidSynthModel& JuicySFAudioProcessor::getFluidSynthModel() { return fluidSynthModel; } -//SharesParams& JuicySFAudioProcessor::getSharedParams() { -// return sharedParams; -//} - //============================================================================== // This creates new instances of the plugin.. AudioProcessor* JUCE_CALLTYPE createPluginFilter() diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index d3cfdca..2544766 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -64,34 +64,21 @@ public: bool supportsDoublePrecisionProcessing() const override; FluidSynthModel& getFluidSynthModel(); -// SharesParams& getSharedParams(); MidiKeyboardState keyboardState; -// void subscribeToStateChanges(StateChangeSubscriber* subscriber); -// void unsubscribeFromStateChanges(StateChangeSubscriber* subscriber); - private: void initialiseSynth(); -// Params sharedParams; AudioProcessorValueTreeState valueTreeState; - // ValueTree valueTree; FluidSynthModel fluidSynthModel; - // fluid_synth_t* fluidSynth; Synthesiser synth; -// // just a raw pointer; we do not own -// AudioProcessorEditor* pluginEditor; - -// list stateChangeSubscribers; - AudioProcessorValueTreeState::ParameterLayout createParameterLayout(); static BusesProperties getBusesProperties(); -// Model* model; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuicySFAudioProcessor) }; diff --git a/Source/SoundfontSynthSound.cpp b/Source/SoundfontSynthSound.cpp deleted file mode 100644 index 110fa33..0000000 --- a/Source/SoundfontSynthSound.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// -// Created by Alex Birch on 07/09/2017. -// - -#include "SoundfontSynthSound.h" - -bool SoundfontSynthSound::appliesToChannel(int) { - return true; -} - -bool SoundfontSynthSound::appliesToNote(int) { - return true; -} \ No newline at end of file diff --git a/Source/SoundfontSynthSound.h b/Source/SoundfontSynthSound.h deleted file mode 100644 index 52e0764..0000000 --- a/Source/SoundfontSynthSound.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Created by Alex Birch on 07/09/2017. -// - -#pragma once - -#include "../JuceLibraryCode/JuceHeader.h" - -class SoundfontSynthSound : public SynthesiserSound { -public: - bool appliesToNote (int /*midiNoteNumber*/) override; - bool appliesToChannel (int /*midiChannel*/) override; -}; \ No newline at end of file diff --git a/Source/SoundfontSynthVoice.cpp b/Source/SoundfontSynthVoice.cpp deleted file mode 100644 index 60590c1..0000000 --- a/Source/SoundfontSynthVoice.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// Created by Alex Birch on 07/09/2017. -// - -#include "SoundfontSynthVoice.h" -#include "SoundfontSynthSound.h" -#include "Util.h" - -using namespace std; - -SoundfontSynthVoice::SoundfontSynthVoice(shared_ptr synth) -: tailOff(0.0) -, level(0.0) -, currentAngle(0.0) -, angleDelta(0.0) -, midiNoteNumber(0) -, synth(synth) -{ -} - -bool SoundfontSynthVoice::canPlaySound(SynthesiserSound* sound) { - return dynamic_cast (sound) != nullptr; -} -void SoundfontSynthVoice::startNote( - int midiNoteNumber, - float velocity, - SynthesiserSound* sound, - int /*currentPitchWheelPosition*/) { - this->midiNoteNumber = midiNoteNumber; - DEBUG_PRINT ( juce::String::formatted("JUCE noteon: %d, %d\n", midiNoteNumber, velocity) ); - fluid_synth_noteon(synth.get(), 0, midiNoteNumber, static_cast(velocity * 127)); - -// currentAngle = 0.0; -// level = velocity * 0.15; -// tailOff = 0.0; -// -// double cyclesPerSecond = MidiMessage::getMidiNoteInHertz (midiNoteNumber); -// double cyclesPerSample = cyclesPerSecond / getSampleRate(); -// -// angleDelta = cyclesPerSample * 2.0 * double_Pi; - -// jassert(dynamic_cast (sound) != nullptr); -// SoundfontSynthSound* sfsynth = dynamic_cast (sound); -} - -void SoundfontSynthVoice::stopNote (float /*velocity*/, bool allowTailOff) { -// if (allowTailOff) { -// // start a tail-off by setting this flag. The render callback will pick up on -// // this and do a fade out, calling clearCurrentNote() when it's finished. -// -// // we only need to begin a tail-off if it's not already doing so - the -// if (tailOff == 0.0) { -// // stopNote method could be called more than once. -// tailOff = 1.0; -// } -// } else { -// // we're being told to stop playing immediately, so reset everything.. -// -// clearCurrentNote(); -// angleDelta = 0.0; -// } - DEBUG_PRINT ( juce::String("JUCE noteoff\n") ); - clearCurrentNote(); - fluid_synth_noteoff(synth.get(), 0, this->midiNoteNumber); -} - -// receives input as MIDI 0 to 16383, with 8192 being center -// this is also exactly the input fluidsynth requires -void SoundfontSynthVoice::pitchWheelMoved (int newValue) { -// fluid_synth_pitch_bend(synth, 0, newValue); -// int ppitch_bend; -// fluid_synth_get_pitch_bend(synth, 0, &ppitch_bend); -// int ppitch_bend_sens; -// fluid_synth_get_pitch_wheel_sens(synth, 0, &ppitch_bend_sens); -// Logger::outputDebugString ( juce::String::formatted("Pitch wheel: %d %d %d\n", newValue, ppitch_bend, ppitch_bend_sens) ); -} - -void SoundfontSynthVoice::controllerMoved (int controllerNumber, int newValue) { - // this seems to be "program change" event - DEBUG_PRINT ( juce::String::formatted("Controller moved: %d, %d\n", controllerNumber, newValue) ); -} - -void SoundfontSynthVoice::renderNextBlock (AudioBuffer& outputBuffer, int startSample, int numSamples) { - //fluid_synth_process(synth.get(), numSamples, 1, nullptr, outputBuffer.getNumChannels(), outputBuffer.getArrayOfWritePointers()); -} - -//void SoundfontSynthVoice::renderBlock (AudioBuffer& outputBuffer, int startSample, int numSamples) { -// fluid_synth_process(synth.get(), numSamples, 1, nullptr, outputBuffer.getNumChannels(), outputBuffer.getArrayOfWritePointers()); -// if (angleDelta == 0.0) { -// return; -// } -// while (--numSamples >= 0) { -// double qualifiedTailOff = tailOff > 0 ? tailOff : 1.0; -// auto currentSample = static_cast (std::sin (currentAngle) * level * qualifiedTailOff); -// for (int i = outputBuffer.getNumChannels(); --i >= 0;) -// outputBuffer.addSample (i, startSample, currentSample); -// -// currentAngle += angleDelta; -// ++startSample; -// -// if (tailOff > 0) { -// tailOff *= 0.99; -// -// if (tailOff <= 0.005) { -// clearCurrentNote(); -// angleDelta = 0.0; -// break; -// } -// } -// } -//} diff --git a/Source/SoundfontSynthVoice.h b/Source/SoundfontSynthVoice.h deleted file mode 100644 index 291ac3d..0000000 --- a/Source/SoundfontSynthVoice.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Created by Alex Birch on 07/09/2017. -// - -#pragma once - -#include -#include -#include "../JuceLibraryCode/JuceHeader.h" - -using namespace std; - -class SoundfontSynthVoice : public SynthesiserVoice { -public: - SoundfontSynthVoice(shared_ptr synth); - - bool canPlaySound (SynthesiserSound* sound) override; - void startNote ( - int midiNoteNumber, - float velocity, - SynthesiserSound* /*sound*/, - int /*currentPitchWheelPosition*/) override; - - void stopNote (float /*velocity*/, bool allowTailOff) override; - void pitchWheelMoved (int /*newValue*/) override; - - void controllerMoved (int /*controllerNumber*/, int /*newValue*/) override; - - void renderNextBlock (AudioBuffer& outputBuffer, int startSample, int numSamples) override; - -private: - double tailOff; - double level; - double currentAngle; - double angleDelta; - int midiNoteNumber; - - shared_ptr synth; -};