diff --git a/Builds/MacOSX/juicysfplugin.xcodeproj/project.pbxproj b/Builds/MacOSX/juicysfplugin.xcodeproj/project.pbxproj index 4f4dd07..fa94fdd 100644 --- a/Builds/MacOSX/juicysfplugin.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/juicysfplugin.xcodeproj/project.pbxproj @@ -294,6 +294,7 @@ 358E45BB22BEE53A0087ED8D /* libgthread-2.0.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = "libgthread-2.0.0.dylib"; sourceTree = ""; }; 358E45BC22BEE53A0087ED8D /* libFLAC.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libFLAC.8.dylib; sourceTree = ""; }; 358E45BD22BEE53A0087ED8D /* libogg.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libogg.0.dylib; sourceTree = ""; }; + 358E45F422BFC00C0087ED8D /* MidiConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MidiConstants.h; path = ../../Source/MidiConstants.h; sourceTree = ""; }; 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; }; 3909EE4609ED2DCCC6B6B290 /* juce_data_structures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_data_structures; path = /Applications/JUCE/modules/juce_data_structures; sourceTree = ""; }; @@ -545,6 +546,7 @@ 420DCC01988E65E68562F9DC /* PluginProcessor.h */, 35D551D55292C9D0508A408A /* PluginEditor.cpp */, 8990F3EAFFBBD6A42247C663 /* PluginEditor.h */, + 358E45F422BFC00C0087ED8D /* MidiConstants.h */, ); name = Source; sourceTree = ""; diff --git a/Source/FluidSynthModel.cpp b/Source/FluidSynthModel.cpp index f9a4301..22221a9 100644 --- a/Source/FluidSynthModel.cpp +++ b/Source/FluidSynthModel.cpp @@ -43,7 +43,7 @@ void FluidSynthModel::initialise() { settings = new_fluid_settings(); // https://sourceforge.net/p/fluidsynth/wiki/FluidSettings/ -// fluid_settings_setint(settings, "synth.verbose", 1); + fluid_settings_setint(settings, "synth.verbose", 1); synth = new_fluid_synth(settings); fluid_synth_set_sample_rate(synth, currentSampleRate); @@ -85,9 +85,10 @@ void FluidSynthModel::initialise() { // FLUID_MOD_CONCAVE); // // modulator's secondary source controller and flags // // MIDI CC 74 -// fluid_mod_set_source2(mod, 74, FLUID_MOD_CC); +//// fluid_mod_set_source2(mod, 74, FLUID_MOD_CC); +// fluid_mod_set_source2(mod, 0, 0); // // generator for filter cutoff -// fluid_mod_set_dest(mod, GEN_FILTERFC); +// fluid_mod_set_dest(mod, GEN_MODENVATTACK); // fluid_mod_set_amount(mod, 13500.0f); // // fluid_synth_add_default_mod(synth, mod, FLUID_SYNTH_ADD); diff --git a/Source/MidiConstants.h b/Source/MidiConstants.h new file mode 100644 index 0000000..d40d852 --- /dev/null +++ b/Source/MidiConstants.h @@ -0,0 +1,130 @@ +#pragma once + +/* Taken from fluidsynth/src/midi/fluid_midi.h + * https://github.com/FluidSynth/fluidsynth/blob/master/src/midi/fluid_midi.h + * + * FluidSynth - A Software Synthesizer + * + * Copyright (C) 2003 Peter Hanappe and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + +enum fluid_midi_event_type +{ + /* channel messages */ + NOTE_OFF = 0x80, + NOTE_ON = 0x90, + KEY_PRESSURE = 0xa0, + CONTROL_CHANGE = 0xb0, + PROGRAM_CHANGE = 0xc0, + CHANNEL_PRESSURE = 0xd0, + PITCH_BEND = 0xe0, + /* system exclusive */ + MIDI_SYSEX = 0xf0, + /* system common - never in midi files */ + MIDI_TIME_CODE = 0xf1, + MIDI_SONG_POSITION = 0xf2, + MIDI_SONG_SELECT = 0xf3, + MIDI_TUNE_REQUEST = 0xf6, + MIDI_EOX = 0xf7, + /* system real-time - never in midi files */ + MIDI_SYNC = 0xf8, + MIDI_TICK = 0xf9, + MIDI_START = 0xfa, + MIDI_CONTINUE = 0xfb, + MIDI_STOP = 0xfc, + MIDI_ACTIVE_SENSING = 0xfe, + MIDI_SYSTEM_RESET = 0xff, + /* meta event - for midi files only */ + MIDI_META_EVENT = 0xff +}; + +enum fluid_midi_control_change +{ + BANK_SELECT_MSB = 0x00, + MODULATION_MSB = 0x01, + BREATH_MSB = 0x02, + FOOT_MSB = 0x04, + PORTAMENTO_TIME_MSB = 0x05, + DATA_ENTRY_MSB = 0x06, + VOLUME_MSB = 0x07, + BALANCE_MSB = 0x08, + PAN_MSB = 0x0A, + EXPRESSION_MSB = 0x0B, + EFFECTS1_MSB = 0x0C, + EFFECTS2_MSB = 0x0D, + GPC1_MSB = 0x10, /* general purpose controller */ + GPC2_MSB = 0x11, + GPC3_MSB = 0x12, + GPC4_MSB = 0x13, + BANK_SELECT_LSB = 0x20, + MODULATION_WHEEL_LSB = 0x21, + BREATH_LSB = 0x22, + FOOT_LSB = 0x24, + PORTAMENTO_TIME_LSB = 0x25, + DATA_ENTRY_LSB = 0x26, + VOLUME_LSB = 0x27, + BALANCE_LSB = 0x28, + PAN_LSB = 0x2A, + EXPRESSION_LSB = 0x2B, + EFFECTS1_LSB = 0x2C, + EFFECTS2_LSB = 0x2D, + GPC1_LSB = 0x30, + GPC2_LSB = 0x31, + GPC3_LSB = 0x32, + GPC4_LSB = 0x33, + SUSTAIN_SWITCH = 0x40, + PORTAMENTO_SWITCH = 0x41, + SOSTENUTO_SWITCH = 0x42, + SOFT_PEDAL_SWITCH = 0x43, + LEGATO_SWITCH = 0x44, + HOLD2_SWITCH = 0x45, + SOUND_CTRL1 = 0x46, + SOUND_CTRL2 = 0x47, + SOUND_CTRL3 = 0x48, + SOUND_CTRL4 = 0x49, + SOUND_CTRL5 = 0x4A, + SOUND_CTRL6 = 0x4B, + SOUND_CTRL7 = 0x4C, + SOUND_CTRL8 = 0x4D, + SOUND_CTRL9 = 0x4E, + SOUND_CTRL10 = 0x4F, + GPC5 = 0x50, + GPC6 = 0x51, + GPC7 = 0x52, + GPC8 = 0x53, + PORTAMENTO_CTRL = 0x54, + EFFECTS_DEPTH1 = 0x5B, + EFFECTS_DEPTH2 = 0x5C, + EFFECTS_DEPTH3 = 0x5D, + EFFECTS_DEPTH4 = 0x5E, + EFFECTS_DEPTH5 = 0x5F, + DATA_ENTRY_INCR = 0x60, + DATA_ENTRY_DECR = 0x61, + NRPN_LSB = 0x62, + NRPN_MSB = 0x63, + RPN_LSB = 0x64, + RPN_MSB = 0x65, + ALL_SOUND_OFF = 0x78, + ALL_CTRL_OFF = 0x79, + LOCAL_CONTROL = 0x7A, + ALL_NOTES_OFF = 0x7B, + OMNI_OFF = 0x7C, + OMNI_ON = 0x7D, + POLY_OFF = 0x7E, + POLY_ON = 0x7F +}; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index ff89ccc..dc5218f 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -13,6 +13,7 @@ #include "SoundfontSynthVoice.h" #include "SoundfontSynthSound.h" #include "ExposesComponents.h" +#include "MidiConstants.h" AudioProcessor* JUCE_CALLTYPE createPluginFilter(); @@ -153,6 +154,36 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer& buffer, MidiBuffer // Now pass any incoming midi messages to our keyboard state object, and let it // add messages to the buffer if the user is clicking on the on-screen keys keyboardState.processNextMidiBuffer (midiMessages, 0, numSamples, true); + + MidiBuffer processedMidi; + int time; + MidiMessage m; + + // TODO: factor into a MidiCollector + for (MidiBuffer::Iterator i (midiMessages); i.getNextEvent (m, time);) { + Logger::outputDebugString ( m.getDescription() ); + if (m.isController()) { +// switch(static_cast(m.getControllerNumber())) { +// case GEN_VOLENVATTACK: +// +// break; +// default: +// break; +// } +// m.getControllerValue() +// fluid_event_t *event(new_fluid_event()); +// fluid_event_control_change(event, fluidSynthModel.getChannel(), m.getControllerNumber(), m.getControllerValue()); +// delete_fluid_event(event); + fluid_midi_event_t *midi_event(new_fluid_midi_event()); + fluid_midi_event_set_type(midi_event, static_cast(CONTROL_CHANGE)); + 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); + + delete_fluid_midi_event(midi_event); + } + } // and now get our synth to process these midi events and generate its output. synth.renderNextBlock (buffer, midiMessages, 0, numSamples);