diff options
Diffstat (limited to 'muse2/synti/fluidsynth/fluidsynthgui.cpp')
-rw-r--r-- | muse2/synti/fluidsynth/fluidsynthgui.cpp | 819 |
1 files changed, 819 insertions, 0 deletions
diff --git a/muse2/synti/fluidsynth/fluidsynthgui.cpp b/muse2/synti/fluidsynth/fluidsynthgui.cpp new file mode 100644 index 00000000..bdb0719b --- /dev/null +++ b/muse2/synti/fluidsynth/fluidsynthgui.cpp @@ -0,0 +1,819 @@ +/* + * MusE FLUID Synth softsynth plugin + * + * Copyright (C) 2004 Mathias Lundgren (lunar_shuttle@users.sourcforge.net) + * + * $Id: fluidsynthgui.cpp,v 1.13.2.2 2009/08/12 20:47:01 spamatica Exp $ + * + */ + +#include "fluidsynthgui.h" +#include "fluidsynti.h" +#include <qpushbutton.h> + +#include <iostream> +#include <qlineedit.h> +#include <q3filedialog.h> +#include <qsocketnotifier.h> +#include <qpixmap.h> +#include <q3listview.h> +#include <qslider.h> +#include <qmessagebox.h> +#include <q3popupmenu.h> +#include <q3header.h> +#include <qcheckbox.h> +#include <qspinbox.h> +#include <qcombobox.h> + +#include "muse/midi.h" +#include "xpm/buttondown.xpm" + + + /* +#include "muse/debug.h" +#include <iomanip> +#include <qtooltip.h> +#include <qapplication.h> +#include <qlistbox.h> +#define MUSE_FLUID_DEBUG false +*/ + +FluidSynthGui::FluidSynthGui() + : MessGui() + { + //Connect socketnotifier to fifo + QSocketNotifier* s = new QSocketNotifier(readFd, QSocketNotifier::Read); + connect(s, SIGNAL(activated(int)), SLOT(readMessage(int))); + connect (Push, SIGNAL (clicked()), SLOT(loadClicked())); + + lastdir = ""; + + channelListView->setColumnWidthMode(FS_CHANNEL_COL,Q3ListView::Maximum); + channelListView->setColumnWidthMode(FS_SF_ID_COL,Q3ListView::Maximum); + ReverbFrame->setEnabled(true); + ChorusFrame->setEnabled(true); + + if (!FS_DEBUG) + dumpInfoButton->hide(); + + //Init reverb sliders: + /*ReverbRoomSize->setValue((int)(16383*FS_PREDEF_REVERB_ROOMSIZE)); + ReverbDamping->setValue((int)(16383*FS_PREDEF_REVERB_DAMPING)); + ReverbWidth->setValue((int)(16383*FS_PREDEF_REVERB_WIDTH));*/ + + connect(Gain, SIGNAL(valueChanged(int)), SLOT(changeGain(int))); + connect(dumpInfoButton , SIGNAL(clicked()), SLOT(dumpInfo())); + connect(channelListView, SIGNAL(pressed(Q3ListViewItem*,const QPoint&,int)), + this, SLOT(channelItemClicked(Q3ListViewItem*,const QPoint&,int))); + + connect(Reverb, SIGNAL (toggled(bool)), SLOT(toggleReverb(bool))); + connect(ReverbLevel, SIGNAL (valueChanged (int)), SLOT(changeReverbLevel(int))); + connect(ReverbRoomSize, SIGNAL (valueChanged (int)), SLOT(changeReverbRoomSize(int))); + connect(ReverbDamping, SIGNAL (valueChanged (int)), SLOT(changeReverbDamping(int))); + connect(ReverbWidth, SIGNAL (valueChanged (int)), SLOT(changeReverbWidth(int))); + + connect (Pop, SIGNAL (clicked()), SLOT(popClicked())); + connect(sfListView, SIGNAL(pressed(Q3ListViewItem*,const QPoint&,int)), + this, SLOT(sfItemClicked(Q3ListViewItem*,const QPoint&,int))); + connect(Chorus, SIGNAL (toggled (bool)), SLOT(toggleChorus (bool))); + connect(ChorusNumber, SIGNAL (valueChanged (int)), SLOT(changeChorusNumber (int))); + connect(ChorusType, SIGNAL (activated (int)), SLOT(changeChorusType (int))); + connect(ChorusSpeed, SIGNAL (valueChanged (int)), SLOT(changeChorusSpeed (int))); + connect(ChorusDepth, SIGNAL (valueChanged (int)), SLOT(changeChorusDepth (int))); + connect(ChorusLevel, SIGNAL (valueChanged (int)), SLOT(changeChorusLevel (int))); +/* + _notifier = new QSocketNotifier(0, QSocketNotifier::Read); + connect(_notifier, SIGNAL(activated(int)), SLOT(readData(int))); + + //Setup the ListView + sfListView->setColumnWidthMode(MUSE_FLUID_ID_COL,QListView::Maximum); + sfListView->setColumnWidthMode(MUSE_FLUID_SFNAME_COL,QListView::Maximum); + + sfListView->setColumnAlignment(MUSE_FLUID_ID_COL,AlignHCenter); + sfListView->setSorting(MUSE_FLUID_ID_COL,true); + channelListView->setColumnAlignment(MUSE_FLUID_CHANNEL_COL,AlignHCenter); + + _currentlySelectedFont = -1; //No selected font to start with + // The GUI-process is killed every time the window is shut, + // need to get all parameters from the synth + + requestAllParameters(); + + */ + + //Clear channels + for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) + channels[i] = FS_UNSPECIFIED_ID; + + // work around for probable QT/WM interaction bug. + // for certain window managers, e.g xfce, this window is + // is displayed although not specifically set to show(); + // bug: 2811156 Softsynth GUI unclosable with XFCE4 (and a few others) + show(); + hide(); + } + +FluidSynthGui::~FluidSynthGui() + { + /* + delete _notifier; + */ + } + +void FluidSynthGui::toggleReverb(bool on) { sendController(0, FS_REVERB_ON, on); } +void FluidSynthGui::changeReverbLevel(int val) { sendController(0, FS_REVERB_LEVEL, val); } +void FluidSynthGui::changeReverbRoomSize(int val) { sendController(0, FS_REVERB_ROOMSIZE, val); } +void FluidSynthGui::changeReverbWidth(int val) { sendController(0, FS_REVERB_WIDTH, val); } +void FluidSynthGui::changeReverbDamping(int val) { sendController(0, FS_REVERB_DAMPING, val); } + +void FluidSynthGui::toggleChorus(bool val) { sendController(0, FS_CHORUS_ON, val); } +void FluidSynthGui::changeChorusNumber(int val) { sendController(0, FS_CHORUS_NUM, val); } +void FluidSynthGui::changeChorusType(int val) { sendController(0, FS_CHORUS_TYPE, val); } +void FluidSynthGui::changeChorusSpeed(int val) { sendController(0, FS_CHORUS_SPEED, val); } +void FluidSynthGui::changeChorusDepth(int val) { sendController(0, FS_CHORUS_DEPTH, val); } +void FluidSynthGui::changeChorusLevel(int val) { sendController(0, FS_CHORUS_LEVEL, val); } + + /* + +void FluidSynthGui::pushClicked() + { + const QString& fns = Filename->text(); + if (fns.isEmpty()) + return; + const char * fn = fns.latin1(); + + int datalen = strlen(fn) + 3; + unsigned char data [datalen]; + data[0] = MUSE_FLUID_SOUNDFONT_PUSH; + data[1] = MUSE_FLUID_UNSPECIFIED_ID; //This makes the client choose next available external id + memcpy(data + 2, fn, strlen(fn) + 1 ); //Store filename + sendSysex(data, datalen); + data[0] = MUSE_FLUID_GUI_REQ_SOUNDFONTS; //For simplicity's sake, just get all the soundfont data again. + sendSysex(data, 1); + printf("Gui sent Sysex.\n"); + + return; + } + */ + +void FluidSynthGui::loadClicked() + { + QString filename = Q3FileDialog::getOpenFileName(lastdir, QString("*.[Ss][Ff]2"), + this, + "Load Soundfont dialog", + "Choose soundfont"); + if (filename != QString::null) { + int lastslash = filename.findRev('/'); + lastdir = filename.left(lastslash); + + sendLastdir(lastdir); + sendLoadFont(filename); + } + } + +//--------------------------------------------------------- +// sendLastdir +// Send the last dir-value to the client +//--------------------------------------------------------- + +void FluidSynthGui::sendLastdir(QString dir) + { + int l = strlen(dir)+2; + byte data[l]; + data[0] = FS_LASTDIR_CHANGE; + memcpy(data+1, dir.latin1(), strlen(dir)+1); + sendSysex(data,l); + } + +//--------------------------------------------------------- +// sendLoadFont +// Tell the client to load a font with first available id +//--------------------------------------------------------- + +void FluidSynthGui::sendLoadFont(QString filename) + { + int l = filename.length()+3; + byte data[l]; + data[0] = FS_PUSH_FONT; + data[1] = FS_UNSPECIFIED_ID; + memcpy(data+2, filename.latin1(), filename.length()+1); + sendSysex(data,l); + } + +//--------------------------------------------------------- +// processEvent +//--------------------------------------------------------- + +void FluidSynthGui::processEvent(const MidiPlayEvent& ev) + { + //Sysexes sent from the client + if (ev.type() == ME_SYSEX) { + byte* data = ev.data(); + switch (*data) { + case FS_LASTDIR_CHANGE: + lastdir = QString((const char*)data+1); + break; + case FS_ERROR: { + char* msg = (char*) (data+1); + + printf("Muse: fluidsynth error: %s\n", msg); + + break; + } + case FS_SEND_SOUNDFONTDATA: { + int chunk_len; + int filename_len; + + int count = (int)*(data+1); //Number of elements + byte* cp = data+2; //Point to beginning of first chunk + sfListView->clear(); //Clear the listview + stack.clear(); //Clear the stack since we're starting over again + + while (count) { + FluidGuiSoundFont font; + filename_len = strlen((const char*)cp) + 1; + font.name = (const char*)cp; + font.id = *(cp + filename_len); + chunk_len = filename_len + FS_SFDATALEN; + stack.push_front(font); + cp += chunk_len; //Move to next chunk + count--; + } + updateSoundfontListView(); + updateChannelListView(); + break; + } + case FS_SEND_CHANNELINFO: { + byte* chptr = (data+1); + for (int i=0; i< FS_MAX_NR_OF_CHANNELS; i++) { + byte id = *chptr; + byte channel = *(chptr+1); + channels[channel] = id; + chptr+=2; + } + updateChannelListView(); + + break; + } + case FS_SEND_DRUMCHANNELINFO: { + byte* drumchptr = (data+1); + for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { + drumchannels[i] = *drumchptr; + drumchptr++; + } + updateChannelListView(); + break; + } + default: + if (FS_DEBUG) + printf("FluidSynthGui::processEvent() : Unknown Sysex received: %d\n", ev.type()); + break; + } + } + //Controllers sent from the client: + else + if(ev.type() == ME_CONTROLLER) { + int id = ev.dataA(); + int val = ev.dataB(); + switch (id) { + case FS_GAIN: { + bool sb = Gain->signalsBlocked(); + Gain->blockSignals(true); + // Update Gain-slider without causing it to respond to it's own signal (and send another msg to the synth) + Gain->setValue(val); + Gain->blockSignals(sb); + break; + } + case FS_REVERB_ON: { + bool sb = Reverb->signalsBlocked(); + Reverb->blockSignals(true); + Reverb->setChecked(val); + Reverb->blockSignals(sb); + break; + } + case FS_REVERB_LEVEL: { + bool sb = ReverbLevel->signalsBlocked(); + ReverbLevel->blockSignals(true); + ReverbLevel->setValue(val); + ReverbLevel->blockSignals(sb); + break; + } + case FS_REVERB_DAMPING: { + bool sb = ReverbDamping->signalsBlocked(); + ReverbDamping->blockSignals(true); + ReverbDamping->setValue(val); + ReverbDamping->blockSignals(sb); + break; + } + case FS_REVERB_ROOMSIZE: { + bool sb = ReverbRoomSize->signalsBlocked(); + ReverbRoomSize->blockSignals(true); + ReverbRoomSize->setValue(val); + ReverbRoomSize->blockSignals(sb); + break; + } + case FS_REVERB_WIDTH: { + bool sb = ReverbWidth->signalsBlocked(); + ReverbWidth->blockSignals(true); + ReverbWidth->setValue(val); + ReverbWidth->blockSignals(sb); + break; + } + case FS_CHORUS_ON: { + Chorus->blockSignals(true); + Chorus->setChecked(val); + Chorus->blockSignals(false); + break; + } + case FS_CHORUS_SPEED: { + ChorusSpeed->blockSignals(true); + ChorusSpeed->setValue(val); + ChorusSpeed->blockSignals(false); + break; + } + case FS_CHORUS_NUM: { + ChorusNumber->blockSignals(true); + ChorusNumber->setValue(val); + ChorusNumber->blockSignals(false); + break; + } + case FS_CHORUS_TYPE: { + ChorusType->blockSignals(true); + ChorusType->setCurrentItem(val); + ChorusType->blockSignals(false); + break; + } + case FS_CHORUS_DEPTH: { + ChorusDepth->blockSignals(true); + ChorusDepth->setValue(val); + ChorusDepth->blockSignals(false); + break; + } + case FS_CHORUS_LEVEL: { + ChorusLevel->blockSignals(true); + ChorusLevel->setValue(val); + ChorusLevel->blockSignals(false); + break; + } + default: + if (FS_DEBUG) + printf("FluidSynthGui::processEvent() : Unknown controller sent to gui: %x\n",id); + break; + } + } + else + if (FS_DEBUG) + printf("FluidSynthGui::processEvent - unknown event of type %dreceived from synth.\n", ev.type()); + } + +//--------------------------------------------------------- +// readMessage +//--------------------------------------------------------- +void FluidSynthGui::readMessage(int) + { + MessGui::readMessage(); + } + +//--------------------------------------------------------- +// updateChannels +//--------------------------------------------------------- +void FluidSynthGui::updateChannelListView() + { + if (FS_DEBUG) + printf("FluidSynthGui::updateChannelListView\n"); + channelListView->clear(); + for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { + QString chanstr, sfidstr, drumchanstr; + + //Soundfont id string: + if (channels[i] == FS_UNSPECIFIED_ID) + sfidstr = "unspecified"; + else + sfidstr = getSoundFontName(channels[i]); + //Channel string: + chanstr = QString::number(i+1); + if (chanstr.length()==1) + chanstr = "0" + chanstr; + + //Drumchan string: + if (drumchannels[i]) + drumchanstr = "Yes"; + else + drumchanstr = "No"; + Q3ListViewItem* qlvNewItem = new Q3ListViewItem(channelListView); + qlvNewItem->setText(FS_CHANNEL_COL, chanstr); + qlvNewItem->setPixmap(FS_SF_ID_COL, buttondown_xpm); + qlvNewItem->setText(FS_SF_ID_COL, sfidstr); + qlvNewItem->setPixmap(FS_DRUM_CHANNEL_COL, buttondown_xpm); + qlvNewItem->setText(FS_DRUM_CHANNEL_COL, drumchanstr); + channelListView->insertItem(qlvNewItem); + } + } + +//--------------------------------------------------------- +// updateSoundfontListView +//--------------------------------------------------------- +void FluidSynthGui::updateSoundfontListView() + { + sfListView->clear(); //Clear the listview + for (std::list<FluidGuiSoundFont>::iterator it = stack.begin(); it != stack.end(); it++) { + Q3ListViewItem* qlvNewItem = new Q3ListViewItem(sfListView); + QString qsid = QString("%1").arg(it->id); + qlvNewItem->setText(FS_ID_COL, qsid); + qlvNewItem->setText(FS_SFNAME_COL, QString(it->name)); + sfListView->insertItem(qlvNewItem); + } + sfListView->sort(); + } + +//--------------------------------------------------------- +// changeGain +//--------------------------------------------------------- +void FluidSynthGui::changeGain(int value) + { + sendController(0, FS_GAIN, value); + } + + +//--------------------------------------------------------- +// dumpInfoButton +//--------------------------------------------------------- +void FluidSynthGui::dumpInfo() + { + byte data[1]; + data[0] = FS_DUMP_INFO; + sendSysex(data, 1); + } + +//--------------------------------------------------------- +// getSoundFontName +//--------------------------------------------------------- + +QString FluidSynthGui::getSoundFontName(int id) + { + QString name = NULL; + for (std::list<FluidGuiSoundFont>::iterator it = stack.begin(); it != stack.end(); it++) { + if (id == it->id) { + name = it->name; + continue; + } + } + return name; + } + +//--------------------------------------------------------- +// channelItemClicked +// change channel parameters like soundfont / drumchannel on/off +//--------------------------------------------------------- + +void FluidSynthGui::channelItemClicked(Q3ListViewItem* item, const QPoint&, int col) + { + if (col == FS_SF_ID_COL) { + Q3PopupMenu* popup = new Q3PopupMenu(this); + QPoint ppt = channelListView->itemRect(item).bottomLeft(); + Q3ListView* listView = item->listView(); + ppt += QPoint(listView->header()->sectionPos(col), listView->header()->height()); + ppt = listView->mapToGlobal(ppt); + + int i = 0; + for (std::list<FluidGuiSoundFont>::reverse_iterator it = stack.rbegin(); it != stack.rend(); it++) { + i++; + /*byte* d = (byte*) it->name.latin1(); + for (int i=0; i<96; i++) { + if (i%16 == 0) + printf("%x:",(i+d)); + + printf("%x ",*(d-48+i)); + + if (i%16 == 15) + printf("\n"); + } + for (int i=0; i<96; i++) { + if (i%16 == 0) + printf("%x:",(i+d-48)); + + printf("%c ",*(d-48+i)); + + if (i%16 == 15) + printf("\n"); + } + printf("\n\n");*/ + popup->insertItem(it->name,i); + } + int lastindex = i+1; + popup->insertItem("unspecified",lastindex); + int index = popup->exec(ppt, 0); + if (index !=-1) { + byte sfid; + QString fontname; + if (index == lastindex) { + sfid = FS_UNSPECIFIED_ID; + fontname = "unspecified"; //Actually, it's not possible to reset fluid-channels as for now, + } //so this is just a dummy that makes the synth block any events for the channel + else { + sfid = getSoundFontId(popup->text(index)); + fontname = getSoundFontName(sfid); + } + byte channel = atoi(item->text(FS_CHANNEL_COL).latin1()) - 1; + sendChannelChange(sfid, channel); + item->setText(FS_SF_ID_COL, fontname); + } + delete popup; + } + // Drumchannel column: + else if (col == FS_DRUM_CHANNEL_COL) { + Q3PopupMenu* popup = new Q3PopupMenu(this); + QPoint ppt = channelListView->itemRect(item).bottomLeft(); + Q3ListView* listView = item->listView(); + ppt += QPoint(listView->header()->sectionPos(col), listView->header()->height()); + ppt = listView->mapToGlobal(ppt); + popup->insertItem("Yes", 1); + popup->insertItem("No", 0); + byte channel = atoi(item->text(FS_CHANNEL_COL).latin1()) - 1; + + int index = popup->exec(ppt, 0); + if (index != drumchannels[channel] && index !=-1) { + sendDrumChannelChange(index, channel); + drumchannels[channel] = index; + item->setText(FS_DRUM_CHANNEL_COL, index == 0 ? "No" : "Yes" ); + } + } + } + +//--------------------------------------------------------- +// getSoundFontId +//--------------------------------------------------------- + +int FluidSynthGui::getSoundFontId(QString q) + { + int id = -1; + for (std::list<FluidGuiSoundFont>::iterator it = stack.begin(); it != stack.end(); it++) { + if (q == it->name) + id = it->id; + } + return id; + } + +//--------------------------------------------------------- +// sendChannelChange +// Tell the client to set a soundfont to a specific fluid channel +//--------------------------------------------------------- + +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); + } + +//--------------------------------------------------------- +// sendDrumChannelChange +// Tell the client to set a specific channel to drum channel (equiv to midichan 10) +//--------------------------------------------------------- +void FluidSynthGui::sendDrumChannelChange(byte onoff, byte channel) + { + byte data[3]; + data[0] = FS_DRUMCHANNEL_SET; + data[1] = onoff; + data[2] = channel; + sendSysex(data, 3); + 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); + } + +void FluidSynthGui::sfItemClicked(Q3ListViewItem* item, const QPoint&, int /*col*/) + { + if (item != 0) { + currentlySelectedFont = atoi(item->text(FS_ID_COL)); + Pop->setEnabled(true); + } + else { + currentlySelectedFont = -1; + Pop->setEnabled(false); + } + } + +#if 0 + + + +void FluidSynthGui::readData (int fd) + { + unsigned char buffer[512]; + int n = ::read(fd, buffer, 512); +// dataInput(buffer, n); + } + + + +void FluidSynthGui::changeReverbRoomSize (int value) { + sendParameterChange(MUSE_FLUID_PARAMETER_REVERB, + "roomsize", value); +} + +void FluidSynthGui::changeReverbDamping (int value) { + sendParameterChange(MUSE_FLUID_PARAMETER_REVERB, + "damping", value); +} + +void FluidSynthGui::changeReverbWidth (int value) { + sendParameterChange(MUSE_FLUID_PARAMETER_REVERB, + "width", value); +} + + +void FluidSynthGui::changeChorusNumber (int value) { + sendParameterChange(MUSE_FLUID_PARAMETER_CHORUS, + "number", value); +} + +void FluidSynthGui::changeChorusType (int value) { + sendParameterChange(MUSE_FLUID_PARAMETER_CHORUS, + "type", value); +} + +void FluidSynthGui::changeChorusSpeed (int value) { + sendParameterChange(MUSE_FLUID_PARAMETER_CHORUS, + "speed", value); //TODO: Right now illegal values may be sent. + //Make sure they stay within fluidsynths legal boundaries (0.29-5Hz) dunno what that is in doubles + //This might be the case for the other chorus parameters as well +} + +void FluidSynthGui::changeChorusDepth (int value) { + sendParameterChange(MUSE_FLUID_PARAMETER_CHORUS, + "depth", value); +} + +void FluidSynthGui::changeChorusLevel (int value) { + sendParameterChange(MUSE_FLUID_PARAMETER_CHORUS, + "level", value); +} + + +void FluidSynthGui::sysexReceived(unsigned char const * data, int len) + { + char * cp; + double * dp; + //std::cerr << "FluidSynthGui, sysexReceived: " << (int) *data << std::endl; + switch (*data) { + case MUSE_FLUID_CLIENT_SEND_PARAMETER: + cp = (char *) (data + 2); + dp = (double *) (data + strlen (cp) + 3); + setParameter ((int) *(data+1), cp, *dp); + break; + + case MUSE_FLUID_GAIN_GET: + dp = (double *) (data + 1); + Gain->setValue ((int) (*dp * 12.8)); + break; + + case MUSE_FLUID_CLIENT_LASTDIR_CHANGE: { + if (*(char*)(data+1) != MUSE_FLUID_UNSPECIFIED_LASTDIR) + _lastDir = QString((char*)(data+1)); + else + _lastDir=""; + } + + default: + break; + } + } + + + + + + + +void FluidSynthGui::requestAllParameters () { + unsigned char data[1]; + + //data[0] = MUSE_FLUID_ADVGUI_GET; + //sendSysex (data, 1); + dbgMsg("Requesting all parameters!\n"); + sendParameterRequest (MUSE_FLUID_PARAMETER_REVERB, "on"); + sendParameterRequest (MUSE_FLUID_PARAMETER_REVERB, "roomsize"); + sendParameterRequest (MUSE_FLUID_PARAMETER_REVERB, "damping"); + sendParameterRequest (MUSE_FLUID_PARAMETER_REVERB, "width"); + sendParameterRequest (MUSE_FLUID_PARAMETER_REVERB, "level"); + sendParameterRequest (MUSE_FLUID_PARAMETER_CHORUS, "on"); + sendParameterRequest (MUSE_FLUID_PARAMETER_CHORUS, "number"); + sendParameterRequest (MUSE_FLUID_PARAMETER_CHORUS, "type"); + sendParameterRequest (MUSE_FLUID_PARAMETER_CHORUS, "speed"); + sendParameterRequest (MUSE_FLUID_PARAMETER_CHORUS, "depth"); + sendParameterRequest (MUSE_FLUID_PARAMETER_CHORUS, "level"); + data[0] = MUSE_FLUID_GAIN_GET; + sendSysex (data, 1); + data[0] = MUSE_FLUID_GUI_REQ_SOUNDFONTS; + sendSysex (data, 1); +} + +bool FluidSynthGui::sendParameterRequest (int parameterSet, const char * parameter) { + size_t parameterMem = strlen (parameter) + 1; + int datalen = 2 + parameterMem; + unsigned char * data = new unsigned char [datalen]; + *data = MUSE_FLUID_GUI_REQ_FXPARAMETER_GET; + *(data + 1) = (char) parameterSet; + memcpy (data + 2, parameter, parameterMem); + sendSysex (data, datalen); + delete data; + return true; +} + +void FluidSynthGui::setParameter (int parameterSet, const char * parameter, double value) { + int ival = (int) (value * 128); + std::string ps (parameter); + if (parameterSet == MUSE_FLUID_PARAMETER_REVERB) { + if (ps == "roomsize") { + ReverbRoomSize->setValue (ival); + } else if (ps == "damping") { + ReverbDamping->setValue (ival); + } else if (ps == "width") { + ReverbWidth->setValue (ival); + } else if (ps == "level") { + ReverbLevel->setValue (ival); + } else if (ps == "on") { + Reverb->setChecked (ival); + } + } else { + if (ps == "number") { + ChorusNumber->setValue (ival); + } else if (ps == "type") { + ChorusType->setCurrentItem (ival); + } else if (ps == "speed") { + ChorusSpeed->setValue (ival); + } else if (ps == "depth") { + ChorusDepth->setValue (ival); + } else if (ps == "level") { + ChorusLevel->setValue (ival); + } else if (ps == "on") { + Chorus->setChecked (ival); + } + } +} + +//Sends parameter to reverb or chorus +bool FluidSynthGui::sendParameterChange (int parameterSet, const char * parameter, int value) { + size_t parameterMem = strlen (parameter) + 1; + int datalen = 2 + parameterMem + sizeof (double); + unsigned char * data = new unsigned char [datalen]; + *data = (unsigned char) MUSE_FLUID_GUI_REQ_FXPARAMETER_SET; + *(data + 1) = (unsigned char) parameterSet; + memcpy (data + 2, parameter, parameterMem); + double * dp = (double *) (data + 2 + parameterMem); + *dp = ((double) value) / ((double) 128.0); + sendSysex (data, datalen); + delete data; + return true; +} + +void FluidSynthGui::dbgMsg(const char* msg) + { + if (MUSE_FLUID_DEBUG) + std::cerr << msg << std::endl; + } +//--------------------------------------------------------- +// main +//--------------------------------------------------------- + +/*QString museProject; +QString museGlobalShare; +QString museUser;*/ + + +int main(int argc, char* argv[]) +{ +/* + museUser = getenv("MUSEHOME"); + if (museUser == 0) + museUser = getenv("HOME"); + museGlobalShare = getenv("MUSE"); + if (museGlobalShare == 0) { + museGlobalShare = "/usr/muse"; + if (access(museGlobalShare.latin1(), R_OK) != 0) { + museGlobalShare = "/usr/local/muse"; + if (access(museGlobalShare.latin1(), R_OK) != 0) + museGlobalShare = museUser; + } + }*/ + char * instanceName = argv[1]; + QApplication app (argc, argv, true); + QWidget* w = new FluidSynthGui (); + if (argc > 1) + w->setCaption(QString(instanceName)); + w->show(); + app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); + qApp->exec(); +} + +#endif |