From 02941424387a064301372c12bda3e8c3ab3fee45 Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Sun, 19 Jun 2011 01:26:26 +0000 Subject: Major work, all synthesizers. Other fixes. Please see ChangeLog. --- muse2/synti/fluidsynth/common_defs.h | 8 ++ muse2/synti/fluidsynth/fluidsynthgui.cpp | 73 ++++++++++------ muse2/synti/fluidsynth/fluidsynthgui.h | 3 +- muse2/synti/fluidsynth/fluidsynti.cpp | 142 ++++++++++++++++++++++--------- muse2/synti/fluidsynth/fluidsynti.h | 10 ++- 5 files changed, 169 insertions(+), 67 deletions(-) create mode 100644 muse2/synti/fluidsynth/common_defs.h (limited to 'muse2/synti/fluidsynth') diff --git a/muse2/synti/fluidsynth/common_defs.h b/muse2/synti/fluidsynth/common_defs.h new file mode 100644 index 00000000..f1f4007d --- /dev/null +++ b/muse2/synti/fluidsynth/common_defs.h @@ -0,0 +1,8 @@ +#ifndef __FLUIDSYNTH_UNIQUE_ID_H +#define __FLUIDSYNTH_UNIQUE_ID_H + +// Make sure this number is unique among all the MESS synths. +#define FLUIDSYNTH_UNIQUE_ID 3 + +#endif + diff --git a/muse2/synti/fluidsynth/fluidsynthgui.cpp b/muse2/synti/fluidsynth/fluidsynthgui.cpp index 2e91515f..6dda43bd 100644 --- a/muse2/synti/fluidsynth/fluidsynthgui.cpp +++ b/muse2/synti/fluidsynth/fluidsynthgui.cpp @@ -22,6 +22,7 @@ #include "muse/midi.h" #include "icons.h" +#include "common_defs.h" /* #include "muse/debug.h" @@ -183,10 +184,14 @@ void FluidSynthGui::loadClicked() void FluidSynthGui::sendLastdir(QString dir) { - int l = dir.length()+2; + //int l = dir.length()+2; + int l = dir.length()+4; byte data[l]; - data[0] = FS_LASTDIR_CHANGE; - memcpy(data+1, dir.toLatin1(), dir.length()+1); + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_LASTDIR_CHANGE; + //memcpy(data+1, dir.toLatin1(), dir.length()+1); + memcpy(data+3, dir.toLatin1(), dir.length()+1); sendSysex(data,l); } @@ -197,11 +202,15 @@ void FluidSynthGui::sendLastdir(QString dir) void FluidSynthGui::sendLoadFont(QString filename) { - int l = filename.length()+3; + //int l = filename.length()+3; + int l = filename.length()+5; byte data[l]; - data[0] = FS_PUSH_FONT; - data[1] = FS_UNSPECIFIED_ID; - memcpy(data+2, filename.toLatin1(), filename.length()+1); + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_PUSH_FONT; + data[3] = FS_UNSPECIFIED_ID; + //memcpy(data+2, filename.toLatin1(), filename.length()+1); + memcpy(data+4, filename.toLatin1(), filename.length()+1); sendSysex(data,l); } @@ -446,9 +455,13 @@ void FluidSynthGui::changeGain(int value) //--------------------------------------------------------- void FluidSynthGui::dumpInfo() { - byte data[1]; - data[0] = FS_DUMP_INFO; - sendSysex(data, 1); + //byte data[1]; + byte data[3]; + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_DUMP_INFO; + //sendSysex(data, 1); + sendSysex(data, 3); } //--------------------------------------------------------- @@ -581,11 +594,15 @@ int FluidSynthGui::getSoundFontId(QString q) void FluidSynthGui::sendChannelChange(byte font_id, byte channel) { - byte data[3]; - data[0] = FS_SOUNDFONT_CHANNEL_SET; - data[1] = font_id; - data[2] = channel; - sendSysex(data, 3); + //byte data[3]; + byte data[5]; + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_SOUNDFONT_CHANNEL_SET; + data[3] = font_id; + data[4] = channel; + //sendSysex(data, 3); + sendSysex(data, 5); } //--------------------------------------------------------- @@ -594,21 +611,29 @@ void FluidSynthGui::sendChannelChange(byte font_id, byte channel) //--------------------------------------------------------- void FluidSynthGui::sendDrumChannelChange(byte onoff, byte channel) { - byte data[3]; - data[0] = FS_DRUMCHANNEL_SET; - data[1] = onoff; - data[2] = channel; - sendSysex(data, 3); + //byte data[3]; + byte data[5]; + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_DRUMCHANNEL_SET; + data[3] = onoff; + data[4] = channel; + //sendSysex(data, 3); + sendSysex(data, 5); if (FS_DEBUG) printf("Sent FS_DRUMCHANNEL_SET for channel %d, status: %d\n", channel, onoff); } void FluidSynthGui::popClicked() { - byte data[2]; - data[0] = FS_SOUNDFONT_POP; - data[1] = currentlySelectedFont; - sendSysex(data,2); + //byte data[2]; + byte data[4]; + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_SOUNDFONT_POP; + data[3] = currentlySelectedFont; + //sendSysex(data,2); + sendSysex(data,4); } void FluidSynthGui::sfItemClicked(QTreeWidgetItem* item, int /*col*/) diff --git a/muse2/synti/fluidsynth/fluidsynthgui.h b/muse2/synti/fluidsynth/fluidsynthgui.h index 5b39723e..373a2343 100644 --- a/muse2/synti/fluidsynth/fluidsynthgui.h +++ b/muse2/synti/fluidsynth/fluidsynthgui.h @@ -46,7 +46,8 @@ struct FluidChannel; #define FS_SFDATALEN 1 #define FS_VERSION_MAJOR 0 #define FS_VERSION_MINOR 4 -#define FS_INIT_DATA_HEADER_SIZE 4 +//#define FS_INIT_DATA_HEADER_SIZE 4 +#define FS_INIT_DATA_HEADER_SIZE 6 // Including MFG + synth IDs #define FS_INIT_CHANNEL_SECTION 255 // Predefined init-values for fluidsynth diff --git a/muse2/synti/fluidsynth/fluidsynti.cpp b/muse2/synti/fluidsynth/fluidsynti.cpp index aadc92ef..35ee16df 100644 --- a/muse2/synti/fluidsynth/fluidsynti.cpp +++ b/muse2/synti/fluidsynth/fluidsynti.cpp @@ -12,6 +12,7 @@ #include +//#include "common_defs.h" #include "fluidsynti.h" #include "muse/midi.h" @@ -65,6 +66,7 @@ QString *projPathPtr; // FluidSynth::FluidSynth(int sr, pthread_mutex_t *_Globalsfloader_mutex) : Mess(2) { + gui = 0; setSampleRate(sr); fluid_settings_t* s = new_fluid_settings(); fluid_settings_setnum(s, (char*) "synth.sample-rate", float(sampleRate())); @@ -85,19 +87,18 @@ FluidSynth::FluidSynth(int sr, pthread_mutex_t *_Globalsfloader_mutex) : Mess(2) //pthread_mutex_init(&_sfloader_mutex,NULL); _sfloader_mutex = _Globalsfloader_mutex; -/* - buffer = 0; - bufferlen = 0; - */ + initBuffer = 0; + initLen = 0; } FluidSynth::~FluidSynth() { int err = delete_fluid_synth (fluidsynth); - delete gui; + if(gui) + delete gui; -/* if (buffer) - delete [] buffer;*/ + if (initBuffer) + delete [] initBuffer; if (err == -1) { std::cerr << DEBUG_ARGS << "error while destroying synth: " << fluid_synth_error(fluidsynth) << std::endl; return; @@ -141,6 +142,13 @@ bool FluidSynth::init(const char* name) return false; } +int FluidSynth::oldMidiStateHeader(const unsigned char** data) const +{ + unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, FLUIDSYNTH_UNIQUE_ID}; + *data = &d[0]; + return 2; +} + //--------------------------------------------------------- // processMessages // Called from host always, even if output path is unconnected. @@ -207,7 +215,7 @@ void FluidSynth::process(float** ports, int offset, int len) // getInitData // Prepare data that will restore the synth's state on load //--------------------------------------------------------- -void FluidSynth::getInitData(int* n, const unsigned char** data) const +void FluidSynth::getInitData(int* n, const unsigned char** data) { //printf("projPathPtr "); @@ -250,16 +258,29 @@ void FluidSynth::getInitData(int* n, const unsigned char** data) const if (FS_DEBUG) printf("Total length of init sysex: %d\n", len); - byte* d = new byte[len]; + + //byte* d = new byte[len]; + if (len > initLen) { + if (initBuffer) + delete [] initBuffer; + initBuffer = new byte[len]; + initLen = len; + } // Header: - d[0] = FS_INIT_DATA; - d[1] = FS_VERSION_MAJOR; - d[2] = FS_VERSION_MINOR; - d[3] = stack.size(); + //d[0] = FS_INIT_DATA; + //d[1] = FS_VERSION_MAJOR; + //d[2] = FS_VERSION_MINOR; + //d[3] = stack.size(); + initBuffer[0] = MUSE_SYNTH_SYSEX_MFG_ID; + initBuffer[1] = FLUIDSYNTH_UNIQUE_ID; + initBuffer[2] = FS_INIT_DATA; + initBuffer[3] = FS_VERSION_MAJOR; + initBuffer[4] = FS_VERSION_MINOR; + initBuffer[5] = stack.size(); //Lastdir: - byte* chptr = d + FS_INIT_DATA_HEADER_SIZE; + byte* chptr = initBuffer + FS_INIT_DATA_HEADER_SIZE; memcpy(chptr, lastdir.c_str(), strlen(lastdir.c_str())+1); //For each font... @@ -298,14 +319,14 @@ void FluidSynth::getInitData(int* n, const unsigned char** data) const *chptr = cho_on; chptr++; if (FS_DEBUG) { for (int i=0; itoAscii().data() << std::endl; @@ -329,6 +350,7 @@ void FluidSynth::parseInitData(int n, const byte* d) byte version_major, version_minor; version_major = d[1]; version_minor = d[2]; + //version_major = d[3]; version_minor = d[4]; // Check which version of the initdata we're using and if it's OK if (!(version_major == FS_VERSION_MAJOR && version_minor == FS_VERSION_MINOR)) { @@ -337,9 +359,9 @@ void FluidSynth::parseInitData(int n, const byte* d) } if (version_major == 0 && version_minor == 1) { - sendError("Initialization data created with different version of FluidSynth Mess, will be ignored."); - return; - } + sendError("Initialization data created with different version of FluidSynth Mess, will be ignored."); + return; + } if (version_major == 0 && version_minor <= 2) { load_drumchannels = false; @@ -351,8 +373,10 @@ void FluidSynth::parseInitData(int n, const byte* d) } byte nr_of_fonts = d[3]; + //byte nr_of_fonts = d[5]; nrOfSoundfonts = nr_of_fonts; //"Global" counter const byte* chptr = (d + 4); + //const byte* chptr = (d + FS_INIT_DATA_HEADER_SIZE); //Get lastdir: lastdir = std::string((char*)chptr); @@ -365,7 +389,7 @@ void FluidSynth::parseInitData(int n, const byte* d) for (int i=0; itoAscii(); + QByteArray ba = projPathPtr->toAscii(); if (QFileInfo(fonts[i].filename.c_str()).isRelative()) { printf("path is relative, we append full path!\n"); @@ -413,7 +437,7 @@ void FluidSynth::parseInitData(int n, const byte* d) for (int i=0; i::iterator it = stack.begin(); it != stack.end(); it++) { @@ -654,11 +689,16 @@ void FluidSynth::sendSoundFontData() ndatalen += FS_SFDATALEN; //unsigned char for ID } byte ndata[ndatalen]; - *ndata = FS_SEND_SOUNDFONTDATA; //The command + *(ndata) = FS_SEND_SOUNDFONTDATA; //The command *(ndata + 1) = (unsigned char)stack.size (); //Nr of Soundfonts + //*ndata = MUSE_SYNTH_SYSEX_MFG_ID; + //*(ndata + 1) = FLUIDSYNTH_UNIQUE_ID; + //*(ndata + 2) = FS_SEND_SOUNDFONTDATA; //The command + //*(ndata + 3) = (unsigned char)stack.size (); //Nr of Soundfonts // Copy the stuff to ndatalen: char* chunk_start = (char*)(ndata + 2); + //char* chunk_start = (char*)(ndata + 4); int chunk_len, name_len; for (std::list::iterator it = stack.begin(); it != stack.end(); ++it) { name_len = strlen(it->name.c_str()) + 1; @@ -675,12 +715,18 @@ void FluidSynth::sendSoundFontData() //--------------------------------------------------------- void FluidSynth::sendChannelData() { - int chunk_size = 2; + ///int chunk_size = 2; + int const chunk_size = 2; int chdata_length = (chunk_size * FS_MAX_NR_OF_CHANNELS) +1 ; //Command and the 2 channels * 16 + //int chdata_length = (chunk_size * FS_MAX_NR_OF_CHANNELS) +3 ; // Header, command and the 2 channels * 16 byte chdata[chdata_length]; byte* chdptr; chdata[0] = FS_SEND_CHANNELINFO; + //chdata[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //chdata[1] = FLUIDSYNTH_UNIQUE_ID; + //chdata[2] = FS_SEND_CHANNELINFO; chdptr = (chdata + 1); + //chdptr = (chdata + 3); for (int i=0; iwriteEvent(ev); @@ -1289,7 +1351,7 @@ static bool mutexEnabled = false; static Mess* instantiate(int sr, QWidget*, QString* projectPathPtr, const char* name) { -printf("fluidsynth sampleRate %d\n", sr); + printf("fluidsynth sampleRate %d\n", sr); projPathPtr=projectPathPtr; if (!mutexEnabled) { diff --git a/muse2/synti/fluidsynth/fluidsynti.h b/muse2/synti/fluidsynth/fluidsynti.h index a371de9e..fde42396 100644 --- a/muse2/synti/fluidsynth/fluidsynti.h +++ b/muse2/synti/fluidsynth/fluidsynti.h @@ -20,6 +20,7 @@ //#include "libsynti/mpevent.h" #include "muse/mpevent.h" #include "muse/midictrl.h" +#include "common_defs.h" #define FS_DEBUG_DATA 0 //Turn on/off debug print of midi data sent to fluidsynth @@ -83,6 +84,9 @@ class FluidSynth : public Mess { void sfChannelChange(unsigned char font_id, unsigned char channel); void parseInitData(int n, const byte* d); + byte* initBuffer; + int initLen; + byte getFontInternalIdByExtId (byte channel); void debug(const char* msg) { if (FS_DEBUG) printf("Debug: %s\n",msg); } @@ -101,15 +105,17 @@ class FluidSynth : public Mess { public: FluidSynth(int sr, pthread_mutex_t *_Globalsfloader_mutex); - ~FluidSynth(); + virtual ~FluidSynth(); bool init(const char*); + // This is only a kludge required to support old songs' midistates. Do not use in any new synth. + virtual int oldMidiStateHeader(const unsigned char** data) const; virtual void processMessages(); virtual void process(float**, int, int); virtual bool playNote(int channel, int pitch, int velo); virtual bool sysex(int, const unsigned char*); virtual bool setController(int, int, int); void setController(int, int , int, bool); - virtual void getInitData(int*, const unsigned char**) const; + virtual void getInitData(int*, const unsigned char**); virtual const char* getPatchName(int, int, int, bool) const; virtual const MidiPatch* getPatchInfo(int i, const MidiPatch* patch) const; virtual int getControllerInfo(int, const char**, int*, int*, int*, int*) const; -- cgit v1.2.3