progress moving uiWidth/Height into audio params, and moving soundFontPath out of SharesParams (for better listener support, and to generalize)
This commit is contained in:
parent
6d2267e23a
commit
a990072f1f
|
@ -12,10 +12,12 @@ using namespace std;
|
|||
|
||||
FluidSynthModel::FluidSynthModel(
|
||||
AudioProcessorValueTreeState& valueTreeState,
|
||||
SharesParams& sharedParams
|
||||
ValueTree& valueTree
|
||||
// SharesParams& sharedParams
|
||||
)
|
||||
: valueTreeState{valueTreeState}
|
||||
, sharedParams{sharedParams}
|
||||
, valueTree{valueTree}
|
||||
// , sharedParams{sharedParams}
|
||||
//, synth{nullptr}
|
||||
, settings{nullptr, nullptr}
|
||||
, currentSoundFontAbsPath{}
|
||||
|
@ -24,10 +26,12 @@ FluidSynthModel::FluidSynthModel(
|
|||
, sfont_id{0}
|
||||
, channel{0}/*,
|
||||
mod(nullptr)*/
|
||||
{
|
||||
valueTree.addListener(this);
|
||||
}
|
||||
|
||||
{}
|
||||
|
||||
// FluidSynthModel::~FluidSynthModel() {
|
||||
FluidSynthModel::~FluidSynthModel() {
|
||||
valueTree.removeListener(this);
|
||||
// if (initialised) {
|
||||
// delete_fluid_audio_driver(driver);
|
||||
// delete_fluid_synth(synth);
|
||||
|
@ -36,7 +40,7 @@ mod(nullptr)*/
|
|||
// delete settings;
|
||||
// delete_fluid_mod(mod);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
int FluidSynthModel::handleMidiEvent(void* data, fluid_midi_event_t* event)
|
||||
{
|
||||
|
@ -79,16 +83,16 @@ void FluidSynthModel::initialise() {
|
|||
synth = { new_fluid_synth(settings.get()), delete_fluid_synth };
|
||||
fluid_synth_set_sample_rate(synth.get(), currentSampleRate);
|
||||
|
||||
valueTreeState.getParameter("soundFontPath")->getValue();
|
||||
// valueTreeState.getParameter("soundFontPath")->getValue();
|
||||
// RangedAudioParameter *param {valueTreeState.getParameter("release")};
|
||||
// jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
|
||||
// AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
|
||||
// *castParam = m.getControllerValue();
|
||||
|
||||
if (sharedParams.getSoundFontPath().isNotEmpty()) {
|
||||
loadFont(sharedParams.getSoundFontPath());
|
||||
// if (sharedParams.getSoundFontPath().isNotEmpty()) {
|
||||
// loadFont(sharedParams.getSoundFontPath());
|
||||
// changePreset(sharedParams->getBank(), sharedParams->getPreset());
|
||||
}
|
||||
// }
|
||||
|
||||
fluid_synth_set_gain(synth.get(), 2.0);
|
||||
|
||||
|
@ -192,9 +196,23 @@ void FluidSynthModel::initialise() {
|
|||
fluid_mod_set_amount(mod.get(), 1000.0f);
|
||||
fluid_synth_add_default_mod(synth.get(), mod.get(), FLUID_SYNTH_ADD);
|
||||
|
||||
valueTree.sendPropertyChangeMessage("soundFontPath");
|
||||
|
||||
// initialised = true;
|
||||
}
|
||||
|
||||
void FluidSynthModel::valueTreePropertyChanged(ValueTree& treeWhosePropertyHasChanged,
|
||||
const Identifier& property) {
|
||||
if (&treeWhosePropertyHasChanged == &valueTree) {
|
||||
if (property == Identifier("soundFontPath")) {
|
||||
String soundFontPath{treeWhosePropertyHasChanged.getProperty("soundFontPath", "")};
|
||||
if (soundFontPath.isNotEmpty()) {
|
||||
loadFont(soundFontPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FluidSynthModel::setControllerValue(int controller, int value) {
|
||||
fluid_midi_event_t *midi_event(new_fluid_midi_event());
|
||||
fluid_midi_event_set_type(midi_event, static_cast<int>(CONTROL_CHANGE));
|
||||
|
@ -300,7 +318,8 @@ void FluidSynthModel::onFileNameChanged(const String &absPath, int bank, int pre
|
|||
}
|
||||
unloadAndLoadFont(absPath);
|
||||
changePreset(bank, preset);
|
||||
sharedParams.setSoundFontPath(absPath);
|
||||
valueTree.setPropertyExcludingListener(this, "soundFontPath", absPath, nullptr);
|
||||
// sharedParams.setSoundFontPath(absPath);
|
||||
eventListeners.call(&FluidSynthModel::Listener::fontChanged, this, absPath);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,13 +17,14 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
class FluidSynthModel {
|
||||
class FluidSynthModel: public ValueTree::Listener {
|
||||
public:
|
||||
FluidSynthModel(
|
||||
AudioProcessorValueTreeState& valueTreeState,
|
||||
SharesParams& sharedParams
|
||||
// SharesParams& sharedParams
|
||||
ValueTree& valueTree
|
||||
);
|
||||
// ~FluidSynthModel();
|
||||
~FluidSynthModel();
|
||||
|
||||
shared_ptr<fluid_synth_t> getSynth();
|
||||
void initialise();
|
||||
|
@ -67,14 +68,53 @@ public:
|
|||
|
||||
const String& getCurrentSoundFontAbsPath();
|
||||
|
||||
|
||||
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 {};
|
||||
|
||||
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 handleMidiEvent(void* data, fluid_midi_event_t* event);
|
||||
|
||||
AudioProcessorValueTreeState& valueTreeState;
|
||||
SharesParams& sharedParams;
|
||||
// ValueTreeListener valueTreeListener;
|
||||
|
||||
shared_ptr<fluid_synth_t> synth;
|
||||
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
|
||||
// http://www.fluidsynth.org/api/
|
||||
// in their examples, they destroy the synth before destroying the settings
|
||||
unique_ptr<fluid_settings_t, decltype(&delete_fluid_settings)> settings;
|
||||
// TODO: shared_ptr may ruin our guarantee of synth's being destroyed first, so consider changing the access we expose
|
||||
shared_ptr<fluid_synth_t> synth;
|
||||
// unique_ptr<fluid_midi_driver_t, decltype(&delete_fluid_midi_driver)> midiDriver;
|
||||
|
||||
String currentSoundFontAbsPath;
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
using namespace std;
|
||||
|
||||
Params::Params() noexcept
|
||||
: uiWidth{GuiConstants::minWidth}
|
||||
, uiHeight{GuiConstants::minHeight}
|
||||
, soundFontPath{String()}
|
||||
// : uiWidth{GuiConstants::minWidth}
|
||||
// , uiHeight{GuiConstants::minHeight}
|
||||
: soundFontPath{String()}
|
||||
// , preset{-1}
|
||||
// , bank{-1}
|
||||
// , attack{0}
|
||||
|
@ -30,8 +30,8 @@ Params::Params() noexcept
|
|||
}
|
||||
|
||||
void Params::setAttributesOnXml(shared_ptr<XmlElement> xml) {
|
||||
xml->setAttribute("uiWidth", uiWidth);
|
||||
xml->setAttribute("uiHeight", uiHeight);
|
||||
// xml->setAttribute("uiWidth", uiWidth);
|
||||
// xml->setAttribute("uiHeight", uiHeight);
|
||||
xml->setAttribute("soundFontPath", soundFontPath);
|
||||
// xml.setAttribute("preset", preset);
|
||||
// xml.setAttribute("bank", bank);
|
||||
|
@ -44,8 +44,8 @@ void Params::setAttributesOnXml(shared_ptr<XmlElement> xml) {
|
|||
}
|
||||
|
||||
void Params::loadAttributesFromXml(shared_ptr<XmlElement> xmlState) {
|
||||
uiWidth = jmin(jmax(xmlState->getIntAttribute("uiWidth", uiWidth), GuiConstants::minWidth), GuiConstants::maxWidth);
|
||||
uiHeight = jmin(jmax(xmlState->getIntAttribute("uiHeight", uiHeight), GuiConstants::minHeight), GuiConstants::maxHeight);
|
||||
// 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);
|
||||
|
@ -95,12 +95,12 @@ String& Params::getSoundFontPath() {
|
|||
//int Params::getBank() {
|
||||
// return bank;
|
||||
//}
|
||||
int Params::getUiWidth() {
|
||||
return uiWidth;
|
||||
}
|
||||
int Params::getUiHeight() {
|
||||
return uiHeight;
|
||||
}
|
||||
// int Params::getUiWidth() {
|
||||
// return uiWidth;
|
||||
// }
|
||||
// int Params::getUiHeight() {
|
||||
// return uiHeight;
|
||||
// }
|
||||
//int Params::getAttack() {
|
||||
// return attack;
|
||||
//}
|
||||
|
@ -126,12 +126,12 @@ int Params::getUiHeight() {
|
|||
//void Params::setBank(int value) {
|
||||
// bank = value;
|
||||
//}
|
||||
void Params::setUiWidth(int value) {
|
||||
uiWidth = value;
|
||||
}
|
||||
void Params::setUiHeight(int value) {
|
||||
uiHeight = value;
|
||||
}
|
||||
// void Params::setUiWidth(int value) {
|
||||
// uiWidth = value;
|
||||
// }
|
||||
// void Params::setUiHeight(int value) {
|
||||
// uiHeight = value;
|
||||
// }
|
||||
//void Params::setAttack(int value) {
|
||||
// attack = value;
|
||||
//}
|
||||
|
|
|
@ -20,10 +20,10 @@ public:
|
|||
// 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 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;
|
||||
|
@ -40,8 +40,8 @@ public:
|
|||
// virtual void setFilterResonance(int value) override;
|
||||
|
||||
private:
|
||||
int uiWidth;
|
||||
int uiHeight;
|
||||
// int uiWidth;
|
||||
// int uiHeight;
|
||||
|
||||
String soundFontPath;
|
||||
// int preset;
|
||||
|
|
|
@ -13,15 +13,17 @@
|
|||
#include "GuiConstants.h"
|
||||
|
||||
//==============================================================================
|
||||
JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor(JuicySFAudioProcessor& p, AudioProcessorValueTreeState& valueTreeState)
|
||||
: AudioProcessorEditor{&p},
|
||||
processor{p},
|
||||
valueTreeState{valueTreeState},
|
||||
sharedParams{p.getSharedParams()},
|
||||
midiKeyboard{p.keyboardState, SurjectiveMidiKeyboardComponent::horizontalKeyboard},
|
||||
tablesComponent{valueTreeState, p.getFluidSynthModel()},
|
||||
filePicker{valueTreeState, p.getFluidSynthModel()},
|
||||
slidersComponent{p.getSharedParams(), valueTreeState, p.getFluidSynthModel()}
|
||||
JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor(
|
||||
JuicySFAudioProcessor& p,
|
||||
AudioProcessorValueTreeState& valueTreeState)
|
||||
: AudioProcessorEditor{&p}
|
||||
, processor{p}
|
||||
, valueTreeState{valueTreeState}
|
||||
// sharedParams{p.getSharedParams()},
|
||||
, midiKeyboard{p.keyboardState, SurjectiveMidiKeyboardComponent::horizontalKeyboard}
|
||||
, tablesComponent{valueTreeState, p.getFluidSynthModel()}
|
||||
, filePicker{valueTreeState, p.getFluidSynthModel()}
|
||||
, slidersComponent{valueTreeState, p.getFluidSynthModel()}
|
||||
{
|
||||
// set resize limits for this plug-in
|
||||
setResizeLimits(
|
||||
|
@ -30,7 +32,28 @@ JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor(JuicySFAudioProcessor&
|
|||
GuiConstants::maxWidth,
|
||||
GuiConstants::maxHeight);
|
||||
|
||||
setSize(sharedParams.getUiWidth(), sharedParams.getUiHeight());
|
||||
// int width, height;
|
||||
// {
|
||||
// RangedAudioParameter *param {valueTreeState.getParameter("uiWidth")};
|
||||
// jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
|
||||
// AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
|
||||
// width = castParam->get();
|
||||
// }
|
||||
// {
|
||||
// RangedAudioParameter *param {valueTreeState.getParameter("uiHeight")};
|
||||
// jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
|
||||
// AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
|
||||
// height = castParam->get();
|
||||
// }
|
||||
|
||||
// valueTreeState.addParameterListener("uiWidthPersist", this);
|
||||
// valueTreeState.addParameterListener("uiHeightPersist", this);
|
||||
// valueTreeState.addParameterListener("uiWidth", this);
|
||||
// valueTreeState.addParameterListener("uiHeight", this);
|
||||
|
||||
valueTreeState.state.addListener(this);
|
||||
|
||||
setSize(GuiConstants::minWidth, GuiConstants::minHeight);
|
||||
|
||||
// processor.subscribeToStateChanges(this);
|
||||
|
||||
|
@ -50,9 +73,53 @@ JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor(JuicySFAudioProcessor&
|
|||
|
||||
JuicySFAudioProcessorEditor::~JuicySFAudioProcessorEditor()
|
||||
{
|
||||
// valueTreeState.removeParameterListener("uiWidthPersist", this);
|
||||
// valueTreeState.removeParameterListener("uiHeightPersist", this);
|
||||
// valueTreeState.removeParameterListener("uiWidth", this);
|
||||
// valueTreeState.removeParameterListener("uiHeight", this);
|
||||
valueTreeState.state.removeListener(this);
|
||||
// processor.unsubscribeFromStateChanges(this);
|
||||
}
|
||||
|
||||
void JuicySFAudioProcessorEditor::valueTreePropertyChanged(ValueTree& treeWhosePropertyHasChanged,
|
||||
const Identifier& property) {
|
||||
if (&treeWhosePropertyHasChanged == &valueTreeState.state) {
|
||||
if (property == Identifier("uiWidth")) {
|
||||
// String soundFontPath{treeWhosePropertyHasChanged.getProperty("soundFontPath", "")};
|
||||
// if (soundFontPath.isNotEmpty()) {
|
||||
// loadFont(soundFontPath);
|
||||
// }
|
||||
int value{treeWhosePropertyHasChanged.getProperty("uiWidth", GuiConstants::minWidth)};
|
||||
setSize(value, getHeight());
|
||||
} else if (property == Identifier("uiHeight")) {
|
||||
int value{treeWhosePropertyHasChanged.getProperty("uiHeight", GuiConstants::minHeight)};
|
||||
setSize(getWidth(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// void JuicySFAudioProcessorEditor::parameterChanged(const String& parameterID, float newValue) {
|
||||
// // if (parameterID == "uiWidthPersist"
|
||||
// // || parameterID == "uiHeightPersist") {
|
||||
// if (parameterID == "uiWidth"
|
||||
// || parameterID == "uiHeight") {
|
||||
// RangedAudioParameter *param {valueTreeState.getParameter(parameterID)};
|
||||
// jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
|
||||
// AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
|
||||
// int value{castParam->get()};
|
||||
// // if (parameterID == "uiWidthPersist") {
|
||||
// // setSize(value, getHeight());
|
||||
// // } else if (parameterID == "uiHeightPersist") {
|
||||
// // setSize(getWidth(), value);
|
||||
// // }
|
||||
// if (parameterID == "uiWidth") {
|
||||
// setSize(value, getHeight());
|
||||
// } else if (parameterID == "uiHeight") {
|
||||
// setSize(getWidth(), value);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
//void JuicySFAudioProcessorEditor::getStateInformation (XmlElement& xml) {
|
||||
// // save
|
||||
// xml.setAttribute ("uiWidth", getWidth());
|
||||
|
@ -104,8 +171,24 @@ void JuicySFAudioProcessorEditor::resized()
|
|||
|
||||
tablesComponent.setBounds(rContent);
|
||||
|
||||
sharedParams.setUiWidth(getWidth());
|
||||
sharedParams.setUiHeight(getHeight());
|
||||
valueTreeState.state.setPropertyExcludingListener(this, "uiWidth", getWidth(), nullptr);
|
||||
valueTreeState.state.setPropertyExcludingListener(this, "uiHeight", getHeight(), nullptr);
|
||||
|
||||
// {
|
||||
// RangedAudioParameter *param {valueTreeState.getParameter("uiWidth2")};
|
||||
// jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
|
||||
// AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
|
||||
// *castParam = getWidth();
|
||||
// }
|
||||
// {
|
||||
// RangedAudioParameter *param {valueTreeState.getParameter("uiHeight2")};
|
||||
// jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
|
||||
// AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
|
||||
// *castParam = getHeight();
|
||||
// }
|
||||
|
||||
// sharedParams.setUiWidth(getWidth());
|
||||
// sharedParams.setUiHeight(getHeight());
|
||||
|
||||
// Rectangle<int> r2 (getLocalBounds());
|
||||
// r2.reduce(0, padding);
|
||||
|
@ -154,10 +237,10 @@ bool JuicySFAudioProcessorEditor::keyStateChanged (bool isKeyDown) {
|
|||
// return false;
|
||||
}
|
||||
|
||||
FilePickerFragment& JuicySFAudioProcessorEditor::getFilePicker() {
|
||||
return filePicker;
|
||||
}
|
||||
|
||||
SlidersFragment& JuicySFAudioProcessorEditor::getSliders() {
|
||||
return slidersComponent;
|
||||
}
|
||||
//FilePickerFragment& JuicySFAudioProcessorEditor::getFilePicker() {
|
||||
// return filePicker;
|
||||
//}
|
||||
//
|
||||
//SlidersFragment& JuicySFAudioProcessorEditor::getSliders() {
|
||||
// return slidersComponent;
|
||||
//}
|
||||
|
|
|
@ -23,14 +23,18 @@
|
|||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
class JuicySFAudioProcessorEditor : public AudioProcessorEditor,
|
||||
public ExposesComponents/*,
|
||||
class JuicySFAudioProcessorEditor
|
||||
: public AudioProcessorEditor
|
||||
// , public AudioProcessorValueTreeState::Listener
|
||||
, public ValueTree::Listener
|
||||
/*,
|
||||
, public ExposesComponents
|
||||
public StateChangeSubscriber*/
|
||||
{
|
||||
public:
|
||||
JuicySFAudioProcessorEditor(
|
||||
JuicySFAudioProcessor&,
|
||||
AudioProcessorValueTreeState& state
|
||||
AudioProcessorValueTreeState& valueTreeState
|
||||
);
|
||||
~JuicySFAudioProcessorEditor();
|
||||
|
||||
|
@ -44,16 +48,33 @@ public:
|
|||
// void getStateInformation (XmlElement& xml) override;
|
||||
// void setStateInformation (XmlElement* xmlState) override;
|
||||
|
||||
virtual FilePickerFragment& getFilePicker() override;
|
||||
virtual SlidersFragment& getSliders() override;
|
||||
// virtual FilePickerFragment& getFilePicker() override;
|
||||
// virtual SlidersFragment& getSliders() override;
|
||||
// virtual void parameterChanged (const String& parameterID, float newValue) override;
|
||||
|
||||
// int getWidth();
|
||||
// int getHeight();
|
||||
|
||||
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 {};
|
||||
|
||||
private:
|
||||
|
||||
// This reference is provided as a quick way for your editor to
|
||||
// access the processor object that created it.
|
||||
JuicySFAudioProcessor& processor;
|
||||
|
||||
AudioProcessorValueTreeState& valueTreeState;
|
||||
SharesParams& sharedParams;
|
||||
// SharesParams& sharedParams;
|
||||
|
||||
SurjectiveMidiKeyboardComponent midiKeyboard;
|
||||
TablesComponent tablesComponent;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "Util.h"
|
||||
#include "SharesParams.h"
|
||||
#include "Params.h"
|
||||
#include "MidiConstants.h"
|
||||
#include "GuiConstants.h"
|
||||
|
||||
using namespace std;
|
||||
using Parameter = AudioProcessorValueTreeState::Parameter;
|
||||
|
@ -29,13 +29,13 @@ AudioProcessor* JUCE_CALLTYPE createPluginFilter();
|
|||
//, sharedParams{static_pointer_cast<SharesParams>(make_shared<Params>())}
|
||||
JuicySFAudioProcessor::JuicySFAudioProcessor()
|
||||
: AudioProcessor{getBusesProperties()}
|
||||
, sharedParams{}
|
||||
// , sharedParams{}
|
||||
, valueTreeState{
|
||||
*this,
|
||||
nullptr,
|
||||
{ "MYPLUGINSETTINGS" },
|
||||
createParameterLayout()}
|
||||
, fluidSynthModel{valueTreeState, sharedParams}
|
||||
, fluidSynthModel{valueTreeState, valueTree}
|
||||
//, fluidSynthModel{*this}
|
||||
//, pluginEditor(nullptr)
|
||||
{
|
||||
|
@ -53,15 +53,22 @@ AudioProcessorValueTreeState::ParameterLayout JuicySFAudioProcessor::createParam
|
|||
|
||||
// https://stackoverflow.com/a/8469002/5257399
|
||||
unique_ptr<AudioParameterInt> params[] {
|
||||
make_unique<AudioParameterInt>("bank", "which bank is selected in the soundfont", 0, 127, 0, "Bank" ),
|
||||
// make_unique<AudioParameterInt>("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<AudioParameterInt>("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<AudioParameterInt>("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<AudioParameterInt>("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<AudioParameterInt>("uiWidth", "width of this plugin's GUI", GuiConstants::minWidth, GuiConstants::maxWidth, GuiConstants::minWidth, "UI Width" ),
|
||||
make_unique<AudioParameterInt>("uiHeight", "height of this plugin's GUI", GuiConstants::minHeight, GuiConstants::maxHeight, GuiConstants::minHeight, "UI Height" ),
|
||||
// todo: check whether bank really is 0-127
|
||||
make_unique<AudioParameterInt>("bank", "which bank is selected in the soundfont", MidiConstants::midiMinValue, MidiConstants::midiMaxValue, MidiConstants::midiMinValue, "Bank" ),
|
||||
// note: banks may be sparse, and lack a 0th preset. so defend against this.
|
||||
make_unique<AudioParameterInt>("preset", "which patch (aka patch, program, instrument) is selected in the soundfont", 0, 127, 0, "Preset" ),
|
||||
make_unique<AudioParameterInt>("attack", "volume envelope attack time", 0, 127, 0, "A" ),
|
||||
make_unique<AudioParameterInt>("decay", "volume envelope sustain attentuation", 0, 127, 0, "D" ),
|
||||
make_unique<AudioParameterInt>("sustain", "volume envelope decay time", 0, 127, 0, "S" ),
|
||||
make_unique<AudioParameterInt>("release", "volume envelope release time", 0, 127, 0, "R" ),
|
||||
make_unique<AudioParameterInt>("filterCutOff", "low-pass filter cut-off frequency", 0, 127, 0, "Cut" ),
|
||||
make_unique<AudioParameterInt>("filterResonance", "low-pass filter resonance attentuation", 0, 127, 0, "Res" ),
|
||||
make_unique<AudioParameterInt>("preset", "which patch (aka patch, program, instrument) is selected in the soundfont", MidiConstants::midiMinValue, MidiConstants::midiMaxValue, MidiConstants::midiMinValue, "Preset" ),
|
||||
make_unique<AudioParameterInt>("attack", "volume envelope attack time", MidiConstants::midiMinValue, MidiConstants::midiMaxValue, MidiConstants::midiMinValue, "A" ),
|
||||
make_unique<AudioParameterInt>("decay", "volume envelope sustain attentuation", MidiConstants::midiMinValue, MidiConstants::midiMaxValue, MidiConstants::midiMinValue, "D" ),
|
||||
make_unique<AudioParameterInt>("sustain", "volume envelope decay time", MidiConstants::midiMinValue, MidiConstants::midiMaxValue, MidiConstants::midiMinValue, "S" ),
|
||||
make_unique<AudioParameterInt>("release", "volume envelope release time", MidiConstants::midiMinValue, MidiConstants::midiMaxValue, MidiConstants::midiMinValue, "R" ),
|
||||
make_unique<AudioParameterInt>("filterCutOff", "low-pass filter cut-off frequency", MidiConstants::midiMinValue, MidiConstants::midiMaxValue, MidiConstants::midiMinValue, "Cut" ),
|
||||
make_unique<AudioParameterInt>("filterResonance", "low-pass filter resonance attentuation", MidiConstants::midiMinValue, MidiConstants::midiMaxValue, MidiConstants::midiMinValue, "Res" ),
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -215,7 +222,7 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
|
|||
fluid_midi_event_set_channel(midi_event, fluidSynthModel.getChannel());
|
||||
fluid_midi_event_set_control(midi_event, m.getControllerNumber());
|
||||
fluid_midi_event_set_value(midi_event, m.getControllerValue());
|
||||
fluid_synth_handle_midi_event(fluidSynth, midi_event);
|
||||
fluid_synth_handle_midi_event(fluidSynthModel.getSynth().get(), midi_event);
|
||||
delete_fluid_midi_event(midi_event);
|
||||
|
||||
switch(static_cast<fluid_midi_control_change>(m.getControllerNumber())) {
|
||||
|
@ -274,21 +281,21 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
|
|||
fluid_midi_event_set_type(midi_event, static_cast<int>(PROGRAM_CHANGE));
|
||||
fluid_midi_event_set_channel(midi_event, fluidSynthModel.getChannel());
|
||||
fluid_midi_event_set_program(midi_event, m.getProgramChangeNumber());
|
||||
fluid_synth_handle_midi_event(fluidSynth, midi_event);
|
||||
fluid_synth_handle_midi_event(fluidSynthModel.getSynth().get(), midi_event);
|
||||
delete_fluid_midi_event(midi_event);
|
||||
} else if (m.isPitchWheel()) {
|
||||
fluid_midi_event_t *midi_event(new_fluid_midi_event());
|
||||
fluid_midi_event_set_type(midi_event, static_cast<int>(PITCH_BEND));
|
||||
fluid_midi_event_set_channel(midi_event, fluidSynthModel.getChannel());
|
||||
fluid_midi_event_set_pitch(midi_event, m.getPitchWheelValue());
|
||||
fluid_synth_handle_midi_event(fluidSynth, midi_event);
|
||||
fluid_synth_handle_midi_event(fluidSynthModel.getSynth().get(), midi_event);
|
||||
delete_fluid_midi_event(midi_event);
|
||||
} else if (m.isChannelPressure()) {
|
||||
fluid_midi_event_t *midi_event(new_fluid_midi_event());
|
||||
fluid_midi_event_set_type(midi_event, static_cast<int>(CHANNEL_PRESSURE));
|
||||
fluid_midi_event_set_channel(midi_event, fluidSynthModel.getChannel());
|
||||
fluid_midi_event_set_program(midi_event, m.getChannelPressureValue());
|
||||
fluid_synth_handle_midi_event(fluidSynth, midi_event);
|
||||
fluid_synth_handle_midi_event(fluidSynthModel.getSynth().get(), midi_event);
|
||||
delete_fluid_midi_event(midi_event);
|
||||
} else if (m.isAftertouch()) {
|
||||
fluid_midi_event_t *midi_event(new_fluid_midi_event());
|
||||
|
@ -296,12 +303,12 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
|
|||
fluid_midi_event_set_channel(midi_event, fluidSynthModel.getChannel());
|
||||
fluid_midi_event_set_key(midi_event, m.getNoteNumber());
|
||||
fluid_midi_event_set_value(midi_event, m.getAfterTouchValue());
|
||||
fluid_synth_handle_midi_event(fluidSynth, midi_event);
|
||||
fluid_synth_handle_midi_event(fluidSynthModel.getSynth().get(), midi_event);
|
||||
delete_fluid_midi_event(midi_event);
|
||||
// } else if (m.isMetaEvent()) {
|
||||
// fluid_midi_event_t *midi_event(new_fluid_midi_event());
|
||||
// fluid_midi_event_set_type(midi_event, static_cast<int>(MIDI_SYSTEM_RESET));
|
||||
// fluid_synth_handle_midi_event(fluidSynth, midi_event);
|
||||
// fluid_synth_handle_midi_event(fluidSynthModel.getSynth().get(), midi_event);
|
||||
// delete_fluid_midi_event(midi_event);
|
||||
} else if (m.isSysEx()) {
|
||||
fluid_midi_event_t *midi_event(new_fluid_midi_event());
|
||||
|
@ -309,7 +316,7 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
|
|||
// I assume that the MidiMessage's sysex buffer would be freed anyway when MidiMessage is destroyed, so set dynamic=false
|
||||
// to ensure that fluidsynth does not attempt to free the sysex buffer during delete_fluid_midi_event()
|
||||
fluid_midi_event_set_sysex(midi_event, const_cast<juce::uint8*>(m.getSysExData()), m.getSysExDataSize(), static_cast<int>(false));
|
||||
fluid_synth_handle_midi_event(fluidSynth, midi_event);
|
||||
fluid_synth_handle_midi_event(fluidSynthModel.getSynth().get(), midi_event);
|
||||
delete_fluid_midi_event(midi_event);
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +331,7 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
|
|||
|
||||
// and now get our synth to process these midi events and generate its output.
|
||||
synth.renderNextBlock (buffer, midiMessages, 0, numSamples);
|
||||
fluid_synth_process(fluidSynth, numSamples, 0, nullptr, buffer.getNumChannels(), buffer.getArrayOfWritePointers());
|
||||
fluid_synth_process(fluidSynthModel.getSynth().get(), numSamples, 0, nullptr, buffer.getNumChannels(), buffer.getArrayOfWritePointers());
|
||||
|
||||
// (see juce_VST3_Wrapper.cpp for the assertion this would trip otherwise)
|
||||
// we are !JucePlugin_ProducesMidiOutput, so clear remaining MIDI messages from our buffer
|
||||
|
@ -364,7 +371,7 @@ void JuicySFAudioProcessor::getStateInformation (MemoryBlock& destData)
|
|||
// sharedParams->setAttributesOnXml(xml);
|
||||
auto state{valueTreeState.copyState()};
|
||||
shared_ptr<XmlElement> xml{state.createXml()};
|
||||
sharedParams.setAttributesOnXml(xml);
|
||||
// sharedParams.setAttributesOnXml(xml);
|
||||
|
||||
// list<StateChangeSubscriber*>::iterator p;
|
||||
// for(p = stateChangeSubscribers.begin(); p != stateChangeSubscribers.end(); p++) {
|
||||
|
@ -399,7 +406,7 @@ void JuicySFAudioProcessor::setStateInformation (const void* data, int sizeInByt
|
|||
// }
|
||||
|
||||
// ok, now pull out our last window size..
|
||||
sharedParams.loadAttributesFromXml(xmlState);
|
||||
// sharedParams.loadAttributesFromXml(xmlState);
|
||||
|
||||
// Now reload our parameters..
|
||||
|
||||
|
@ -448,9 +455,9 @@ FluidSynthModel& JuicySFAudioProcessor::getFluidSynthModel() {
|
|||
return fluidSynthModel;
|
||||
}
|
||||
|
||||
SharesParams& JuicySFAudioProcessor::getSharedParams() {
|
||||
return sharedParams;
|
||||
}
|
||||
//SharesParams& JuicySFAudioProcessor::getSharedParams() {
|
||||
// return sharedParams;
|
||||
//}
|
||||
|
||||
//==============================================================================
|
||||
// This creates new instances of the plugin..
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
bool supportsDoublePrecisionProcessing() const override;
|
||||
|
||||
FluidSynthModel& getFluidSynthModel();
|
||||
SharesParams& getSharedParams();
|
||||
// SharesParams& getSharedParams();
|
||||
|
||||
MidiKeyboardState keyboardState;
|
||||
|
||||
|
@ -74,11 +74,12 @@ public:
|
|||
private:
|
||||
void initialiseSynth();
|
||||
|
||||
Params sharedParams;
|
||||
// Params sharedParams;
|
||||
AudioProcessorValueTreeState valueTreeState;
|
||||
ValueTree valueTree;
|
||||
|
||||
FluidSynthModel fluidSynthModel;
|
||||
fluid_synth_t* fluidSynth;
|
||||
// fluid_synth_t* fluidSynth;
|
||||
Synthesiser synth;
|
||||
|
||||
// // just a raw pointer; we do not own
|
||||
|
|
|
@ -24,10 +24,10 @@ public:
|
|||
// 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 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;
|
||||
|
|
|
@ -115,11 +115,11 @@ void SlidersComponent::acceptMidiControlEvent(int controller, int value) {
|
|||
// }
|
||||
|
||||
SlidersComponent::SlidersComponent(
|
||||
SharesParams& sharedParams,
|
||||
// SharesParams& sharedParams,
|
||||
AudioProcessorValueTreeState& valueTreeState,
|
||||
FluidSynthModel& fluidSynthModel)
|
||||
: sharedParams{sharedParams}
|
||||
, valueTreeState{valueTreeState}
|
||||
// : sharedParams{sharedParams}
|
||||
: valueTreeState{valueTreeState}
|
||||
, fluidSynthModel{fluidSynthModel}
|
||||
, envelopeGroup{"envelopeGroup", "Envelope"}
|
||||
, filterGroup{"filterGroup", "Filter"}
|
||||
|
|
|
@ -13,7 +13,7 @@ class SlidersComponent : public Component,
|
|||
{
|
||||
public:
|
||||
SlidersComponent(
|
||||
SharesParams& sharedParams,
|
||||
// SharesParams& sharedParams,
|
||||
AudioProcessorValueTreeState& valueTreeState,
|
||||
FluidSynthModel& fluidSynthModel);
|
||||
~SlidersComponent();
|
||||
|
@ -35,7 +35,7 @@ public:
|
|||
private:
|
||||
std::function<void()> makeSliderListener(Slider& slider, int controller);
|
||||
|
||||
SharesParams& sharedParams;
|
||||
// SharesParams& sharedParams;
|
||||
AudioProcessorValueTreeState& valueTreeState;
|
||||
FluidSynthModel& fluidSynthModel;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user