00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "pent_include.h"
00022 #include "FluidSynthMidiDriver.h"
00023
00024 #ifdef USE_FLUIDSYNTH_MIDI
00025
00026
00027
00028 const MidiDriver::MidiDriverDesc FluidSynthMidiDriver::desc =
00029 MidiDriver::MidiDriverDesc ("FluidSynth", createInstance);
00030
00031
00032
00033 FluidSynthMidiDriver::FluidSynthMidiDriver()
00034 : LowLevelMidiDriver(), _settings(0), _synth(0), _soundFont(-1)
00035 {
00036 }
00037
00038 void FluidSynthMidiDriver::setInt(const char *name, int val) {
00039
00040 char *name2 = const_cast<char*>(name);
00041
00042 fluid_settings_setint(_settings, name2, val);
00043
00044 }
00045
00046 void FluidSynthMidiDriver::setNum(const char *name, double val) {
00047
00048 char *name2 = const_cast<char*>(name);
00049
00050 fluid_settings_setnum(_settings, name2, val);
00051
00052 }
00053
00054 void FluidSynthMidiDriver::setStr(const char *name, const char *val) {
00055
00056
00057 char *name2 = const_cast<char*>(name);
00058 char *val2 = const_cast<char*>(val);
00059
00060 fluid_settings_setstr(_settings, name2, val2);
00061
00062
00063 }
00064
00065 int FluidSynthMidiDriver::open() {
00066
00067 if (!stereo) {
00068 perr << "FluidSynth only works with Stereo output" << std::endl;
00069 return -1;
00070 }
00071
00072 std::string soundfont = getConfigSetting("fluidsynth_soundfont", "");
00073
00074 if (soundfont == "") {
00075 perr << "FluidSynth requires a 'fluidsynth_soundfont' setting" << std::endl;
00076 return -2;
00077 }
00078
00079 _settings = new_fluid_settings();
00080
00081
00082
00083
00084 setNum("synth.gain", 2.1);
00085 setNum("synth.sample-rate", sample_rate);
00086
00087 _synth = new_fluid_synth(_settings);
00088
00089
00090
00091
00092
00093
00094
00095
00096 _soundFont = fluid_synth_sfload(_synth, soundfont.c_str(), 1);
00097 if (_soundFont == -1) {
00098 perr << "Failed loading custom sound font '" << soundfont << "'" << std::endl;
00099 return -3;
00100 }
00101
00102 return 0;
00103 }
00104
00105 void FluidSynthMidiDriver::close() {
00106
00107 if (_soundFont != -1)
00108 fluid_synth_sfunload(_synth, _soundFont, 1);
00109 _soundFont = -1;
00110
00111 delete_fluid_synth(_synth);
00112 _synth = 0;
00113 delete_fluid_settings(_settings);
00114 _settings = 0;
00115 }
00116
00117 void FluidSynthMidiDriver::send(uint32 b) {
00118
00119 uint32 param2 = (uint8) ((b >> 16) & 0xFF);
00120 uint32 param1 = (uint8) ((b >> 8) & 0xFF);
00121 uint8 cmd = (uint8) (b & 0xF0);
00122 uint8 chan = (uint8) (b & 0x0F);
00123
00124 switch (cmd) {
00125 case 0x80:
00126 fluid_synth_noteoff(_synth, chan, param1);
00127 break;
00128 case 0x90:
00129 fluid_synth_noteon(_synth, chan, param1, param2);
00130 break;
00131 case 0xA0:
00132 break;
00133 case 0xB0:
00134 fluid_synth_cc(_synth, chan, param1, param2);
00135 break;
00136 case 0xC0:
00137 fluid_synth_program_change(_synth, chan, param1);
00138 break;
00139 case 0xD0:
00140 break;
00141 case 0xE0:
00142 fluid_synth_pitch_bend(_synth, chan, (param2 << 7) | param1);
00143 break;
00144 case 0xF0:
00145
00146
00147 perr << "FluidSynthMidiDriver: Receiving SysEx command on a send() call" << std::endl;
00148 break;
00149 default:
00150 perr << "FluidSynthMidiDriver: Unknown send() command 0x" << std::hex << cmd << std::dec << std::endl;
00151 break;
00152 }
00153 }
00154
00155 void FluidSynthMidiDriver::lowLevelProduceSamples(sint16 *samples, uint32 num_samples) {
00156 fluid_synth_write_s16(_synth, num_samples, samples, 0, 2, samples, 1, 2);
00157 }
00158
00159 #endif