diff options
| author | Robert Jonsson <spamatica@gmail.com> | 2011-09-15 12:14:55 +0000 | 
|---|---|---|
| committer | Robert Jonsson <spamatica@gmail.com> | 2011-09-15 12:14:55 +0000 | 
| commit | b0546e5e7f7044019892543c6c82029db8d564a7 (patch) | |
| tree | 1b96a6260900f3fbf3513fb48a5a72aa89052dc8 /attic/muse_qt4_evolution/synti/fluidsynth/fluidsynti.cpp | |
| parent | 583c73d1a07154d3d2672d65d8cce6495f490454 (diff) | |
moved attic to a branch of it's own
Diffstat (limited to 'attic/muse_qt4_evolution/synti/fluidsynth/fluidsynti.cpp')
| -rw-r--r-- | attic/muse_qt4_evolution/synti/fluidsynth/fluidsynti.cpp | 1174 | 
1 files changed, 0 insertions, 1174 deletions
diff --git a/attic/muse_qt4_evolution/synti/fluidsynth/fluidsynti.cpp b/attic/muse_qt4_evolution/synti/fluidsynth/fluidsynti.cpp deleted file mode 100644 index 57e72262..00000000 --- a/attic/muse_qt4_evolution/synti/fluidsynth/fluidsynti.cpp +++ /dev/null @@ -1,1174 +0,0 @@ -/* - * MusE FLUID Synth softsynth plugin - * - * Copyright (C) 2004 Mathias Lundgren (lunar_shuttle@users.sourcforge.net) - * - * $Id: fluidsynti.cpp,v 1.28 2005/12/18 14:09:54 wschweer Exp $ - * - */ - -#include "fluidsynti.h" -#include "muse/midi.h" - -#include <list> -#include <iostream> - - -FluidCtrl FluidSynth::fluidCtrl[] = { -      { "Gain", FS_GAIN ,0, 127}, -      { "Master reverb on/off", FS_REVERB_ON , 0, 1}, -      { "Master reverb level", FS_REVERB_LEVEL, 0, 16384 }, -      { "Master reverb size", FS_REVERB_ROOMSIZE, 0, 16384 }, // Interval: [0,1] -      { "Master reverb damping", FS_REVERB_DAMPING, 0, 16384 }, // Interval: [0,1] -      { "Master reverb width", FS_REVERB_WIDTH, 0, 16384 }, // Interval: [0,100] -      { "Master chorus on/off", FS_CHORUS_ON, 0, 1}, -      { "Master chorus num delay lines", FS_CHORUS_NUM, 0, 10 }, //Default: 3 -      { "Master chorus type",  FS_CHORUS_TYPE, 0, 1 }, -      { "Master chorus speed", FS_CHORUS_SPEED, 0, 16384 }, // (0.291,5) Hz -      { "Master chorus depth", FS_CHORUS_DEPTH, 0, 16384 }, // [0,40] -      { "Master chorus level", FS_CHORUS_LEVEL, 0, 16384 }, // [0,1] -      { "Modulation", CTRL_MODULATION, 0, 127 }, -      { "Portamento time", CTRL_PORTAMENTO_TIME, 0, 127 }, -      { "Volume", CTRL_VOLUME, 0, 127 }, -      { "Pan", CTRL_PANPOT, 0, 127 }, -      { "Expression", CTRL_EXPRESSION, 0, 127 }, -      { "Sustain", CTRL_SUSTAIN, 0, 127 }, -      { "Portamento", CTRL_PORTAMENTO, 0, 127 }, -      { "Soft Pedal", CTRL_SOFT_PEDAL, 0, 127 }, -      { "Variation", CTRL_VARIATION_SEND, 0, 127 }, -      { "Channel reverb send", CTRL_REVERB_SEND, 0, 127 }, -      { "Channel chorus send", CTRL_CHORUS_SEND, 0, 127 }, -      { "Pitch", CTRL_PITCH, -8192, 8191 } -    }; - -static int NUM_CONTROLLER = sizeof(FluidSynth::fluidCtrl)/sizeof(*(FluidSynth::fluidCtrl)); - -// -// Fluidsynth -// -FluidSynth::FluidSynth(int sr) : Mess(2) -      { -      setSampleRate(sr); -      fluid_settings_t* s = new_fluid_settings(); -      fluid_settings_setnum(s, "synth.sample-rate", float(sampleRate())); -      fluidsynth = new_fluid_synth(s); -      if (!fluidsynth) { -            printf("Error while creating fluidsynth!\n"); -            return; -            } - -      //Set up channels: -      for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { -            //channels[i].font       = 0; -            channels[i].font_extid = FS_UNSPECIFIED_ID; -            channels[i].font_intid = FS_UNSPECIFIED_ID; -            channels[i].preset     = FS_UNSPECIFIED_PRESET; -            channels[i].drumchannel= false; -      } -      pthread_mutex_init(&_sfloader_mutex,NULL); - -/* -      buffer = 0; -      bufferlen = 0; -      */ -      } - -FluidSynth::~FluidSynth() -      { -      /* -      int err = delete_fluid_synth (_fluidsynth); -      if (buffer) -               delete [] buffer; -      if (err == -1) { -            std::cerr << DEBUG_ARGS << "error while destroying synth: " << fluid_synth_error(_fluidsynth) << std::endl; -            return; -            } -      //Destroy the mutex -      if (pthread_mutex_destroy(&_sfloader_mutex) != 0) -            std::cerr << DEBUG_ARGS << "Strange, mutex busy! Should not be!" << std::endl; -            */ -      } - -bool FluidSynth::init(const char* name) -      { -      debug("FluidSynth::init\n"); - -      gui = new FluidSynthGui(); -      gui->show(); -      gui->setWindowTitle(name); - -      lastdir= ""; -      currentlyLoadedFonts = 0; -      nrOfSoundfonts = 0; -      sendChannelData(); -      cho_on = false; -      cho_num = FS_PREDEF_CHORUS_NUM; -      cho_type = FS_PREDEF_CHORUS_TYPE; -      cho_level = FS_PREDEF_CHORUS_LEVEL; -      cho_speed = FS_PREDEF_CHORUS_SPEED; -      cho_depth = FS_PREDEF_CHORUS_DEPTH; -      setController(0, FS_GAIN, (int)(fluidCtrl[0].max*FS_PREDEF_VOLUME)); -      setController(0, FS_REVERB_ON, 0); -      setController(0, FS_REVERB_LEVEL, (int)(fluidCtrl[2].max*FS_PREDEF_REVERB_LEVEL)); -      setController(0, FS_REVERB_ROOMSIZE, (int)(fluidCtrl[3].max*FS_PREDEF_REVERB_ROOMSIZE)); -      setController(0, FS_REVERB_DAMPING, (int)(fluidCtrl[4].max*FS_PREDEF_REVERB_DAMPING)); -      setController(0, FS_REVERB_WIDTH, (int)(fluidCtrl[5].max*FS_PREDEF_REVERB_WIDTH)); -      setController(0, FS_CHORUS_ON, 0); -      setController(0, FS_CHORUS_NUM, FS_PREDEF_CHORUS_NUM); -      //setController(0, FS_CHORUS_TYPE, FS_PREDEF_CHORUS_TYPE); //? -      setController(0, FS_CHORUS_SPEED, (int)(fluidCtrl[9].max*FS_PREDEF_CHORUS_SPEED)); -      setController(0, FS_CHORUS_DEPTH, (int)(fluidCtrl[10].max*FS_PREDEF_CHORUS_DEPTH)); -      setController(0, FS_CHORUS_LEVEL, (int)(fluidCtrl[11].max*FS_PREDEF_CHORUS_LEVEL)); -      return false; -      } - -//--------------------------------------------------------- -//   process -//    called from host -//--------------------------------------------------------- - -void FluidSynth::process(float** ports, int offset, int len) -      { -      //Process messages from the gui -      while (gui->fifoSize()) { -            MidiEvent ev = gui->readEvent(); -            if (ev.type() == ME_SYSEX) { -                  sysex(ev.len(), ev.data()); -                  sendEvent(ev); -                  } -            else if (ev.type() == ME_CONTROLLER) { -                  setController(ev.channel(), ev.dataA(), ev.dataB(), true); -                  sendEvent(ev); -                  } -            else { -                  if (FS_DEBUG) -                        printf("FluidSynth::process(): unknown event, type: %d\n", ev.type()); -                  } -            } - -      if (fluid_synth_write_float(fluidsynth, len, ports[0], offset, 1, ports[1], offset, 1)) { -            M_ERROR("Error writing from synth!"); -            return; -            } -      } - -//--------------------------------------------------------- -//   getInitData -// Prepare data that will restore the synth's state on load -//--------------------------------------------------------- -void FluidSynth::getInitData(int* n, const unsigned char** data) -      { -      // Data setup: -      // FS_INIT_DATA (1 byte) -      // FluidSynth version (2 bytes, x.y) -      // n = Number of soundfonts (1 byte) -      // Lastdir (variable size) -      // -      // FS_FONTS_BEGIN -      // n blocks with font path (variable size) -      // n bytes with font external id -      // -      // for all channels (16), 1 byte each for external id + 1 byte for preset + 1 byte for bankno -      // which is mapped to internal id after all fonts are loaded. -      // -      // reverb + chorus on/off (2 bytes) -      if (FS_DEBUG) -            printf("FluidSynth::getInitData()\n"); - -      //Calculate length: -      int len = FS_INIT_DATA_HEADER_SIZE + strlen(lastdir.c_str()) + 1; //header size -      for (std::list<FluidSoundFont>::const_iterator it = stack.begin(); it!=stack.end(); it++) { -            len+=strlen(it->filename.c_str()) + 2; -            } -      //Add length for lastdir and channels: -      len+=strlen(lastdir.c_str())+1; -      len+=(FS_MAX_NR_OF_CHANNELS*4); // 4 bytes: ext+int id + bankno + drumchannel status -      // + reverb -      len+=2; - -      if (FS_DEBUG) -            printf("Total length of init sysex: %d\n", len); -      byte* d = new byte[len]; - -      // Header: -      d[0] = FS_INIT_DATA; -      d[1] = FS_VERSION_MAJOR; -      d[2] = FS_VERSION_MINOR; -      d[3] = stack.size(); - -      //Lastdir: -      byte* chptr = d + FS_INIT_DATA_HEADER_SIZE; -      memcpy(chptr, lastdir.c_str(), strlen(lastdir.c_str())+1); - -      //For each font... -      chptr+=strlen(lastdir.c_str())+1; -      for (std::list<FluidSoundFont>::const_iterator it =stack.begin(); it!=stack.end(); it++) { -            memcpy(chptr, it->filename.c_str(), strlen(it->filename.c_str())+1); -            chptr = chptr + 1 + strlen(it->filename.c_str()); -            } - -      //For each font again... -      *chptr = FS_INIT_CHANNEL_SECTION; -      chptr++; -      for (std::list<FluidSoundFont>::const_iterator it =stack.begin(); it!=stack.end(); it++) { -            *chptr = it->extid; -            chptr++; -            } - -      //External id:s & preset for all channels: -      for(int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { -            *chptr = channels[i].font_extid; chptr++; -            *chptr = channels[i].preset; chptr++; -            *chptr = channels[i].banknum; chptr++; -            *chptr = channels[i].drumchannel; chptr++; -            } - -      //Reverb: -      *chptr = rev_on; chptr++; -      *chptr = cho_on; chptr++; -      if (FS_DEBUG) { -            for (int i=0; i<len; i++) -                  printf("%c ", d[i]); -            printf("\n"); -            for (int i=0; i<len; i++) -                  printf("%x ", d[i]); -            printf("\n"); -            } -      // Give values to host: -      *data = d; -      *n = len; -      } - -//----------------------------------- -// parseInitData -//----------------------------------- -void FluidSynth::parseInitData(int n, const byte* d) -      { -      bool load_drumchannels = true; // Introduced in initdata ver 0.3 -      bool handle_bankvalue  = true; // Introduced in initdata ver 0.4 - -      if (FS_DEBUG) { -            printf("--- PARSING INIT DATA ---\n"); -            for (int i=0; i<n; i++) -                  printf("%c ", d[i]); -            printf("\n"); -            } - -      byte version_major, version_minor; -      version_major = d[1]; version_minor = d[2]; - -      // 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)) { -            if (FS_DEBUG) { -                  printf("Project saved with other version of fluidsynth format. Ver: %d.%d\n", version_major, version_minor); -                  } - -            if (version_major == 0 && version_minor == 1) { -               sendError("Initialization data created with different version of FluidSynth Mess, will be ignored."); -               return; -               } - -            if (version_major == 0 && version_minor <= 2) { -                  load_drumchannels = false; -                  } - -            if (version_major == 0 && version_minor <= 3) { -                  handle_bankvalue = false; -                  } -            } - -      byte nr_of_fonts = d[3]; -      nrOfSoundfonts = nr_of_fonts; //"Global" counter -      const byte* chptr = (d + 4); - -      //Get lastdir: -      lastdir = std::string((char*)chptr); -      sendLastdir(lastdir.c_str()); - -      chptr+=strlen(lastdir.c_str())+1; - -      FluidSoundFont fonts[nrOfSoundfonts]; //Just a temp one -      //Fonts: -      for (int i=0; i<nr_of_fonts; i++) { -            fonts[i].filename = (char*)(chptr); -            chptr+=(strlen(fonts[i].filename.c_str())+1); -            } - -      if (*chptr != FS_INIT_CHANNEL_SECTION) { -            sendError("Init-data corrupt... Projectfile error. Initdata ignored.\n"); -            return; -            } - -      chptr++; -      for (int i=0; i<nr_of_fonts; i++) { -            fonts[i].extid = *chptr; -            chptr++; -            //printf("Extid, %d: %d\n",i,fonts[i].extid); -            } - -      // All channels external id + preset -      for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { -            channels[i].font_extid = *chptr; chptr++; -            channels[i].preset     = *chptr; chptr++; -            if (handle_bankvalue) { // Ver 0.4 and later -                  channels[i].banknum = *chptr; chptr++; -                  } -            else { -                  channels[i].banknum = 0; -                  } - -            if (load_drumchannels) { // Ver 0.3 and later -                  channels[i].drumchannel = *chptr; -                  chptr++; -                  } -            } - -      //Reverb: -      setController(0, FS_REVERB_ON, *chptr); chptr++; -      setController(0, FS_CHORUS_ON, *chptr); chptr++; - -      if (FS_DEBUG) -            printf("--- END PARSE INIT DATA ---\n"); -      //Load the shit: -      for (int i=0; i<nrOfSoundfonts; i++) { -            pushSoundfont(fonts[i].filename.c_str(), fonts[i].extid); -            } -      } - - -//--------------------------------------------------------- -//   processEvent -//    All events from the sequencer goes here -//--------------------------------------------------------- - -bool FluidSynth::processEvent(const MidiEvent& ev) -      { -      switch(ev.type()) { -            case ME_CONTROLLER: -                  if (FS_DEBUG_DATA) { -                        printf("*** FluidSynth::process - Controller. Chan: %x dataA: %x dataB: %x\n", ev.channel(), ev.dataA(), ev.dataB()); -                        for (int i=0; i< ev.len(); i++) -                              printf("%x ", ev.data()[i]); -                        } -                  setController(ev.channel(), ev.dataA(), ev.dataB(), false); -                  return true; -            case ME_NOTEON: -                  return playNote(ev.channel(), ev.dataA(), ev.dataB()); -            case ME_NOTEOFF: -                  return playNote(ev.channel(), ev.dataA(), 0); -            case ME_SYSEX: -                  //Debug print -                  if (FS_DEBUG_DATA) { -                        printf("*** FluidSynth::process - Sysex received\n"); -                        for (int i=0; i< ev.len(); i++) -                              printf("%x ", ev.data()[i]); -                        printf("\n"); -                        } -                  return sysex(ev.len(), ev.data()); -            } -      return false; -      } - -//--------------------------------------------------------- -//   sysex -//--------------------------------------------------------- - -bool FluidSynth::sysex(int n, const unsigned char* d) -      { -      if (n == 0 || d == 0) -            return false; -      switch(*d) { -            case FS_LASTDIR_CHANGE: { -                  lastdir = std::string((char*)(d+1)); -                  sendLastdir(lastdir.c_str()); -                  break; -                  } -            case FS_PUSH_FONT: { -                  int extid = d[1]; - -                  if (FS_DEBUG) -                        printf("Client: Got push font %s, id: %d\n",(d+1), extid); - -                  const char* filename = (const char*)(d+2); -                  if (!pushSoundfont(filename, extid)) -                              sendError("Could not load soundfont "); -                  break; -                  } -            case FS_DUMP_INFO: { -                  dumpInfo(); -                  break; -                  } -            case FS_SOUNDFONT_CHANNEL_SET: { -                  sfChannelChange(*(d+1), *(d+2)); -                  break; -                  } -            case FS_INIT_DATA: { -                  parseInitData(n,d); -                  break; -                  } -            case FS_SOUNDFONT_POP: -                  popSoundfont(*(d+1)); -                  break; -            case FS_DRUMCHANNEL_SET: { -                  byte onoff = (*(d+1)); -                  byte channel = (*(d+2)); -                  channels[channel].drumchannel = onoff; -                  if (FS_DEBUG) -                        printf("Client: Set drumchannel on chan %d to %d\n",channel, onoff); -                  break; -                  } -            default: -                  if (FS_DEBUG) -                        printf("FluidSynth::sysex() : unknown sysex received: %d\n",*d); -                  break; -            } -      return false; -      } - -//--------------------------------------------------------- -//   sendSysex -//--------------------------------------------------------- -void FluidSynth::sendSysex(int l, const unsigned char* d) -      { -      MidiEvent ev(0, ME_SYSEX, d, l); -      gui->writeEvent(ev); -      } - -//----------------------------------- -// pushSoundfont - load a soundfont -//----------------------------------- -bool FluidSynth::pushSoundfont (const char* filename, int extid) -      { -      pthread_attr_t* attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t)); -      pthread_attr_init(attributes); -      pthread_attr_setdetachstate(attributes, PTHREAD_CREATE_DETACHED); - -      FS_Helper* helper = new FS_Helper; -      helper->fptr = this; -      helper->filename = filename; -      helper->id = extid; - -      if (pthread_create(&fontThread, attributes, FluidSynth::fontLoadThread, (void*) helper)) -            perror("creating thread failed:"); - -      pthread_attr_destroy(attributes); -      return true; -      } - -//--------------------------------------------------------- -//   fontLoadThread -//    helper thread to load soundfont in the -//    background -//--------------------------------------------------------- - -void* FluidSynth::fontLoadThread(void* t) -      { -      //Init vars -      FS_Helper* h = (FS_Helper*) t; -      FluidSynth* fptr = h->fptr; -      const char* filename = h->filename.c_str(); -      pthread_mutex_t* sfloader_mutex = &(fptr->_sfloader_mutex); - -      //Let only one loadThread have access to the fluidsynth-object at the time -      pthread_mutex_lock(sfloader_mutex); -      int rv = fluid_synth_sfload(fptr->fluidsynth, filename, 1); - -      if (rv ==-1) { -            fptr->sendError(fluid_synth_error(fptr->fluidsynth)); -            if (FS_DEBUG) -                  std::cerr << DEBUG_ARGS << "error loading soundfont: " << fluid_synth_error(fptr->fluidsynth) << std::endl; - -            //Unlock the mutex, or else we might be stuck here forever... -            pthread_mutex_unlock(sfloader_mutex); -            delete h; -            pthread_exit(0); -            } - -      //Deal with internal and external id etc. -      if (FS_DEBUG) -            printf("Soundfont %s loaded, index %d\n", filename, rv); - -      FluidSoundFont font; -      font.filename = h->filename;//strdup(filename); - -      font.intid = rv; -      if (h->id == FS_UNSPECIFIED_ID) { -            font.extid = fptr->getNextAvailableExternalId(); -            if (FS_DEBUG) -                  printf("Font got extid %d\n",font.extid); -            } -      else -            font.extid = h->id; -      if (FS_DEBUG) -            printf("Font has external id: %d int id:%d\n", font.extid, font.intid); - -      //Strip off the filename -      QFileInfo fi(filename); -      font.name = fi.baseName().toLatin1().data(); -      fptr->stack.push_front(font); -      fptr->currentlyLoadedFonts++; - -      //Cleanup & unlock: -      pthread_mutex_unlock(sfloader_mutex); -      delete h; - -      if (FS_DEBUG) -            printf("Currently loaded fonts: %d Nr of soundfonts: %d\n",fptr->currentlyLoadedFonts, fptr->nrOfSoundfonts); -      //Check whether this was the last font or not. If so, run initSynth(); -      if (fptr->nrOfSoundfonts <= fptr->currentlyLoadedFonts) { -            if (FS_DEBUG) -                  printf("This was the last font, rewriting channel settings...\n"); -            fptr->rewriteChannelSettings(); -            //Update data in GUI-window. -            fptr->sendSoundFontData(); -            fptr->sendChannelData(); -            fptr->sendFontSuccessfullyLoaded(filename, font.extid); -            } - -      pthread_exit(0); -      } - -//--------------------------------------------------------- -//   playNote -//    called from host -//--------------------------------------------------------- - -bool FluidSynth::playNote(int channel, int pitch, int velo) -      { -      if (channels[channel].font_intid == FS_UNSPECIFIED_FONT) -            return false; -      if (velo) { -            if (fluid_synth_noteon(fluidsynth, channel, pitch, velo)) { -                  if (FS_DEBUG) -                        std::cerr << DEBUG_ARGS << "error processing noteon event: " << fluid_synth_error(fluidsynth); -                  } -            } -      else { -            if (fluid_synth_noteoff(fluidsynth, channel, pitch)) -                  if (FS_DEBUG) -                        std::cerr << DEBUG_ARGS << "error processing noteoff event: " << fluid_synth_error(fluidsynth) << std::endl; -            } -      return false; -      } - -//--------------------------------------------------------- -//   sendSoundFontData -//--------------------------------------------------------- -void FluidSynth::sendSoundFontData() -      { -      int ndatalen = 2; //2 bytes for command and length - -      //Calculate length in chars of all strings in the soundfontstack in one string -      for (std::list<FluidSoundFont>::iterator it = stack.begin(); it != stack.end(); it++) { -            ndatalen += 1 + strlen(it->name.c_str()); -            ndatalen += FS_SFDATALEN; //unsigned char for ID -            } -      byte ndata[ndatalen]; -      *ndata = FS_SEND_SOUNDFONTDATA; //The command -      *(ndata + 1) = (unsigned char)stack.size (); //Nr of Soundfonts - -      // Copy the stuff to ndatalen: -      char* chunk_start = (char*)(ndata + 2); -      int chunk_len, name_len; -      for (std::list<FluidSoundFont>::iterator it = stack.begin(); it != stack.end();  ++it) { -            name_len = strlen(it->name.c_str()) + 1; -            chunk_len = name_len + FS_SFDATALEN; -            memcpy(chunk_start, it->name.c_str(), name_len); //First, store the fontname -            *(chunk_start + name_len) = it->extid; //The GUI only needs to know about the external id, store that here -            chunk_start += chunk_len; -            } -      sendSysex(ndatalen, ndata); -      } - -//--------------------------------------------------------- -//   sendChannelData -//--------------------------------------------------------- -void FluidSynth::sendChannelData() -      { -      int chunk_size = 2; -      int chdata_length = (chunk_size * FS_MAX_NR_OF_CHANNELS) +1 ; //Command and the 2 channels * 16 -      byte chdata[chdata_length]; -      byte* chdptr; -      chdata[0] = FS_SEND_CHANNELINFO; -      chdptr = (chdata + 1); -      for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { -            *(chdptr)    = channels[i].font_extid; //Font external id -            *(chdptr+1)  = i; //Channel nr -            chdptr += chunk_size; -            } -      sendSysex(chdata_length, chdata); -      // Send drum channel info afterwards (later addition, not very neat, but works...) - -      int drumchdata_length = FS_MAX_NR_OF_CHANNELS + 1; //1 byte for the command, one byte for each channel -      byte drumchdata[drumchdata_length ]; -      byte* drumchdataptr = drumchdata; -      *drumchdata = FS_SEND_DRUMCHANNELINFO; - -      for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { -            drumchdataptr++; -            *drumchdataptr = channels[i].drumchannel; -            } -      sendSysex(drumchdata_length, drumchdata); -      } - -//--------------------------------------------------------- -//   dumpInfo -//--------------------------------------------------------- - -void FluidSynth::dumpInfo() -      { -      printf("-----------------------------------------------------\n"); -      printf("Dumping info...\n"); -      printf("Last dir: %s\n", lastdir.c_str()); -      for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) -            printf("Chan %d\tFont extid:%d\tintid:%d\tdrumchan:%d\tpreset: %d\n", i, channels[i].font_extid, channels[i].font_intid, channels[i].drumchannel, channels[i].preset); - -      printf("\n"); -      for (std::list<FluidSoundFont>::iterator it = stack.begin(); it != stack.end(); it++) -            printf("Font: %s\tintid: %d\textid %d\tfilename:%s\n", it->name.c_str(), it->intid, it->extid, it->filename.c_str()); -      printf("Reverb on: %d, width: %f, size: %f level: %f damp: %f\n",rev_on, rev_width, rev_size, rev_level, rev_damping); -      printf("-----------------------------------------------------\n"); -      } - -//--------------------------------------------------------- -//   guiVisible -//--------------------------------------------------------- - -bool FluidSynth::guiVisible() const -      { -      return gui->isVisible(); -      } - - -//--------------------------------------------------------- -//   showGui -//--------------------------------------------------------- - -void FluidSynth::showGui(bool val) -      { -      gui->setShown(val); -      } - -//--------------------------------------------------------- -//   setController -//--------------------------------------------------------- - -bool FluidSynth::setController(int channel, int id, int val) -      { -      setController(channel, id, val, false); -      return false; -      } - -//--------------------------------------------------------- -//   setController -//--------------------------------------------------------- - -void FluidSynth::setController(int channel, int id, int val, bool fromGui) -      { -      // -      // Channelless controllers -      // -      int err = 0; -      switch (id) { -            case FS_GAIN: { -                  fluid_synth_set_gain(fluidsynth, (float) val/25); //gives val an interval of approximately[0,5] -                  //Forward to gui if not from Gui -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_GAIN, val); -                        gui->writeEvent(ev); -                        } -                  break; -                  } -            case FS_REVERB_ON: { -                  rev_on = val; -                  fluid_synth_set_reverb_on(fluidsynth, val); // 0 or 1 -                  //if (rev_on) -                  //      fluid_synth_set_reverb(fluidsynth, rev_size, rev_damping, rev_width, rev_level); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_REVERB_ON, val); -                        gui->writeEvent(ev); -                        } -                  break; -                  } -            case FS_REVERB_LEVEL: -                  //Interval: 0-2 -                  rev_level = (double)2*val/16384; //[0,2] -                  //if (rev_on) -                        fluid_synth_set_reverb(fluidsynth, rev_size, rev_damping, rev_width, rev_level); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_REVERB_LEVEL, val); -                        gui->writeEvent(ev); -                        } -                  break; -            case FS_REVERB_WIDTH: // -                  rev_width = (double)val/164; //[0,100] -                  //if (rev_on) -                        fluid_synth_set_reverb(fluidsynth, rev_size, rev_damping, rev_width, rev_level); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_REVERB_WIDTH, val); -                        gui->writeEvent(ev); -                        } -                  break; -            case FS_REVERB_DAMPING: //[0,1] -                  rev_damping = (double)val/16384; -                  //if (rev_on) -                        fluid_synth_set_reverb(fluidsynth, rev_size, rev_damping, rev_width, rev_level); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_REVERB_DAMPING, val); -                        gui->writeEvent(ev); -                        } -                  break; -            case FS_REVERB_ROOMSIZE: //[0,1] -                  rev_size = (double)val/16384; -                  //if (rev_on) -                        fluid_synth_set_reverb(fluidsynth, rev_size, rev_damping, rev_width, rev_level); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_REVERB_ROOMSIZE, val); -                        gui->writeEvent(ev); -                        } -                  break; -            case FS_CHORUS_ON: {// 0 or 1 -                  cho_on = val; -                  fluid_synth_set_chorus_on(fluidsynth, val); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_CHORUS_ON, val); -                        gui->writeEvent(ev); -                        } -                  break; -                  } -            case FS_CHORUS_NUM: {//Number of delay lines -                  cho_num = val; -                  fluid_synth_set_chorus(fluidsynth, cho_num, cho_level, cho_speed, cho_depth, cho_type); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_CHORUS_NUM, val); -                        gui->writeEvent(ev); -                        } -                  break; -                  } -            case FS_CHORUS_TYPE: {//? -                  cho_type = val; -                  fluid_synth_set_chorus(fluidsynth, cho_num, cho_level, cho_speed, cho_depth, cho_type); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_CHORUS_TYPE, val); -                        gui->writeEvent(ev); -                        } -                  break; -                  } -            case FS_CHORUS_SPEED: {//(0.291,5) Hz -                  cho_speed = (double)(0.291 + (double)val/3479); -                  fluid_synth_set_chorus(fluidsynth, cho_num, cho_level, cho_speed, cho_depth, cho_type); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_CHORUS_SPEED, val); -                        gui->writeEvent(ev); -                        } -                  break; -                  } -            case FS_CHORUS_DEPTH: { //[0,40] -                  cho_depth = (double) val*40/16383; -                  fluid_synth_set_chorus(fluidsynth, cho_num, cho_level, cho_speed, cho_depth, cho_type); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_CHORUS_DEPTH, val); -                        gui->writeEvent(ev); -                        } -                  break; -                  } -            case FS_CHORUS_LEVEL: { //[0,1] -                  cho_level = (double) val/16383; -                  fluid_synth_set_chorus(fluidsynth, cho_num, cho_level, cho_speed, cho_depth, cho_type); -                  if (!fromGui) { -                        MidiEvent ev(0, 0, ME_CONTROLLER, FS_CHORUS_LEVEL, val); -                        gui->writeEvent(ev); -                        } -                  break; -                  } -            // -            // Controllers that depend on channels -            // -            case CTRL_PITCH: -                  err = fluid_synth_pitch_bend (fluidsynth, channel, val); -                        break; -            case CTRL_PROGRAM: { -                  //Check if MusE is trying to set a preset on an unspecified font. If so, ignore. -                  if (FS_DEBUG) -                        printf("Program select : channel %d val %d\n",channel, val); -                  byte font_intid = channels[channel].font_intid; - -                  if (font_intid == FS_UNSPECIFIED_ID || font_intid == FS_UNSPECIFIED_FONT) -                        return; - -                  byte banknum = ((val >> 16) & 0xff); -                  byte patch = (val & 0xff); -                  //printf("val: %d banknum: %x patch: %d\n", val, banknum, patch); - -                  err = fluid_synth_program_select(fluidsynth, channel, font_intid , banknum, patch); -                  if (err) -                        printf("FluidSynth::setController() - Error changing program on soundfont %s, channel: %d\n", fluid_synth_error(fluidsynth), channel); -                  else { -                        channels[channel].preset = val;//setChannelPreset(val, channel); -                        channels[channel].banknum = banknum; -                        } -                  break; -                  } -            default: -                  if (FS_DEBUG) -                        printf("Setting controller on channel: %d with id: 0x%x to val: %d\n",channel, id, val); -                  err = fluid_synth_cc(fluidsynth, channel, id, val); -                  break; -            } - -      if (err) -            printf ("FluidSynth::setController() - error processing controller event: %s\n", fluid_synth_error(fluidsynth)); -      } - -//--------------------------------------------------------- -//   getControllerInfo -//--------------------------------------------------------- -int FluidSynth::getControllerInfo(int id, const char** name, int* controller, int* min, int* max) -      { -      if (id >= NUM_CONTROLLER) -            return 0; -      *controller = fluidCtrl[id].num; -      *name       = fluidCtrl[id].name; -      *min        = fluidCtrl[id].min; -      *max        = fluidCtrl[id].max; -      if (FS_DEBUG) -            printf("FluidSynth::getControllerInfo() id: %d name: %s controller: %d min: %d max: %d\n",id,*name,*controller,*min,*max); -      return ++id; -      } - -//--------------------------------------------------------- -//   sendError -//--------------------------------------------------------- -void FluidSynth::sendError(const char *errorMessage) -      { -      int len = 2 + strlen(errorMessage); -      unsigned char data[len]; -      *data = FS_ERROR; -      memcpy(data + 1, errorMessage, len - 1); -      sendSysex(len, data); -      } - -//--------------------------------------------------------- -//   getNextAvailableExternalId -//--------------------------------------------------------- - -int FluidSynth::getNextAvailableExternalId() -      { -      unsigned char place[FS_MAX_NR_OF_CHANNELS]; -      for(int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) -            place[i] = 0; -      for (std::list<FluidSoundFont>::iterator it = stack.begin(); it != stack.end(); it++) -            place[it->extid] = 1; - -      int i=0; -      while (i < FS_MAX_NR_OF_CHANNELS && place[i] == 1) -            i++; - -      return i; -      } - -//--------------------------------------------------------- -//   sfChannelChange -//--------------------------------------------------------- - -void FluidSynth::sfChannelChange(byte extid, byte channel) -      { -      if (FS_DEBUG) -            printf("FluidSynth::sfChannelChange()-Setting channel %d to font with extid %d intid %d\n",channel, extid, getFontInternalIdByExtId(extid)); -      channels[channel].font_extid = extid; -      channels[channel].font_intid = getFontInternalIdByExtId(extid); -      } - -//--------------------------------------------------------- -//   getFontInternalIdByExtId -//--------------------------------------------------------- -byte FluidSynth::getFontInternalIdByExtId(byte ext_id) -      { -      for (std::list<FluidSoundFont>::iterator it = stack.begin(); it !=stack.end(); it++) { -            if (it->extid == ext_id) -                  return it->intid; -            } -      return FS_UNSPECIFIED_FONT; -      } - -//--------------------------------------------------------- -//   sendLastDir -//--------------------------------------------------------- -void FluidSynth::sendLastdir(const char* lastdir) -      { -      int n = strlen(lastdir) + 2; -      byte d[n]; -      d[0] = FS_LASTDIR_CHANGE; -      memcpy(d+1,lastdir, strlen(lastdir)+1); - -      MidiEvent ev(0, ME_SYSEX, d, n); -      gui->writeEvent(ev); -      } - -//--------------------------------------------------------- -//   sendLastDir -//--------------------------------------------------------- -void FluidSynth::sendFontSuccessfullyLoaded(const char* filename, byte extid) -      { -      // extid first, then filename: -      int n = strlen(filename) + 3; -      byte d[n]; -      d[0] = FS_FONT_SUCCESSFULLY_LOADED; -      d[1] = extid; -      memcpy(d+2, filename, strlen(filename)+1); -      MidiEvent ev(0, ME_SYSEX, d, n); -      gui->writeEvent(ev); -      } -//--------------------------------------------------------- -//   rewriteChannelSettings -//--------------------------------------------------------- -void FluidSynth::rewriteChannelSettings() -      { -      //Walk through the channels, remap internal ID:s to external ID:s (something that actually only needs to be done at -      //startup, since the fonts aren't loaded yet at that time and it isn't possible to give them a correct internal id -      //since they don't have any at that time, this can probably be fixed in a smarter way (but it works..)) -      for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { -            int ext_id = channels[i].font_extid;//getFontExternalIdByChannel(i); -            if (ext_id != FS_UNSPECIFIED_ID) //Check if ext_id is set to any sane font -                  { -                  channels[i].font_intid = getFontInternalIdByExtId(ext_id);//(getFontInternalIdByExtId(ext_id));//if so, get value from the stack -                  } -            else -                  channels[i].font_intid = FS_UNSPECIFIED_FONT; //if not, set it to unspecified -            } - -      //Assign correct presets to all channels -      for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { -            int preset = channels[i].preset; -            int int_id = channels[i].font_intid; -            byte banknum = channels[i].banknum; - -            if (channels[i].drumchannel) -                  banknum = 128; - -            //printf("Channel %d, font int-id %d ext_id %d, preset %d\n",i, int_id, getFontExternalIdByChannel(i), preset); -            if (!(preset == FS_UNSPECIFIED_PRESET || int_id == FS_UNSPECIFIED_FONT)) { -                  int rv = fluid_synth_program_select(fluidsynth, i, int_id, banknum, preset); -                  if (rv) -                        std::cerr << DEBUG_ARGS << "Error changing preset! " << fluid_synth_error(fluidsynth) << std::endl; -                  } -            } -      } - -//--------------------------------------------------------- -//   getPatchName -//--------------------------------------------------------- -const char* FluidSynth::getPatchName(int i, int, int) const -      { -      if (channels[i].font_intid == FS_UNSPECIFIED_FONT) -            return "no preset"; -      else if (channels[i].preset == FS_UNSPECIFIED_PRESET) -            return "no preset"; -      else { -            //printf("Getpatchname, channel: %d\n",channel); -            fluid_preset_t *preset = fluid_synth_get_channel_preset(fluidsynth, i); -            if (!preset) return "no preset"; -            return preset->get_name(preset); -            } -      } - -//--------------------------------------------------------- -//   getPatchInfo -//--------------------------------------------------------- -const MidiPatch* FluidSynth::getPatchInfo(int i, const MidiPatch* patch) const -      { -      if (channels[i].font_intid == FS_UNSPECIFIED_FONT) -            return 0; -      //else if (channels[i].preset == FS_UNSPECIFIED_PRESET) -      //      return 0; -      else { -            //printf("Getpatchname, channel: %d\n",channel); -            if (!patch) -                  //Deliver first patch -                  return getFirstPatch(i); -            else -                  //Deliver next patch -                  return getNextPatch(i, patch); -            } -      } - -//--------------------------------------------------------- -//   getFirstPatch -//--------------------------------------------------------- -const MidiPatch* FluidSynth::getFirstPatch (int channel) const -      { -      static MidiPatch midiPatch; - -      midiPatch.typ = 0; -      midiPatch.lbank = 0; - -      fluid_preset_t* preset; -      int font_id = channels[channel].font_intid; -      if (font_id == FS_UNSPECIFIED_FONT) -            return 0; - -      fluid_sfont_t* sfont = fluid_synth_get_sfont_by_id(fluidsynth, font_id); - -      if (!channels[channel].drumchannel) { -            for (unsigned bank = 0; bank < 128; ++bank) { -                  for (unsigned patch = 0; patch < 128; ++patch) { -                        preset = sfont->get_preset (sfont, bank, patch); -                        if (preset) { -                              midiPatch.hbank = bank; -                              midiPatch.prog = patch; -                              midiPatch.name = preset->get_name (preset); -                              return &midiPatch; -                              } -                        } -                  } -            return 0; -            } -      else { //This is a drumchannel -            int bank = 128; -            for (unsigned patch = 0; patch < 128; ++patch) { -                  preset = sfont->get_preset (sfont, bank, patch); -                  if (preset) { -                        midiPatch.hbank = bank; -                        midiPatch.prog = patch; -                        midiPatch.name = preset->get_name(preset); -                        return &midiPatch; -                        } -                  } -            } -      return 0; -      } - -//--------------------------------------------------------- -//   getNextPatch -//--------------------------------------------------------- -const MidiPatch* FluidSynth::getNextPatch (int channel, const MidiPatch* patch) const -      { -      static MidiPatch midiPatch; -      //First check if there actually is any soundfont associated to the channel. If not, don't bother -      int font_id = channels[channel].font_intid; -      if (font_id == FS_UNSPECIFIED_FONT) -            return 0; -      if (patch == 0) -            return getFirstPatch(channel); - -      midiPatch.typ = 0; -      midiPatch.lbank = 0; - -      if (font_id == FS_UNSPECIFIED_FONT) -            return 0; -      //printf("Font has internal id: %d\n",font_id); -      fluid_preset_t* preset; -      fluid_sfont_t* sfont = fluid_synth_get_sfont_by_id(fluidsynth, font_id); - -      if (!channels[channel].drumchannel) { -            unsigned prog = patch->prog + 1; - -            for (unsigned bank = patch->hbank; bank < 128; ++bank) { -                  for ( ; prog < 128; ++prog) { -                        preset = sfont->get_preset (sfont, bank, prog); -                        if (preset) { -                              //printf("Preset info: bank: %d prog: %d name: %s\n", bank, prog, preset->get_name(preset)); -                              midiPatch.hbank = bank; -                              midiPatch.prog = prog; -                              midiPatch.name = preset->get_name (preset); -                              return &midiPatch; -                              } -                        } -                        prog = 0; // Reset if we "come around" -                  } -            } -      else { //This is a drum channel -            unsigned bank = 128; -            unsigned prog = patch->prog; -            for (prog = patch->prog + 1; prog < 128; ++prog) { -                  preset = sfont->get_preset (sfont, bank, prog); -                  if (preset) { -                        //printf("Preset info: bank: %d prog: %d name: %s\n",bank, prog, preset->get_name(preset)); -                        midiPatch.hbank = bank; -                        midiPatch.prog = prog; -                        midiPatch.name = preset->get_name (preset); -                        return &midiPatch; -                        } -                  } -            } -      return 0; -      } - -//--------------------------------------------------------- -//   popSoundfont -//--------------------------------------------------------- - -bool FluidSynth::popSoundfont (int ext_id) -      { -         bool success = false; -         int int_id = getFontInternalIdByExtId(ext_id); - -         if (int_id == FS_UNSPECIFIED_FONT) { -               std::cerr << DEBUG_ARGS << "Internal error! Request for deletion of Soundfont that is not registered!" << std::endl; -               } -         else -         { -         //Try to unload soundfont -         int err = fluid_synth_sfunload(fluidsynth, int_id, 0); -         if (err != -1) {//Success -               //Check all channels that the font is used in -               for (int i=0; i<FS_MAX_NR_OF_CHANNELS;  i++) { -                     //Set them to unspecified and reset preset settings -                     if (channels[i].font_intid == int_id) { -                           channels[i].font_intid = FS_UNSPECIFIED_ID; -                           channels[i].font_extid = FS_UNSPECIFIED_ID; -                           channels[i].preset = FS_UNSPECIFIED_PRESET; -                           } -                     } -               //Remove it from soundfont stack -               for (std::list<FluidSoundFont>::iterator it =stack.begin(); it !=stack.end(); it++) { -                     if (it->intid == int_id) { -                           stack.erase(it); -                           break; -                           } -                     } -               //Resend fontdata & re-initialize -               sendSoundFontData(); -               sendChannelData(); -               rewriteChannelSettings(); -               success = true; -               currentlyLoadedFonts--; -            } -         else //OK, there was trouble -               std::cerr << DEBUG_ARGS << "Error unloading soundfont!" << fluid_synth_error(fluidsynth) << std::endl; -      } -      if (FS_DEBUG) -            printf("Removed soundfont with ext it: %d\n",ext_id); -      return success; -      } - -//--------------------------------------------------------- -//   instantiate -//    construct a new synthesizer instance -//--------------------------------------------------------- - -class QWidget; - -static Mess* instantiate(int sr, const char* name) -      { -      printf("fluidsynth sampleRate %d\n", sr); -      FluidSynth* synth = new FluidSynth(sr); -      if (synth->init(name)) { -            delete synth; -            synth = 0; -            } -      return synth; -      } - -extern "C" -      { -      static MESS descriptor = { -            "FluidSynth", -            "Mathias Lundgren (lunar_shuttle@users.sf.net)", -            "0.1",      //Version string -            MESS_MAJOR_VERSION, MESS_MINOR_VERSION, -            instantiate, -            }; -      const MESS* mess_descriptor() { return &descriptor; } -      } -  | 
