commit
395e78ba23
|
@ -107,6 +107,7 @@
|
||||||
358E45F122BEE5CE0087ED8D /* libgthread-2.0.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 358E45BB22BEE53A0087ED8D /* libgthread-2.0.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
358E45F122BEE5CE0087ED8D /* libgthread-2.0.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 358E45BB22BEE53A0087ED8D /* libgthread-2.0.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
358E45F222BEE5CE0087ED8D /* libFLAC.8.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 358E45BC22BEE53A0087ED8D /* libFLAC.8.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
358E45F222BEE5CE0087ED8D /* libFLAC.8.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 358E45BC22BEE53A0087ED8D /* libFLAC.8.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
358E45F322BEE5CE0087ED8D /* libogg.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 358E45BD22BEE53A0087ED8D /* libogg.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
358E45F322BEE5CE0087ED8D /* libogg.0.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 358E45BD22BEE53A0087ED8D /* libogg.0.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
|
358E45FB22C80DCA0087ED8D /* SlidersComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 358E45F922C80DCA0087ED8D /* SlidersComponent.cpp */; };
|
||||||
3793A7D5AC25576FAC8583E6 /* include_juce_graphics.mm in Sources */ = {isa = PBXBuildFile; fileRef = A6BC2528C1717DDC2B66215E /* include_juce_graphics.mm */; };
|
3793A7D5AC25576FAC8583E6 /* include_juce_graphics.mm in Sources */ = {isa = PBXBuildFile; fileRef = A6BC2528C1717DDC2B66215E /* include_juce_graphics.mm */; };
|
||||||
42542EDC02B3DE845BCC21FE /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1616112041466F7324D7E19 /* Accelerate.framework */; };
|
42542EDC02B3DE845BCC21FE /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1616112041466F7324D7E19 /* Accelerate.framework */; };
|
||||||
458D25AB7460484F90B37A2F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1910B48593DA5FACC7E122 /* IOKit.framework */; };
|
458D25AB7460484F90B37A2F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1910B48593DA5FACC7E122 /* IOKit.framework */; };
|
||||||
|
@ -295,6 +296,8 @@
|
||||||
358E45BC22BEE53A0087ED8D /* libFLAC.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libFLAC.8.dylib; sourceTree = "<group>"; };
|
358E45BC22BEE53A0087ED8D /* libFLAC.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libFLAC.8.dylib; sourceTree = "<group>"; };
|
||||||
358E45BD22BEE53A0087ED8D /* libogg.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libogg.0.dylib; sourceTree = "<group>"; };
|
358E45BD22BEE53A0087ED8D /* libogg.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libogg.0.dylib; sourceTree = "<group>"; };
|
||||||
358E45F422BFC00C0087ED8D /* MidiConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MidiConstants.h; path = ../../Source/MidiConstants.h; sourceTree = "<group>"; };
|
358E45F422BFC00C0087ED8D /* MidiConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MidiConstants.h; path = ../../Source/MidiConstants.h; sourceTree = "<group>"; };
|
||||||
|
358E45F922C80DCA0087ED8D /* SlidersComponent.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SlidersComponent.cpp; path = ../../Source/SlidersComponent.cpp; sourceTree = "<group>"; };
|
||||||
|
358E45FA22C80DCA0087ED8D /* SlidersComponent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SlidersComponent.h; path = ../../Source/SlidersComponent.h; sourceTree = "<group>"; };
|
||||||
35D551D55292C9D0508A408A /* PluginEditor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PluginEditor.cpp; path = ../../Source/PluginEditor.cpp; sourceTree = SOURCE_ROOT; };
|
35D551D55292C9D0508A408A /* PluginEditor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PluginEditor.cpp; path = ../../Source/PluginEditor.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
373EF982A53046CE00BECE68 /* include_juce_events.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_events.mm; path = ../../JuceLibraryCode/include_juce_events.mm; sourceTree = SOURCE_ROOT; };
|
373EF982A53046CE00BECE68 /* include_juce_events.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = include_juce_events.mm; path = ../../JuceLibraryCode/include_juce_events.mm; sourceTree = SOURCE_ROOT; };
|
||||||
3909EE4609ED2DCCC6B6B290 /* juce_data_structures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_data_structures; path = /Applications/JUCE/modules/juce_data_structures; sourceTree = "<absolute>"; };
|
3909EE4609ED2DCCC6B6B290 /* juce_data_structures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_data_structures; path = /Applications/JUCE/modules/juce_data_structures; sourceTree = "<absolute>"; };
|
||||||
|
@ -547,6 +550,8 @@
|
||||||
35D551D55292C9D0508A408A /* PluginEditor.cpp */,
|
35D551D55292C9D0508A408A /* PluginEditor.cpp */,
|
||||||
8990F3EAFFBBD6A42247C663 /* PluginEditor.h */,
|
8990F3EAFFBBD6A42247C663 /* PluginEditor.h */,
|
||||||
358E45F422BFC00C0087ED8D /* MidiConstants.h */,
|
358E45F422BFC00C0087ED8D /* MidiConstants.h */,
|
||||||
|
358E45F922C80DCA0087ED8D /* SlidersComponent.cpp */,
|
||||||
|
358E45FA22C80DCA0087ED8D /* SlidersComponent.h */,
|
||||||
);
|
);
|
||||||
name = Source;
|
name = Source;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -945,6 +950,7 @@
|
||||||
E08B3A2AF85F9FCF991F1CA2 /* include_juce_audio_basics.mm in Sources */,
|
E08B3A2AF85F9FCF991F1CA2 /* include_juce_audio_basics.mm in Sources */,
|
||||||
C4D76C968347E2ACBAB5B6E7 /* include_juce_audio_devices.mm in Sources */,
|
C4D76C968347E2ACBAB5B6E7 /* include_juce_audio_devices.mm in Sources */,
|
||||||
51C9DBCA840E334DB1804133 /* include_juce_audio_formats.mm 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 */,
|
5E5B833BBDD65F0D4271CA52 /* include_juce_audio_plugin_client_utils.cpp in Sources */,
|
||||||
C59AF9E198C59F67039F12BB /* include_juce_audio_plugin_client_VST_utils.mm in Sources */,
|
C59AF9E198C59F67039F12BB /* include_juce_audio_plugin_client_VST_utils.mm in Sources */,
|
||||||
5BEE82A710A5F9566FCF4FDA /* include_juce_audio_processors.mm in Sources */,
|
5BEE82A710A5F9566FCF4FDA /* include_juce_audio_processors.mm in Sources */,
|
||||||
|
|
|
@ -55,6 +55,11 @@ void FluidSynthModel::initialise() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fluid_synth_set_gain(synth, 2.0);
|
fluid_synth_set_gain(synth, 2.0);
|
||||||
|
|
||||||
|
for(int i{SOUND_CTRL1}; i <= SOUND_CTRL10; i++)
|
||||||
|
{
|
||||||
|
setControllerValue(i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// fluid_synth_bank_select(synth, 0, 3);
|
// fluid_synth_bank_select(synth, 0, 3);
|
||||||
|
|
||||||
|
@ -68,9 +73,14 @@ void FluidSynthModel::initialise() {
|
||||||
|
|
||||||
// http://www.synthfont.com/SoundFont_NRPNs.PDF
|
// http://www.synthfont.com/SoundFont_NRPNs.PDF
|
||||||
float env_amount(20000.0f);
|
float env_amount(20000.0f);
|
||||||
|
// float env_amount(24000.0f);
|
||||||
|
|
||||||
|
// note: fluid_chan.c#fluid_channel_init_ctrl()
|
||||||
|
// all SOUND_CTRL are inited with value of 64, not zero.
|
||||||
|
// "Just like panning, a value of 64 indicates no change for sound ctrls"
|
||||||
|
|
||||||
fluid_mod_t *mod(new_fluid_mod());
|
fluid_mod_t *mod(new_fluid_mod());
|
||||||
|
//
|
||||||
fluid_mod_set_source1(mod,
|
fluid_mod_set_source1(mod,
|
||||||
static_cast<int>(SOUND_CTRL2), // MIDI CC 71 Timbre/Harmonic Intensity (filter resonance)
|
static_cast<int>(SOUND_CTRL2), // MIDI CC 71 Timbre/Harmonic Intensity (filter resonance)
|
||||||
FLUID_MOD_CC
|
FLUID_MOD_CC
|
||||||
|
@ -92,6 +102,7 @@ void FluidSynthModel::initialise() {
|
||||||
| FLUID_MOD_POSITIVE);
|
| FLUID_MOD_POSITIVE);
|
||||||
fluid_mod_set_source2(mod, 0, 0);
|
fluid_mod_set_source2(mod, 0, 0);
|
||||||
fluid_mod_set_dest(mod, GEN_VOLENVRELEASE);
|
fluid_mod_set_dest(mod, GEN_VOLENVRELEASE);
|
||||||
|
// fluid_mod_set_amount(mod, 15200.0f);
|
||||||
fluid_mod_set_amount(mod, env_amount);
|
fluid_mod_set_amount(mod, env_amount);
|
||||||
fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD);
|
fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD);
|
||||||
delete_fluid_mod(mod);
|
delete_fluid_mod(mod);
|
||||||
|
@ -109,6 +120,7 @@ void FluidSynthModel::initialise() {
|
||||||
fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD);
|
fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD);
|
||||||
delete_fluid_mod(mod);
|
delete_fluid_mod(mod);
|
||||||
|
|
||||||
|
// soundfont spec says that if cutoff is >20kHz and resonance Q is 0, then no filtering occurs
|
||||||
mod = new_fluid_mod();
|
mod = new_fluid_mod();
|
||||||
fluid_mod_set_source1(mod,
|
fluid_mod_set_source1(mod,
|
||||||
static_cast<int>(SOUND_CTRL5), // MIDI CC 74 Brightness (cutoff frequency, FILTERFC)
|
static_cast<int>(SOUND_CTRL5), // MIDI CC 74 Brightness (cutoff frequency, FILTERFC)
|
||||||
|
@ -134,10 +146,36 @@ void FluidSynthModel::initialise() {
|
||||||
fluid_mod_set_amount(mod, env_amount);
|
fluid_mod_set_amount(mod, env_amount);
|
||||||
fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD);
|
fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD);
|
||||||
delete_fluid_mod(mod);
|
delete_fluid_mod(mod);
|
||||||
|
|
||||||
|
mod = new_fluid_mod();
|
||||||
|
fluid_mod_set_source1(mod,
|
||||||
|
static_cast<int>(SOUND_CTRL10), // MIDI CC 79 undefined
|
||||||
|
FLUID_MOD_CC
|
||||||
|
| FLUID_MOD_UNIPOLAR
|
||||||
|
| FLUID_MOD_CONCAVE
|
||||||
|
| FLUID_MOD_POSITIVE);
|
||||||
|
fluid_mod_set_source2(mod, 0, 0);
|
||||||
|
fluid_mod_set_dest(mod, GEN_VOLENVSUSTAIN);
|
||||||
|
// fluice_voice.c#fluid_voice_update_param()
|
||||||
|
// clamps the range to between 0 and 1000, so we'll copy that
|
||||||
|
fluid_mod_set_amount(mod, 1000.0f);
|
||||||
|
fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD);
|
||||||
|
delete_fluid_mod(mod);
|
||||||
|
|
||||||
initialised = true;
|
initialised = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
fluid_midi_event_set_channel(midi_event, channel);
|
||||||
|
fluid_midi_event_set_control(midi_event, controller);
|
||||||
|
fluid_midi_event_set_value(midi_event, value);
|
||||||
|
fluid_synth_handle_midi_event(synth, midi_event);
|
||||||
|
delete_fluid_midi_event(midi_event);
|
||||||
|
// fluid_channel_set_cc(channel, i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int FluidSynthModel::getChannel() {
|
int FluidSynthModel::getChannel() {
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
int getChannel();
|
int getChannel();
|
||||||
|
|
||||||
void onFileNameChanged(const String &absPath, int bank, int preset);
|
void onFileNameChanged(const String &absPath, int bank, int preset);
|
||||||
|
void setControllerValue(int controller, int value);
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -97,15 +97,15 @@ enum fluid_midi_control_change
|
||||||
LEGATO_SWITCH = 0x44,
|
LEGATO_SWITCH = 0x44,
|
||||||
HOLD2_SWITCH = 0x45,
|
HOLD2_SWITCH = 0x45,
|
||||||
SOUND_CTRL1 = 0x46,
|
SOUND_CTRL1 = 0x46,
|
||||||
SOUND_CTRL2 = 0x47,
|
SOUND_CTRL2 = 0x47, // MIDI CC 71 Timbre/Harmonic Intensity (filter resonance)
|
||||||
SOUND_CTRL3 = 0x48,
|
SOUND_CTRL3 = 0x48, // MIDI CC 72 Release time
|
||||||
SOUND_CTRL4 = 0x49,
|
SOUND_CTRL4 = 0x49, // MIDI CC 73 Attack time
|
||||||
SOUND_CTRL5 = 0x4A,
|
SOUND_CTRL5 = 0x4A, // MIDI CC 74 Brightness (cutoff frequency, FILTERFC)
|
||||||
SOUND_CTRL6 = 0x4B,
|
SOUND_CTRL6 = 0x4B, // MIDI CC 75 Decay Time
|
||||||
SOUND_CTRL7 = 0x4C,
|
SOUND_CTRL7 = 0x4C,
|
||||||
SOUND_CTRL8 = 0x4D,
|
SOUND_CTRL8 = 0x4D,
|
||||||
SOUND_CTRL9 = 0x4E,
|
SOUND_CTRL9 = 0x4E,
|
||||||
SOUND_CTRL10 = 0x4F,
|
SOUND_CTRL10 = 0x4F, // MIDI CC 79 undefined
|
||||||
GPC5 = 0x50,
|
GPC5 = 0x50,
|
||||||
GPC6 = 0x51,
|
GPC6 = 0x51,
|
||||||
GPC7 = 0x52,
|
GPC7 = 0x52,
|
||||||
|
|
|
@ -17,10 +17,11 @@ JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor (JuicySFAudioProcessor&
|
||||||
processor (p),
|
processor (p),
|
||||||
midiKeyboard (p.keyboardState, SurjectiveMidiKeyboardComponent::horizontalKeyboard),
|
midiKeyboard (p.keyboardState, SurjectiveMidiKeyboardComponent::horizontalKeyboard),
|
||||||
tablesComponent(p.getFluidSynthModel()),
|
tablesComponent(p.getFluidSynthModel()),
|
||||||
filePicker(p.getFluidSynthModel())
|
filePicker(p.getFluidSynthModel()),
|
||||||
|
slidersComponent{p.getFluidSynthModel()}
|
||||||
{
|
{
|
||||||
// set resize limits for this plug-in
|
// set resize limits for this plug-in
|
||||||
setResizeLimits (400, 300, 800, 600);
|
setResizeLimits (500, 300, 1900, 1000);
|
||||||
|
|
||||||
setSize (p.lastUIWidth, p.lastUIHeight);
|
setSize (p.lastUIWidth, p.lastUIHeight);
|
||||||
|
|
||||||
|
@ -34,8 +35,10 @@ JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor (JuicySFAudioProcessor&
|
||||||
setWantsKeyboardFocus(true);
|
setWantsKeyboardFocus(true);
|
||||||
addAndMakeVisible (midiKeyboard);
|
addAndMakeVisible (midiKeyboard);
|
||||||
|
|
||||||
|
addAndMakeVisible(slidersComponent);
|
||||||
addAndMakeVisible(tablesComponent);
|
addAndMakeVisible(tablesComponent);
|
||||||
addAndMakeVisible(filePicker);
|
addAndMakeVisible(filePicker);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JuicySFAudioProcessorEditor::~JuicySFAudioProcessorEditor()
|
JuicySFAudioProcessorEditor::~JuicySFAudioProcessorEditor()
|
||||||
|
@ -77,13 +80,23 @@ void JuicySFAudioProcessorEditor::paint (Graphics& g)
|
||||||
|
|
||||||
void JuicySFAudioProcessorEditor::resized()
|
void JuicySFAudioProcessorEditor::resized()
|
||||||
{
|
{
|
||||||
const int padding = 8;
|
const int padding{8};
|
||||||
const int pianoHeight = 70;
|
const int pianoHeight{70};
|
||||||
const int filePickerHeight = 25;
|
const int filePickerHeight{25};
|
||||||
Rectangle<int> r (getLocalBounds());
|
// const int slidersHeight{150};
|
||||||
|
Rectangle<int> r{getLocalBounds()};
|
||||||
filePicker.setBounds(r.removeFromTop(filePickerHeight + padding).reduced(padding, 0).withTrimmedTop(padding));
|
filePicker.setBounds(r.removeFromTop(filePickerHeight + padding).reduced(padding, 0).withTrimmedTop(padding));
|
||||||
|
|
||||||
|
// Rectangle<int> r2 (getLocalBounds());
|
||||||
|
// slidersComponent.setBounds(r2.removeFromLeft(filePickerWidth + padding).reduced(padding, 0).withTrimmedLeft(padding));
|
||||||
|
|
||||||
midiKeyboard.setBounds (r.removeFromBottom (pianoHeight).reduced(padding, 0));
|
midiKeyboard.setBounds (r.removeFromBottom (pianoHeight).reduced(padding, 0));
|
||||||
tablesComponent.setBounds(r.reduced(0, padding));
|
|
||||||
|
Rectangle<int> rContent{r.reduced(0, padding)};
|
||||||
|
slidersComponent.setBounds(rContent.removeFromRight(slidersComponent.getDesiredWidth() + padding).withTrimmedRight(padding));
|
||||||
|
|
||||||
|
tablesComponent.setBounds(rContent);
|
||||||
|
|
||||||
|
|
||||||
processor.lastUIWidth = getWidth();
|
processor.lastUIWidth = getWidth();
|
||||||
processor.lastUIHeight = getHeight();
|
processor.lastUIHeight = getHeight();
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "ExposesComponents.h"
|
#include "ExposesComponents.h"
|
||||||
#include "FilePicker.h"
|
#include "FilePicker.h"
|
||||||
#include "StateChangeSubscriber.h"
|
#include "StateChangeSubscriber.h"
|
||||||
|
#include "SlidersComponent.h"
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
/**
|
/**
|
||||||
|
@ -50,6 +51,7 @@ private:
|
||||||
SurjectiveMidiKeyboardComponent midiKeyboard;
|
SurjectiveMidiKeyboardComponent midiKeyboard;
|
||||||
TablesComponent tablesComponent;
|
TablesComponent tablesComponent;
|
||||||
FilePicker filePicker;
|
FilePicker filePicker;
|
||||||
|
SlidersComponent slidersComponent;
|
||||||
|
|
||||||
bool focusInitialized;
|
bool focusInitialized;
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,14 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
|
||||||
delete_fluid_midi_event(midi_event);
|
delete_fluid_midi_event(midi_event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int pval;
|
||||||
|
// 73: 64 attack
|
||||||
|
// 75: decay
|
||||||
|
// 79: sustain
|
||||||
|
// 72: 64 release
|
||||||
|
// fluid_synth_get_cc(fluidSynth, 0, 73, &pval);
|
||||||
|
// Logger::outputDebugString ( juce::String::formatted("hey: %d\n", pval) );
|
||||||
|
|
||||||
// and now get our synth to process these midi events and generate its output.
|
// and now get our synth to process these midi events and generate its output.
|
||||||
synth.renderNextBlock (buffer, midiMessages, 0, numSamples);
|
synth.renderNextBlock (buffer, midiMessages, 0, numSamples);
|
||||||
|
|
141
Source/SlidersComponent.cpp
Normal file
141
Source/SlidersComponent.cpp
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
//
|
||||||
|
// SlidersComponent.cpp
|
||||||
|
// juicysfplugin - Shared Code
|
||||||
|
//
|
||||||
|
// Created by Alex Birch on 29/06/2019.
|
||||||
|
// Copyright © 2019 Birchlabs. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SlidersComponent.h"
|
||||||
|
#include "FluidSynthModel.h"
|
||||||
|
#include "MidiConstants.h"
|
||||||
|
|
||||||
|
std::function<void()> SlidersComponent::makeSliderListener(Slider& slider, int controller) {
|
||||||
|
return [this, controller, &slider]{
|
||||||
|
// slider.setValue(slider.getValue(), NotificationType::dontSendNotification);
|
||||||
|
fluidSynthModel->setControllerValue(controller, slider.getValue());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SlidersComponent::~SlidersComponent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const int SlidersComponent::getDesiredWidth() {
|
||||||
|
const int envelopeSliders{4};
|
||||||
|
const int filterSliders{2};
|
||||||
|
const int groupXMargin{8};
|
||||||
|
const int groupXPadding{8};
|
||||||
|
const int sliderXMargin{3};
|
||||||
|
const int sliderWidth{30};
|
||||||
|
|
||||||
|
return envelopeSliders * sliderWidth + (envelopeSliders-1) * sliderXMargin + 2 * groupXPadding
|
||||||
|
+ filterSliders * sliderWidth + (filterSliders-1) * sliderXMargin + 2 * groupXPadding + groupXMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SlidersComponent::resized() {
|
||||||
|
const int envelopeSliders{4};
|
||||||
|
const int filterSliders{2};
|
||||||
|
const int groupXMargin{8};
|
||||||
|
const int groupXPadding{8};
|
||||||
|
const int groupYPadding{9};
|
||||||
|
const int sliderXMargin{3};
|
||||||
|
const int labelHeight{25};
|
||||||
|
const int sliderWidth{30};
|
||||||
|
Rectangle<int> r{getLocalBounds()};
|
||||||
|
Rectangle<int> rEnvelope{r.removeFromLeft(envelopeSliders * sliderWidth + (envelopeSliders-1) * sliderXMargin + 2 * groupXPadding)};
|
||||||
|
Rectangle<int> rFilter{r.removeFromLeft(filterSliders * sliderWidth + (filterSliders-1) * sliderXMargin + 2 * groupXPadding + groupXMargin).withTrimmedLeft(groupXMargin)};
|
||||||
|
envelopeGroup.setBounds(rEnvelope);
|
||||||
|
filterGroup.setBounds(rFilter);
|
||||||
|
|
||||||
|
rEnvelope.reduce(groupXPadding, groupYPadding);
|
||||||
|
rFilter.reduce(groupXPadding, groupYPadding);
|
||||||
|
attackSlider.setBounds(rEnvelope.removeFromLeft(sliderWidth).withTrimmedTop(labelHeight));
|
||||||
|
decaySlider.setBounds(rEnvelope.removeFromLeft(sliderWidth + sliderXMargin).withTrimmedTop(labelHeight).withTrimmedLeft(sliderXMargin));
|
||||||
|
sustainSlider.setBounds(rEnvelope.removeFromLeft(sliderWidth + sliderXMargin).withTrimmedTop(labelHeight).withTrimmedLeft(sliderXMargin));
|
||||||
|
releaseSlider.setBounds(rEnvelope.removeFromLeft(sliderWidth + sliderXMargin).withTrimmedTop(labelHeight).withTrimmedLeft(sliderXMargin));
|
||||||
|
filterCutOffSlider.setBounds(rFilter.removeFromLeft(sliderWidth).withTrimmedTop(labelHeight));
|
||||||
|
filterResonanceSlider.setBounds(rFilter.removeFromLeft(sliderWidth + sliderXMargin).withTrimmedTop(labelHeight).withTrimmedLeft(sliderXMargin));
|
||||||
|
}
|
||||||
|
|
||||||
|
SlidersComponent::SlidersComponent(FluidSynthModel* fluidSynthModel) :
|
||||||
|
fluidSynthModel{fluidSynthModel},
|
||||||
|
envelopeGroup{"envelopeGroup", "Envelope"},
|
||||||
|
filterGroup{"filterGroup", "Filter"}
|
||||||
|
{
|
||||||
|
const Slider::SliderStyle style{Slider::SliderStyle::LinearVertical};
|
||||||
|
const double rangeMin(0);
|
||||||
|
const double rangeMax(127);
|
||||||
|
const double rangeStep(1);
|
||||||
|
|
||||||
|
attackSlider.setSliderStyle(style);
|
||||||
|
attackSlider.setRange(rangeMin, rangeMax, rangeStep);
|
||||||
|
attackSlider.onValueChange = makeSliderListener(attackSlider, static_cast<int>(SOUND_CTRL4));
|
||||||
|
attackSlider.setTextBoxStyle(Slider::TextBoxBelow, true, attackSlider.getTextBoxWidth(), attackSlider.getTextBoxHeight());
|
||||||
|
|
||||||
|
decaySlider.setSliderStyle(style);
|
||||||
|
decaySlider.setRange(rangeMin, rangeMax, rangeStep);
|
||||||
|
decaySlider.onValueChange = makeSliderListener(decaySlider, static_cast<int>(SOUND_CTRL6));
|
||||||
|
decaySlider.setTextBoxStyle(Slider::TextBoxBelow, true, decaySlider.getTextBoxWidth(), decaySlider.getTextBoxHeight());
|
||||||
|
|
||||||
|
sustainSlider.setSliderStyle(style);
|
||||||
|
sustainSlider.setRange(rangeMin, rangeMax, rangeStep);
|
||||||
|
sustainSlider.onValueChange = makeSliderListener(sustainSlider, static_cast<int>(SOUND_CTRL10));
|
||||||
|
sustainSlider.setTextBoxStyle(Slider::TextBoxBelow, true, sustainSlider.getTextBoxWidth(), sustainSlider.getTextBoxHeight());
|
||||||
|
|
||||||
|
releaseSlider.setSliderStyle(style);
|
||||||
|
releaseSlider.setRange(rangeMin, rangeMax, rangeStep);
|
||||||
|
releaseSlider.onValueChange = makeSliderListener(releaseSlider, static_cast<int>(SOUND_CTRL3));
|
||||||
|
releaseSlider.setTextBoxStyle(Slider::TextBoxBelow, true, releaseSlider.getTextBoxWidth(), releaseSlider.getTextBoxHeight());
|
||||||
|
|
||||||
|
filterCutOffSlider.setSliderStyle(style);
|
||||||
|
filterCutOffSlider.setRange(rangeMin, rangeMax, rangeStep);
|
||||||
|
filterCutOffSlider.onValueChange = makeSliderListener(filterCutOffSlider, static_cast<int>(SOUND_CTRL5));
|
||||||
|
filterCutOffSlider.setTextBoxStyle(Slider::TextBoxBelow, true, filterCutOffSlider.getTextBoxWidth(), filterCutOffSlider.getTextBoxHeight());
|
||||||
|
|
||||||
|
filterResonanceSlider.setSliderStyle(style);
|
||||||
|
filterResonanceSlider.setRange(rangeMin, rangeMax, rangeStep);
|
||||||
|
filterResonanceSlider.onValueChange = makeSliderListener(filterResonanceSlider, static_cast<int>(SOUND_CTRL2));
|
||||||
|
filterResonanceSlider.setTextBoxStyle(Slider::TextBoxBelow, true, filterResonanceSlider.getTextBoxWidth(), filterResonanceSlider.getTextBoxHeight());
|
||||||
|
|
||||||
|
addAndMakeVisible(attackSlider);
|
||||||
|
addAndMakeVisible(decaySlider);
|
||||||
|
addAndMakeVisible(sustainSlider);
|
||||||
|
addAndMakeVisible(releaseSlider);
|
||||||
|
addAndMakeVisible(filterCutOffSlider);
|
||||||
|
addAndMakeVisible(filterResonanceSlider);
|
||||||
|
|
||||||
|
attackLabel.setText("A", NotificationType::dontSendNotification);
|
||||||
|
attackLabel.setJustificationType(Justification::centredBottom);
|
||||||
|
attackLabel.attachToComponent(&attackSlider, false);
|
||||||
|
|
||||||
|
decayLabel.setText("D", NotificationType::dontSendNotification);
|
||||||
|
decayLabel.setJustificationType(Justification::centredBottom);
|
||||||
|
decayLabel.attachToComponent(&decaySlider, false);
|
||||||
|
|
||||||
|
sustainLabel.setText("S", NotificationType::dontSendNotification);
|
||||||
|
sustainLabel.setJustificationType(Justification::centredBottom);
|
||||||
|
sustainLabel.attachToComponent(&sustainSlider, false);
|
||||||
|
|
||||||
|
releaseLabel.setText("R", NotificationType::dontSendNotification);
|
||||||
|
releaseLabel.setJustificationType(Justification::centredBottom);
|
||||||
|
releaseLabel.attachToComponent(&releaseSlider, false);
|
||||||
|
|
||||||
|
filterCutOffLabel.setText("Cut", NotificationType::dontSendNotification);
|
||||||
|
filterCutOffLabel.setJustificationType(Justification::centredBottom);
|
||||||
|
filterCutOffLabel.attachToComponent(&filterCutOffSlider, false);
|
||||||
|
|
||||||
|
filterResonanceLabel.setText("Res", NotificationType::dontSendNotification);
|
||||||
|
filterResonanceLabel.setJustificationType(Justification::centredBottom);
|
||||||
|
filterResonanceLabel.attachToComponent(&filterResonanceSlider, false);
|
||||||
|
|
||||||
|
addAndMakeVisible(attackLabel);
|
||||||
|
addAndMakeVisible(decayLabel);
|
||||||
|
addAndMakeVisible(sustainLabel);
|
||||||
|
addAndMakeVisible(releaseLabel);
|
||||||
|
addAndMakeVisible(filterCutOffLabel);
|
||||||
|
addAndMakeVisible(filterResonanceLabel);
|
||||||
|
|
||||||
|
addAndMakeVisible(envelopeGroup);
|
||||||
|
addAndMakeVisible(filterGroup);
|
||||||
|
}
|
46
Source/SlidersComponent.h
Normal file
46
Source/SlidersComponent.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# pragma once
|
||||||
|
|
||||||
|
#include "../JuceLibraryCode/JuceHeader.h"
|
||||||
|
#include "FluidSynthModel.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class SlidersComponent : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SlidersComponent(FluidSynthModel* fluidSynthModel);
|
||||||
|
~SlidersComponent();
|
||||||
|
|
||||||
|
void resized() override;
|
||||||
|
|
||||||
|
const int getDesiredWidth();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void()> makeSliderListener(Slider& slider, int controller);
|
||||||
|
|
||||||
|
FluidSynthModel* fluidSynthModel;
|
||||||
|
|
||||||
|
GroupComponent envelopeGroup;
|
||||||
|
|
||||||
|
Slider attackSlider;
|
||||||
|
Label attackLabel;
|
||||||
|
|
||||||
|
Slider decaySlider;
|
||||||
|
Label decayLabel;
|
||||||
|
|
||||||
|
Slider sustainSlider;
|
||||||
|
Label sustainLabel;
|
||||||
|
|
||||||
|
Slider releaseSlider;
|
||||||
|
Label releaseLabel;
|
||||||
|
|
||||||
|
GroupComponent filterGroup;
|
||||||
|
|
||||||
|
Slider filterCutOffSlider;
|
||||||
|
Label filterCutOffLabel;
|
||||||
|
|
||||||
|
Slider filterResonanceSlider;
|
||||||
|
Label filterResonanceLabel;
|
||||||
|
|
||||||
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SlidersComponent)
|
||||||
|
};
|
|
@ -24,6 +24,7 @@ void SoundfontSynthVoice::startNote(
|
||||||
SynthesiserSound* sound,
|
SynthesiserSound* sound,
|
||||||
int /*currentPitchWheelPosition*/) {
|
int /*currentPitchWheelPosition*/) {
|
||||||
this->midiNoteNumber = midiNoteNumber;
|
this->midiNoteNumber = midiNoteNumber;
|
||||||
|
Logger::outputDebugString ( juce::String::formatted("JUCE noteon: %d, %d\n", midiNoteNumber, velocity) );
|
||||||
fluid_synth_noteon(synth, 0, midiNoteNumber, static_cast<int>(velocity * 127));
|
fluid_synth_noteon(synth, 0, midiNoteNumber, static_cast<int>(velocity * 127));
|
||||||
|
|
||||||
// currentAngle = 0.0;
|
// currentAngle = 0.0;
|
||||||
|
@ -55,6 +56,7 @@ void SoundfontSynthVoice::stopNote (float /*velocity*/, bool allowTailOff) {
|
||||||
// clearCurrentNote();
|
// clearCurrentNote();
|
||||||
// angleDelta = 0.0;
|
// angleDelta = 0.0;
|
||||||
// }
|
// }
|
||||||
|
Logger::outputDebugString ( juce::String("JUCE noteoff\n") );
|
||||||
clearCurrentNote();
|
clearCurrentNote();
|
||||||
fluid_synth_noteoff(synth, 0, this->midiNoteNumber);
|
fluid_synth_noteoff(synth, 0, this->midiNoteNumber);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,12 @@ TableComponent::TableComponent(
|
||||||
// Add some columns to the table header, based on the column list in our database..
|
// Add some columns to the table header, based on the column list in our database..
|
||||||
for (auto &column : columns) // access by reference to avoid copying
|
for (auto &column : columns) // access by reference to avoid copying
|
||||||
{
|
{
|
||||||
|
const int colWidth{ columnIx == 1 ? 30 : 200 };
|
||||||
table.getHeader().addColumn (
|
table.getHeader().addColumn (
|
||||||
String(column),
|
String(column),
|
||||||
columnIx++,
|
columnIx++,
|
||||||
100, // column width
|
colWidth, // column width
|
||||||
50, // min width
|
30, // min width
|
||||||
400, // max width
|
400, // max width
|
||||||
TableHeaderComponent::defaultFlags
|
TableHeaderComponent::defaultFlags
|
||||||
);
|
);
|
||||||
|
@ -147,9 +148,12 @@ void TableComponent::sortOrderChanged (
|
||||||
// This is overloaded from TableListBoxModel, and should choose the best width for the specified
|
// This is overloaded from TableListBoxModel, and should choose the best width for the specified
|
||||||
// column.
|
// column.
|
||||||
int TableComponent::getColumnAutoSizeWidth (int columnId) {
|
int TableComponent::getColumnAutoSizeWidth (int columnId) {
|
||||||
if (columnId == 5)
|
// if (columnId == 5)
|
||||||
return 100; // (this is the ratings column, containing a custom combobox component)
|
// return 100; // (this is the ratings column, containing a custom combobox component)
|
||||||
|
if (columnId == 1)
|
||||||
|
return 30; // (this is the ratings column, containing a custom combobox component)
|
||||||
|
|
||||||
|
|
||||||
int widest = 32;
|
int widest = 32;
|
||||||
|
|
||||||
// find the widest bit of text in this column..
|
// find the widest bit of text in this column..
|
||||||
|
@ -202,4 +206,4 @@ void TableComponent::selectedRowsChanged (int row) {
|
||||||
|
|
||||||
bool TableComponent::keyPressed(const KeyPress &key) {
|
bool TableComponent::keyPressed(const KeyPress &key) {
|
||||||
return table.keyPressed(key);
|
return table.keyPressed(key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ TablesComponent::TablesComponent(
|
||||||
};
|
};
|
||||||
|
|
||||||
presetTable = new TableComponent(
|
presetTable = new TableComponent(
|
||||||
{"Preset", "Name"},
|
{"#", "Name"},
|
||||||
mapPresets(
|
mapPresets(
|
||||||
banksToPresets,
|
banksToPresets,
|
||||||
selectedBank
|
selectedBank
|
||||||
|
@ -184,4 +184,4 @@ void TablesComponent::fontChanged(FluidSynthModel *, const String &) {
|
||||||
mapBanks(banksToPresets),
|
mapBanks(banksToPresets),
|
||||||
selectedBank
|
selectedBank
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user