encapsulate responsibility of params. add params for ADSR and filter. attempt to sync Slider. not obviously working yet.
This commit is contained in:
parent
758dda40a9
commit
218beb00e7
|
@ -34,6 +34,7 @@
|
|||
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 */; };
|
||||
358E458E22BEE5090087ED8D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28CA077CDD21D0FEC66FC290 /* AudioToolbox.framework */; };
|
||||
|
@ -285,6 +286,11 @@
|
|||
2C66D01D1DD9006E77E2E260 /* include_juce_data_structures.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_data_structures.mm; path = ../../JuceLibraryCode/include_juce_data_structures.mm; sourceTree = SOURCE_ROOT; };
|
||||
307CB49DF900DE4A612FF98E /* FluidSynthModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FluidSynthModel.h; path = ../../Source/FluidSynthModel.h; sourceTree = SOURCE_ROOT; };
|
||||
35099D9022CA8EF500CD4523 /* Util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Util.h; path = ../../Source/Util.h; sourceTree = "<group>"; };
|
||||
35099D9122CAA87D00CD4523 /* Params.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Params.cpp; path = ../../Source/Params.cpp; sourceTree = "<group>"; };
|
||||
35099D9222CAA87D00CD4523 /* Params.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Params.h; path = ../../Source/Params.h; sourceTree = "<group>"; };
|
||||
35099D9422CAB0A400CD4523 /* GuiConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GuiConstants.h; path = ../../Source/GuiConstants.h; sourceTree = "<group>"; };
|
||||
35099D9522CAB7CD00CD4523 /* SlidersFragment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SlidersFragment.h; path = ../../Source/SlidersFragment.h; sourceTree = "<group>"; };
|
||||
35099D9622CAC3C800CD4523 /* SharesParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharesParams.h; path = ../../Source/SharesParams.h; sourceTree = "<group>"; };
|
||||
35880F58CB540AD30D1B0ED3 /* TablesComponent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TablesComponent.h; path = ../../Source/TablesComponent.h; sourceTree = SOURCE_ROOT; };
|
||||
358E45B422BEE53A0087ED8D /* libpcre.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libpcre.1.dylib; sourceTree = "<group>"; };
|
||||
358E45B522BEE53A0087ED8D /* libvorbisenc.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libvorbisenc.2.dylib; sourceTree = "<group>"; };
|
||||
|
@ -521,6 +527,7 @@
|
|||
403EB0CF49CF1D62BF359002 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
35099D9622CAC3C800CD4523 /* SharesParams.h */,
|
||||
DECFA95359BC1DDDD1CC86C3 /* BankAndPreset.cpp */,
|
||||
B000E7A360C0C86ADD3C911D /* BankAndPreset.h */,
|
||||
F1EB35E262DC717222E2F93D /* ExposesComponents.h */,
|
||||
|
@ -554,6 +561,10 @@
|
|||
358E45F922C80DCA0087ED8D /* SlidersComponent.cpp */,
|
||||
358E45FA22C80DCA0087ED8D /* SlidersComponent.h */,
|
||||
35099D9022CA8EF500CD4523 /* Util.h */,
|
||||
35099D9122CAA87D00CD4523 /* Params.cpp */,
|
||||
35099D9222CAA87D00CD4523 /* Params.h */,
|
||||
35099D9422CAB0A400CD4523 /* GuiConstants.h */,
|
||||
35099D9522CAB7CD00CD4523 /* SlidersFragment.h */,
|
||||
);
|
||||
name = Source;
|
||||
sourceTree = "<group>";
|
||||
|
@ -951,6 +962,7 @@
|
|||
7DF73014FFCCE46E228216DB /* PluginEditor.cpp in Sources */,
|
||||
E08B3A2AF85F9FCF991F1CA2 /* include_juce_audio_basics.mm in Sources */,
|
||||
C4D76C968347E2ACBAB5B6E7 /* include_juce_audio_devices.mm in Sources */,
|
||||
35099D9322CAA87D00CD4523 /* Params.cpp in Sources */,
|
||||
51C9DBCA840E334DB1804133 /* include_juce_audio_formats.mm in Sources */,
|
||||
358E45FB22C80DCA0087ED8D /* SlidersComponent.cpp in Sources */,
|
||||
5E5B833BBDD65F0D4271CA52 /* include_juce_audio_plugin_client_utils.cpp in Sources */,
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "FilePickerFragment.h"
|
||||
#include "SlidersFragment.h"
|
||||
|
||||
class ExposesComponents {
|
||||
public:
|
||||
virtual ~ExposesComponents() {}
|
||||
|
||||
virtual FilePickerFragment& getFilePicker() = 0;
|
||||
virtual SlidersFragment& getSliders() = 0;
|
||||
|
||||
};
|
|
@ -8,15 +8,15 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
FluidSynthModel::FluidSynthModel(SharesParams& p)
|
||||
: sharesParams(p),
|
||||
synth(nullptr),
|
||||
settings(nullptr),
|
||||
currentSoundFontAbsPath(),
|
||||
currentSampleRate(44100),
|
||||
initialised(false),
|
||||
sfont_id(0),
|
||||
channel(0)/*,
|
||||
FluidSynthModel::FluidSynthModel(shared_ptr<SharesParams> sharedParams)
|
||||
: sharedParams{sharedParams},
|
||||
synth{nullptr},
|
||||
settings{nullptr},
|
||||
currentSoundFontAbsPath{},
|
||||
currentSampleRate{44100},
|
||||
initialised{false},
|
||||
sfont_id{0},
|
||||
channel{0}/*,
|
||||
mod(nullptr)*/
|
||||
|
||||
{}
|
||||
|
@ -51,9 +51,9 @@ void FluidSynthModel::initialise() {
|
|||
synth = new_fluid_synth(settings);
|
||||
fluid_synth_set_sample_rate(synth, currentSampleRate);
|
||||
|
||||
if (sharesParams.getSoundFontPath().isNotEmpty()) {
|
||||
loadFont(sharesParams.getSoundFontPath());
|
||||
changePreset(sharesParams.getBank(), sharesParams.getPreset());
|
||||
if (sharedParams->getSoundFontPath().isNotEmpty()) {
|
||||
loadFont(sharedParams->getSoundFontPath());
|
||||
changePreset(sharedParams->getBank(), sharedParams->getPreset());
|
||||
}
|
||||
|
||||
fluid_synth_set_gain(synth, 2.0);
|
||||
|
@ -189,8 +189,8 @@ void FluidSynthModel::changePreset(int bank, int preset) {
|
|||
preset = bankAndPreset->getPreset();
|
||||
}
|
||||
changePresetImpl(bank, preset);
|
||||
sharesParams.setPreset(preset);
|
||||
sharesParams.setBank(bank);
|
||||
sharedParams->setPreset(preset);
|
||||
sharedParams->setBank(bank);
|
||||
}
|
||||
|
||||
void FluidSynthModel::changePresetImpl(int bank, int preset) {
|
||||
|
@ -272,7 +272,7 @@ void FluidSynthModel::onFileNameChanged(const String &absPath, int bank, int pre
|
|||
}
|
||||
unloadAndLoadFont(absPath);
|
||||
changePreset(bank, preset);
|
||||
sharesParams.setSoundFontPath(absPath);
|
||||
sharedParams->setSoundFontPath(absPath);
|
||||
eventListeners.call(&FluidSynthModel::Listener::fontChanged, this, absPath);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ using namespace std;
|
|||
|
||||
class FluidSynthModel {
|
||||
public:
|
||||
FluidSynthModel(SharesParams& p);
|
||||
FluidSynthModel(shared_ptr<SharesParams> sharedParams);
|
||||
~FluidSynthModel();
|
||||
|
||||
fluid_synth_t* getSynth();
|
||||
|
@ -65,7 +65,7 @@ public:
|
|||
const String& getCurrentSoundFontAbsPath();
|
||||
|
||||
private:
|
||||
SharesParams& sharesParams;
|
||||
shared_ptr<SharesParams> sharedParams;
|
||||
|
||||
fluid_synth_t* synth;
|
||||
fluid_settings_t* settings;
|
||||
|
|
8
Source/GuiConstants.h
Normal file
8
Source/GuiConstants.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
struct GuiConstants {
|
||||
inline static const int minWidth = 500;
|
||||
inline static const int maxWidth = 1900;
|
||||
inline static const int minHeight = 300;
|
||||
inline static const int maxHeight = 1000;
|
||||
};
|
|
@ -162,3 +162,8 @@ enum fluid_midi_control_change
|
|||
- for case (2) or (3), FLUID_NOISE_FLOOR should be the noise floor for 16 bits (i.e -90 dB).
|
||||
*/
|
||||
#define FLUID_PEAK_ATTENUATION 960.0f
|
||||
|
||||
struct MidiConstants {
|
||||
inline static const int midiMinValue = 0;
|
||||
inline static const int midiMaxValue = 127;
|
||||
};
|
||||
|
|
152
Source/Params.cpp
Normal file
152
Source/Params.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
//
|
||||
// Params.cpp
|
||||
// juicysfplugin - Shared Code
|
||||
//
|
||||
// Created by Alex Birch on 01/07/2019.
|
||||
// Copyright © 2019 Birchlabs. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Params.h"
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "MidiConstants.h"
|
||||
#include "GuiConstants.h"
|
||||
#include "SharesParams.h"
|
||||
|
||||
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}
|
||||
{
|
||||
}
|
||||
|
||||
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::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);
|
||||
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);
|
||||
}
|
||||
|
||||
void Params::acceptMidiControlEvent(int controller, int value) {
|
||||
switch(static_cast<fluid_midi_control_change>(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;
|
||||
}
|
||||
|
||||
String& Params::getSoundFontPath() {
|
||||
return soundFontPath;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
59
Source/Params.h
Normal file
59
Source/Params.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
|
||||
#include "SharesParams.h"
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Params: public SharesParams {
|
||||
public:
|
||||
Params() noexcept;
|
||||
|
||||
virtual void setAttributesOnXml(XmlElement& xml) override;
|
||||
virtual void loadAttributesFromXml(shared_ptr<XmlElement> xmlState) 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 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 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 attack;
|
||||
int decay;
|
||||
int sustain;
|
||||
int release;
|
||||
|
||||
int filterCutOff;
|
||||
int filterResonance;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Params)
|
||||
};
|
|
@ -10,20 +10,26 @@
|
|||
|
||||
#include "PluginProcessor.h"
|
||||
#include "PluginEditor.h"
|
||||
#include "GuiConstants.h"
|
||||
|
||||
//==============================================================================
|
||||
JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor (JuicySFAudioProcessor& p)
|
||||
: AudioProcessorEditor (&p),
|
||||
processor (p),
|
||||
midiKeyboard (p.keyboardState, SurjectiveMidiKeyboardComponent::horizontalKeyboard),
|
||||
tablesComponent(p.getFluidSynthModel()),
|
||||
filePicker(p.getFluidSynthModel()),
|
||||
slidersComponent{p.getFluidSynthModel()}
|
||||
JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor(JuicySFAudioProcessor& p)
|
||||
: AudioProcessorEditor{&p},
|
||||
processor{p},
|
||||
sharedParams{p.sharedParams},
|
||||
midiKeyboard{p.keyboardState, SurjectiveMidiKeyboardComponent::horizontalKeyboard},
|
||||
tablesComponent{p.getFluidSynthModel()},
|
||||
filePicker{p.getFluidSynthModel()},
|
||||
slidersComponent{p.sharedParams, p.getFluidSynthModel()}
|
||||
{
|
||||
// set resize limits for this plug-in
|
||||
setResizeLimits (500, 300, 1900, 1000);
|
||||
setResizeLimits(
|
||||
GuiConstants::minWidth,
|
||||
GuiConstants::minHeight,
|
||||
GuiConstants::maxWidth,
|
||||
GuiConstants::maxHeight);
|
||||
|
||||
setSize (p.lastUIWidth, p.lastUIHeight);
|
||||
setSize(sharedParams->getUiWidth(), sharedParams->getUiHeight());
|
||||
|
||||
// processor.subscribeToStateChanges(this);
|
||||
|
||||
|
@ -97,9 +103,8 @@ void JuicySFAudioProcessorEditor::resized()
|
|||
|
||||
tablesComponent.setBounds(rContent);
|
||||
|
||||
|
||||
processor.lastUIWidth = getWidth();
|
||||
processor.lastUIHeight = getHeight();
|
||||
sharedParams->setUiWidth(getWidth());
|
||||
sharedParams->setUiHeight(getHeight());
|
||||
|
||||
// Rectangle<int> r2 (getLocalBounds());
|
||||
// r2.reduce(0, padding);
|
||||
|
@ -151,3 +156,7 @@ bool JuicySFAudioProcessorEditor::keyStateChanged (bool isKeyDown) {
|
|||
FilePickerFragment& JuicySFAudioProcessorEditor::getFilePicker() {
|
||||
return filePicker;
|
||||
}
|
||||
|
||||
SlidersFragment& JuicySFAudioProcessorEditor::getSliders() {
|
||||
return slidersComponent;
|
||||
}
|
|
@ -42,12 +42,15 @@ public:
|
|||
// void setStateInformation (XmlElement* xmlState) override;
|
||||
|
||||
virtual FilePickerFragment& getFilePicker() override;
|
||||
virtual SlidersFragment& getSliders() override;
|
||||
|
||||
private:
|
||||
// This reference is provided as a quick way for your editor to
|
||||
// access the processor object that created it.
|
||||
JuicySFAudioProcessor& processor;
|
||||
|
||||
shared_ptr<SharesParams> sharedParams;
|
||||
|
||||
SurjectiveMidiKeyboardComponent midiKeyboard;
|
||||
TablesComponent tablesComponent;
|
||||
FilePicker filePicker;
|
||||
|
|
|
@ -15,19 +15,20 @@
|
|||
#include "ExposesComponents.h"
|
||||
#include "MidiConstants.h"
|
||||
#include "Util.h"
|
||||
#include "SharesParams.h"
|
||||
#include "Params.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
AudioProcessor* JUCE_CALLTYPE createPluginFilter();
|
||||
|
||||
|
||||
//==============================================================================
|
||||
JuicySFAudioProcessor::JuicySFAudioProcessor()
|
||||
: AudioProcessor (getBusesProperties()),
|
||||
lastUIWidth(400),
|
||||
lastUIHeight(300),
|
||||
soundFontPath(String()),
|
||||
lastPreset(-1),
|
||||
lastBank(-1),
|
||||
fluidSynthModel(*this)/*,
|
||||
: AudioProcessor{getBusesProperties()},
|
||||
sharedParams{static_pointer_cast<SharesParams>(make_shared<Params>())},
|
||||
fluidSynthModel{sharedParams}/*,
|
||||
fluidSynthModel{*this},
|
||||
pluginEditor(nullptr)*/
|
||||
{
|
||||
initialiseSynth();
|
||||
|
@ -47,10 +48,10 @@ void JuicySFAudioProcessor::initialiseSynth() {
|
|||
|
||||
// Add some voices...
|
||||
for (int i = numVoices; --i >= 0;)
|
||||
synth.addVoice (new SoundfontSynthVoice(fluidSynthModel.getSynth()));
|
||||
synth.addVoice(new SoundfontSynthVoice(fluidSynthModel.getSynth()));
|
||||
|
||||
// ..and give the synth a sound to play
|
||||
synth.addSound (new SoundfontSynthSound());
|
||||
synth.addSound(new SoundfontSynthSound());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
@ -168,6 +169,11 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
|
|||
// responsibilities of SoundfontSynthVoice.
|
||||
// well, by that logic maybe I should move program change onto Voice. but it doesn't feel like a per-voice concern.
|
||||
if (m.isController()) {
|
||||
// shared_ptr<fluid_midi_event_t> midi_event{
|
||||
// new_fluid_midi_event(),
|
||||
// [](fluid_midi_event_t *event) {
|
||||
// delete_fluid_midi_event(midi_event);
|
||||
// }};
|
||||
fluid_midi_event_t *midi_event(new_fluid_midi_event());
|
||||
fluid_midi_event_set_type(midi_event, static_cast<int>(CONTROL_CHANGE));
|
||||
fluid_midi_event_set_channel(midi_event, fluidSynthModel.getChannel());
|
||||
|
@ -175,6 +181,13 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
|
|||
fluid_midi_event_set_value(midi_event, m.getControllerValue());
|
||||
fluid_synth_handle_midi_event(fluidSynth, midi_event);
|
||||
delete_fluid_midi_event(midi_event);
|
||||
|
||||
sharedParams->acceptMidiControlEvent(m.getControllerNumber(), m.getControllerValue());
|
||||
|
||||
AudioProcessorEditor* editor{getActiveEditor()};
|
||||
jassert(dynamic_cast<ExposesComponents*> (editor) != nullptr);
|
||||
ExposesComponents* exposesComponents{dynamic_cast<ExposesComponents*>(editor)};
|
||||
exposesComponents->getSliders().acceptMidiControlEvent(m.getControllerNumber(), m.getControllerValue());
|
||||
} else if (m.isProgramChange()) {
|
||||
fluid_midi_event_t *midi_event(new_fluid_midi_event());
|
||||
fluid_midi_event_set_type(midi_event, static_cast<int>(PROGRAM_CHANGE));
|
||||
|
@ -266,14 +279,8 @@ 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");
|
||||
|
||||
// add some attributes to it..
|
||||
xml.setAttribute ("uiWidth", lastUIWidth);
|
||||
xml.setAttribute ("uiHeight", lastUIHeight);
|
||||
xml.setAttribute ("soundFontPath", soundFontPath);
|
||||
xml.setAttribute ("preset", lastPreset);
|
||||
xml.setAttribute ("bank", lastBank);
|
||||
XmlElement xml{"MYPLUGINSETTINGS"};
|
||||
sharedParams->setAttributesOnXml(xml);
|
||||
|
||||
// list<StateChangeSubscriber*>::iterator p;
|
||||
// for(p = stateChangeSubscribers.begin(); p != stateChangeSubscribers.end(); p++) {
|
||||
|
@ -294,7 +301,7 @@ void JuicySFAudioProcessor::setStateInformation (const void* data, int sizeInByt
|
|||
// You should use this method to restore your parameters from this memory block,
|
||||
// whose contents will have been created by the getStateInformation() call.
|
||||
// This getXmlFromBinary() helper function retrieves our XML from the binary blob..
|
||||
ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
|
||||
shared_ptr<XmlElement> xmlState{getXmlFromBinary(data, sizeInBytes)};
|
||||
|
||||
if (xmlState != nullptr)
|
||||
{
|
||||
|
@ -307,26 +314,27 @@ void JuicySFAudioProcessor::setStateInformation (const void* data, int sizeInByt
|
|||
// }
|
||||
|
||||
// ok, now pull out our last window size..
|
||||
lastUIWidth = jmax (xmlState->getIntAttribute ("uiWidth", lastUIWidth), 400);
|
||||
lastUIHeight = jmax (xmlState->getIntAttribute ("uiHeight", lastUIHeight), 300);
|
||||
soundFontPath = xmlState->getStringAttribute ("soundFontPath", soundFontPath);
|
||||
lastPreset = xmlState->getIntAttribute ("preset", lastPreset);
|
||||
lastBank = xmlState->getIntAttribute ("bank", lastBank);
|
||||
sharedParams->loadAttributesFromXml(xmlState);
|
||||
|
||||
// Now reload our parameters..
|
||||
for (auto* param : getParameters())
|
||||
if (auto* p = dynamic_cast<AudioProcessorParameterWithID*> (param))
|
||||
p->setValue ((float) xmlState->getDoubleAttribute (p->paramID, p->getValue()));
|
||||
|
||||
fluidSynthModel.onFileNameChanged(soundFontPath, lastBank, lastPreset);
|
||||
fluidSynthModel.onFileNameChanged(
|
||||
sharedParams->getSoundFontPath(),
|
||||
sharedParams->getBank(),
|
||||
sharedParams->getPreset());
|
||||
|
||||
AudioProcessorEditor* editor = getActiveEditor();
|
||||
AudioProcessorEditor* editor{getActiveEditor()};
|
||||
if (editor != nullptr) {
|
||||
editor->setSize(lastUIWidth, lastUIHeight);
|
||||
editor->setSize(
|
||||
sharedParams->getUiWidth(),
|
||||
sharedParams->getUiHeight());
|
||||
|
||||
jassert(dynamic_cast<ExposesComponents*> (editor) != nullptr);
|
||||
ExposesComponents* exposesComponents = dynamic_cast<ExposesComponents*> (editor);
|
||||
exposesComponents->getFilePicker().setDisplayedFilePath(soundFontPath);
|
||||
exposesComponents->getFilePicker().setDisplayedFilePath(sharedParams->getSoundFontPath());
|
||||
}
|
||||
|
||||
// const String& currentSoundFontAbsPath = fluidSynthModel->getCurrentSoundFontAbsPath();
|
||||
|
@ -354,26 +362,6 @@ FluidSynthModel* JuicySFAudioProcessor::getFluidSynthModel() {
|
|||
return &fluidSynthModel;
|
||||
}
|
||||
|
||||
void JuicySFAudioProcessor::setSoundFontPath(const String& value) {
|
||||
soundFontPath = value;
|
||||
}
|
||||
|
||||
String& JuicySFAudioProcessor::getSoundFontPath() {
|
||||
return soundFontPath;
|
||||
}
|
||||
int JuicySFAudioProcessor::getPreset() {
|
||||
return lastPreset;
|
||||
}
|
||||
int JuicySFAudioProcessor::getBank() {
|
||||
return lastBank;
|
||||
}
|
||||
void JuicySFAudioProcessor::setPreset(int preset) {
|
||||
lastPreset = preset;
|
||||
}
|
||||
void JuicySFAudioProcessor::setBank(int bank) {
|
||||
lastBank = bank;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// This creates new instances of the plugin..
|
||||
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
|
||||
|
|
|
@ -21,8 +21,7 @@ using namespace std;
|
|||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
class JuicySFAudioProcessor : public AudioProcessor,
|
||||
public SharesParams
|
||||
class JuicySFAudioProcessor : public AudioProcessor
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
|
@ -67,25 +66,14 @@ public:
|
|||
|
||||
MidiKeyboardState keyboardState;
|
||||
|
||||
virtual void setSoundFontPath(const String& value) override;
|
||||
virtual String& getSoundFontPath() override;
|
||||
virtual int getPreset() override;
|
||||
virtual void setPreset(int preset) override;
|
||||
virtual int getBank() override;
|
||||
virtual void setBank(int bank) override;
|
||||
shared_ptr<SharesParams> sharedParams;
|
||||
|
||||
// void subscribeToStateChanges(StateChangeSubscriber* subscriber);
|
||||
// void unsubscribeFromStateChanges(StateChangeSubscriber* subscriber);
|
||||
|
||||
int lastUIWidth, lastUIHeight;
|
||||
|
||||
private:
|
||||
void initialiseSynth();
|
||||
|
||||
String soundFontPath;
|
||||
int lastPreset;
|
||||
int lastBank;
|
||||
|
||||
FluidSynthModel fluidSynthModel;
|
||||
fluid_synth_t* fluidSynth;
|
||||
Synthesiser synth;
|
||||
|
|
|
@ -7,16 +7,42 @@
|
|||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class SharesParams {
|
||||
public:
|
||||
virtual ~SharesParams() {}
|
||||
|
||||
virtual void setAttributesOnXml(XmlElement& xml) = 0;
|
||||
virtual void loadAttributesFromXml(shared_ptr<XmlElement> xmlState) = 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 preset) = 0;
|
||||
virtual void setPreset(int value) = 0;
|
||||
virtual int getBank() = 0;
|
||||
virtual void setBank(int bank) = 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 getFilterCutOff() = 0;
|
||||
virtual void setFilterCutOff(int value) = 0;
|
||||
virtual int getFilterResonance() = 0;
|
||||
virtual void setFilterResonance(int value) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -10,10 +10,11 @@
|
|||
#include "FluidSynthModel.h"
|
||||
#include "MidiConstants.h"
|
||||
|
||||
std::function<void()> SlidersComponent::makeSliderListener(Slider& slider, int controller) {
|
||||
std::function<void()> SlidersComponent::makeSliderListener(Slider& slider, int controller/*, std::function<void()> callback*/) {
|
||||
return [this, controller, &slider]{
|
||||
// slider.setValue(slider.getValue(), NotificationType::dontSendNotification);
|
||||
fluidSynthModel->setControllerValue(controller, slider.getValue());
|
||||
// callback();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -58,7 +59,54 @@ void SlidersComponent::resized() {
|
|||
filterResonanceSlider.setBounds(rFilter.removeFromLeft(sliderWidth + sliderXMargin).withTrimmedTop(labelHeight).withTrimmedLeft(sliderXMargin));
|
||||
}
|
||||
|
||||
SlidersComponent::SlidersComponent(FluidSynthModel* fluidSynthModel) :
|
||||
void SlidersComponent::acceptMidiControlEvent(int controller, int value) {
|
||||
switch(static_cast<fluid_midi_control_change>(controller)) {
|
||||
case SOUND_CTRL2: // MIDI CC 71 Timbre/Harmonic Intensity (filter resonance)
|
||||
filterResonanceSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
break;
|
||||
case SOUND_CTRL3: // MIDI CC 72 Release time
|
||||
releaseSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
break;
|
||||
case SOUND_CTRL4: // MIDI CC 73 Attack time
|
||||
attackSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
break;
|
||||
case SOUND_CTRL5: // MIDI CC 74 Brightness (cutoff frequency, FILTERFC)
|
||||
filterCutOffSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
break;
|
||||
case SOUND_CTRL6: // MIDI CC 75 Decay Time
|
||||
decaySlider.setValue(value, NotificationType::dontSendNotification);
|
||||
break;
|
||||
case SOUND_CTRL10: // MIDI CC 79 undefined
|
||||
sustainSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// void SlidersComponent::updateAttackSlider(int value) {
|
||||
// attackSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
// }
|
||||
// void SlidersComponent::updateDecaySlider(int value) {
|
||||
// decaySlider.setValue(value, NotificationType::dontSendNotification);
|
||||
// }
|
||||
// void SlidersComponent::updateSustainSlider(int value) {
|
||||
// sustainSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
// }
|
||||
// void SlidersComponent::updateReleaseSlider(int value) {
|
||||
// releaseSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
// }
|
||||
// void SlidersComponent::updateFilterCutOffSlider(int value) {
|
||||
// filterCutOffSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
// }
|
||||
// void SlidersComponent::updateFilterResonanceSlider(int value) {
|
||||
// filterResonanceSlider.setValue(value, NotificationType::dontSendNotification);
|
||||
// }
|
||||
|
||||
SlidersComponent::SlidersComponent(
|
||||
shared_ptr<SharesParams> sharedParams,
|
||||
FluidSynthModel* fluidSynthModel) :
|
||||
sharedParams{sharedParams},
|
||||
fluidSynthModel{fluidSynthModel},
|
||||
envelopeGroup{"envelopeGroup", "Envelope"},
|
||||
filterGroup{"filterGroup", "Filter"}
|
||||
|
|
|
@ -2,22 +2,38 @@
|
|||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "FluidSynthModel.h"
|
||||
#include "SharesParams.h"
|
||||
#include "SlidersFragment.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class SlidersComponent : public Component
|
||||
class SlidersComponent : public Component,
|
||||
public SlidersFragment
|
||||
{
|
||||
public:
|
||||
SlidersComponent(FluidSynthModel* fluidSynthModel);
|
||||
SlidersComponent(
|
||||
shared_ptr<SharesParams> sharedParams,
|
||||
FluidSynthModel* fluidSynthModel);
|
||||
~SlidersComponent();
|
||||
|
||||
void resized() override;
|
||||
|
||||
const int getDesiredWidth();
|
||||
|
||||
virtual void acceptMidiControlEvent(int controller, int value) override;
|
||||
|
||||
// virtual void updateAttackSlider(int value) override;
|
||||
// virtual void updateDecaySlider(int value) override;
|
||||
// virtual void updateSustainSlider(int value) override;
|
||||
// virtual void updateReleaseSlider(int value) override;
|
||||
|
||||
// virtual void updateFilterCutOffSlider(int value) override;
|
||||
// virtual void updateFilterResonanceSlider(int value) override;
|
||||
|
||||
private:
|
||||
std::function<void()> makeSliderListener(Slider& slider, int controller);
|
||||
|
||||
shared_ptr<SharesParams> sharedParams;
|
||||
FluidSynthModel* fluidSynthModel;
|
||||
|
||||
GroupComponent envelopeGroup;
|
||||
|
|
18
Source/SlidersFragment.h
Normal file
18
Source/SlidersFragment.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
|
||||
class SlidersFragment {
|
||||
public:
|
||||
virtual ~SlidersFragment() {}
|
||||
|
||||
virtual void acceptMidiControlEvent(int controller, int value) = 0;
|
||||
|
||||
// virtual void updateAttackSlider(int value) = 0;
|
||||
// virtual void updateDecaySlider(int value) = 0;
|
||||
// virtual void updateSustainSlider(int value) = 0;
|
||||
// virtual void updateReleaseSlider(int value) = 0;
|
||||
|
||||
// virtual void updateFilterCutOffSlider(int value) = 0;
|
||||
// virtual void updateFilterResonanceSlider(int value) = 0;
|
||||
};
|
Loading…
Reference in New Issue
Block a user