diff options
Diffstat (limited to 'muse_qt4_evolution/muse/synth.cpp')
-rw-r--r-- | muse_qt4_evolution/muse/synth.cpp | 588 |
1 files changed, 0 insertions, 588 deletions
diff --git a/muse_qt4_evolution/muse/synth.cpp b/muse_qt4_evolution/muse/synth.cpp deleted file mode 100644 index bbec5e34..00000000 --- a/muse_qt4_evolution/muse/synth.cpp +++ /dev/null @@ -1,588 +0,0 @@ -//============================================================================= -// MusE -// Linux Music Editor -// $Id:$ -// -// Copyright (C) 2002-2006 by Werner Schweer and others -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2. -// -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -//============================================================================= - -#include <dlfcn.h> - -#include "al/al.h" -#include "al/xml.h" -#include "al/tempo.h" -#include "muse.h" -#include "synth.h" -#include "midi.h" -#include "synti/libsynti/mess.h" -#include "song.h" -#include "audio.h" -#include "event.h" -#include "midievent.h" -#include "audio.h" -#include "midictrl.h" -#include "instruments/minstrument.h" -#include "audiodev.h" - -std::vector<Synth*> synthis; // array of available synthis - -extern void connectNodes(AudioTrack*, AudioTrack*); - -//--------------------------------------------------------- -// description -//--------------------------------------------------------- - -const char* MessSynth::description() const - { - return descr ? descr->description : ""; - } - -//--------------------------------------------------------- -// version -//--------------------------------------------------------- - -const char* MessSynth::version() const - { - return descr ? descr->version : ""; - } - -bool MessSynthIF::guiVisible() const - { - return _mess ? _mess->guiVisible() : false; - } - -void MessSynthIF::showGui(bool v) - { - if (v == guiVisible()) - return; - if (_mess) - _mess->showGui(v); - } - -bool MessSynthIF::hasGui() const - { - if (_mess) - return _mess->hasGui(); - return false; - } - -MidiEvent MessSynthIF::receiveEvent() - { - if (_mess) - return _mess->receiveEvent(); - return MidiEvent(); - } - -int MessSynthIF::eventsPending() const - { - if (_mess) - return _mess->eventsPending(); - return 0; - } - -void MessSynthIF::getGeometry(int* x, int* y, int* w, int* h) const - { - if (_mess) - _mess->getGeometry(x, y, w, h); - } - -void MessSynthIF::setGeometry(int x, int y, int w, int h) - { - if (_mess) - _mess->setGeometry(x, y, w, h); - } - -//--------------------------------------------------------- -// findSynth -// search for synthesizer base class -//--------------------------------------------------------- - -Synth* findSynth(const QString& sclass) - { - for (std::vector<Synth*>::iterator i = synthis.begin(); - i != synthis.end(); ++i) { - if ((*i)->name() == sclass) - return *i; - } - printf("synthi class <%s> not found\n", sclass.toLatin1().data()); - return 0; - } - -//--------------------------------------------------------- -// Synth -//--------------------------------------------------------- - -Synth::Synth(const QFileInfo* fi, QString s) - : info(*fi), _name(s) - { - _instances = 0; - } - -//--------------------------------------------------------- -// instantiate -//--------------------------------------------------------- - -void* MessSynth::instantiate(const QString& instanceName) - { - ++_instances; - const char* path = strdup(info.filePath().toAscii().data()); - - // load Synti dll - if (debugMsg) - printf(" load synti <%s>\n", path); - void* handle = dlopen(path, RTLD_NOW); - // void* handle = dlopen(path, RTLD_LAZY); - if (handle == 0) { - fprintf(stderr, "Synth::instantiate: dlopen(%s) failed: %s\n", - path, dlerror()); - delete path; - return 0; - } - typedef const MESS* (*MESS_Function)(); - MESS_Function msynth = (MESS_Function)dlsym(handle, "mess_descriptor"); - - if (!msynth) { - const char *txt = dlerror(); - if (txt) { - fprintf(stderr, - "Unable to find msynth_descriptor() function in plugin " - "library file \"%s\": %s.\n" - "Are you sure this is a MESS plugin file?\n", - path, txt); - delete path; - return 0; - } - } - delete path; - descr = msynth(); - if (descr == 0) { - fprintf(stderr, "Synth::instantiate: no MESS descr found\n"); - return 0; - } - Mess* mess = descr->instantiate(AL::sampleRate, instanceName.toLatin1().data()); - return mess; - } - -//--------------------------------------------------------- -// SynthI -//--------------------------------------------------------- - -SynthI::SynthI() - : AudioTrack() - { - track = this; - synthesizer = 0; - _sif = 0; - // setVolume(1.0); - // setPan(0.0); - setReadonly(true); // midi instrument cannot be edited - } - -//--------------------------------------------------------- -// ~SynthI -//--------------------------------------------------------- - -SynthI::~SynthI() - { - deactivate2(); - deactivate3(); - } - -//--------------------------------------------------------- -// setName -//--------------------------------------------------------- - -void SynthI::setName(const QString& s) - { - Track::setName(s); - } - -//--------------------------------------------------------- -// init -//--------------------------------------------------------- - -bool MessSynthIF::init(Synth* s, SynthI* si) - { - _mess = (Mess*)((MessSynth*)s)->instantiate(si->name()); - return (_mess == 0); - } - -//--------------------------------------------------------- -// channels -//--------------------------------------------------------- - -int MessSynthIF::channels() const - { - return _mess->channels(); - } - -//--------------------------------------------------------- -// createSIF -//--------------------------------------------------------- - -SynthIF* MessSynth::createSIF(SynthI* si) - { - MessSynthIF* sif = new MessSynthIF(si); - sif->init(this, si); - return sif; - } - -//--------------------------------------------------------- -// initInstance -// returns false on success -//--------------------------------------------------------- - -bool SynthI::initInstance(Synth* s) - { - synthesizer = s; - _sif = s->createSIF(this); - - setIName(name()); // set instrument name - int n = _sif->channels(); - AudioTrack::setChannels(n); - - //--------------------------------------------------- - // read available controller from synti - //--------------------------------------------------- - - int id = 0; - MidiControllerList* cl = MidiInstrument::controller(); - for (;;) { - const char* name; - int ctrl; - int min; - int max; - id = _sif->getControllerInfo(id, &name, &ctrl, &min, &max); - if (id == 0) - break; - MidiController* c = new MidiController(QString(name), ctrl, min, max, 0); - cl->push_back(c); - } - - EventList* iel = midiState(); - if (!iel->empty()) { - for (iEvent i = iel->begin(); i != iel->end(); ++i) { - Event ev = i->second; - MidiEvent pev(0, 0, ev); - if (_sif->putEvent(pev)) - putFifo.put(pev); // save for later retry - } - iel->clear(); - } - - int idx = 0; - for (std::vector<float>::iterator i = initParams.begin(); i != initParams.end(); ++i, ++idx) - _sif->setParameter(idx, *i); - return false; - } - -//--------------------------------------------------------- -// getControllerInfo -//--------------------------------------------------------- - -int MessSynthIF::getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max) - { - return _mess->getControllerInfo(id, name, ctrl, min, max); - } - -//--------------------------------------------------------- -// SynthI::deactivate -//--------------------------------------------------------- - -void SynthI::deactivate2() - { - removeMidiInstrument(this); - } - -//--------------------------------------------------------- -// deactivate3 -//--------------------------------------------------------- - -void SynthI::deactivate3() - { - delete _sif; - _sif = 0; - synthesizer->incInstances(-1); - } - -void MessSynthIF::deactivate3() - { - if (_mess) { - delete _mess; - _mess = 0; - } - } - -MessSynthIF::~MessSynthIF() - { - deactivate3(); - } - -//--------------------------------------------------------- -// initMidiSynth -// search for software synthis and advertise -//--------------------------------------------------------- - -void initMidiSynth() - { - QString s = museGlobalLib + "/synthi"; - -#ifdef __APPLE__ - QDir pluginDir(s, QString("*.dylib"), 0, QDir::Files); -#else - QDir pluginDir(s, QString("*.so"), 0, QDir::Files); -#endif - if (debugMsg) - printf("searching for software synthesizer in <%s>\n", s.toLatin1().data()); - if (pluginDir.exists()) { - QFileInfoList list = pluginDir.entryInfoList(); - for (int i = 0; i < list.size(); ++i) { - QFileInfo fi = list.at(i); - synthis.push_back(new MessSynth(&fi)); - } - if (debugMsg) - printf("%zd soft synth found\n", synthis.size()); - } - } - -//--------------------------------------------------------- -// write -//--------------------------------------------------------- - -void SynthI::write(Xml& xml) const - { - xml.stag("SynthI"); - AudioTrack::writeProperties(xml); - xml.tag("class", synth()->name()); - - //--------------------------------------------- - // if soft synth is attached to a midi port, - // write out port number - //--------------------------------------------- - - if (hasGui()) { - xml.tag("guiVisible", guiVisible()); - int x, y, w, h; - w = 0; - h = 0; - getGeometry(&x, &y, &w, &h); - if (h || w) - xml.tag("geometry", QRect(x, y, w, h)); - } - _sif->write(xml); - xml.etag("SynthI"); - - } - -void MessSynthIF::write(Xml& xml) const - { - //--------------------------------------------- - // dump current state of synth - //--------------------------------------------- - - int len = 0; - const unsigned char* p; - _mess->getInitData(&len, &p); - if (len) { - xml.stag("midistate"); - xml.stag(QString("event type=\"%1\" datalen=\"%2\"").arg(Sysex).arg(len)); - xml.dump(len, p); - xml.etag("event"); - xml.etag("midistate"); - } - } - -//--------------------------------------------------------- -// SynthI::read -//--------------------------------------------------------- - -void SynthI::read(QDomNode node) - { - QString sclass; - int port = -1; - bool startGui = false; - QRect r; - - for (; !node.isNull(); node = node.nextSibling()) { - QDomElement e = node.toElement(); - QString tag(e.tagName()); - if (tag == "class") - sclass = e.text(); - else if (tag == "port") - port = e.text().toInt(); - else if (tag == "guiVisible") - startGui = e.text().toInt(); - else if (tag == "midistate") - readMidiState(node.firstChild()); - else if (tag == "param") { - float val = e.text().toFloat(); - initParams.push_back(val); - } - else if (tag == "geometry") - r = AL::readGeometry(node); - else if (AudioTrack::readProperties(node)) { - printf("MusE:SynthI: unknown tag %s\n", e.tagName().toLatin1().data()); - } - } - Synth* s = findSynth(sclass); - if (s == 0) - return; - if (initInstance(s)) - return; - song->insertTrack0(this, -1); - setGeometry(r.x(), r.y(), r.width(), r.height()); - showGui(startGui); - } - -//--------------------------------------------------------- -// getPatchName -//--------------------------------------------------------- - -QString MessSynthIF::getPatchName(int channel, int prog) - { - if (_mess) - return _mess->getPatchName(channel, prog, 0); - return ""; - } - -//--------------------------------------------------------- -// populatePatchPopup -//--------------------------------------------------------- - -void MessSynthIF::populatePatchPopup(QMenu* menu, int ch) - { - menu->clear(); - const MidiPatch* mp = _mess->getPatchInfo(ch, 0); - QMenu *hm = NULL, *lm = NULL; - while (mp) { - switch(mp->typ) { - case MP_TYPE_HBANK : - hm = menu->addMenu(QString(mp->name)); - break; - case MP_TYPE_LBANK : - if(hm) lm = hm->addMenu(QString(mp->name)); - else lm = menu->addMenu(QString(mp->name)); - break; - default : - int id = ((mp->hbank & 0xff) << 16) - + ((mp->lbank & 0xff) << 8) + mp->prog; - QAction* a; - if(lm) a = lm->addAction(QString(mp->name)); - else a = menu->addAction(QString(mp->name)); - a->setData(id); - break; - } - mp = _mess->getPatchInfo(ch, mp); - } - } - - - -//--------------------------------------------------------- -// getData -//--------------------------------------------------------- - -void MessSynthIF::getData(MidiEventList* el, unsigned pos, int ports, unsigned n, float** buffer) - { - // Reset buffers first - for (int port = 0; port < ports; ++port) - memset(buffer[port], 0, n * sizeof(float)); - - int curPos = pos; - int endPos = pos + n; - - while (!synti->putFifo.isEmpty()) { - if (putEvent(synti->putFifo.peek())) - break; - synti->putFifo.remove(); - } - - // Echo events from Synti back - while (_mess->eventsPending()) - // _mess->processEvent(_mess->receiveEvent()); - _mess->receiveEvent(); // throw away event - - if (ports >= channels()) { - iMidiEvent i = el->begin(); - for (; i != el->end(); ++i) { - int frame = i->time(); - if (frame >= endPos) - break; - if (frame > curPos) { - // Several following notes during same segmentsize? - _mess->process(buffer, curPos-pos, frame - curPos); - curPos = frame; // don't process this piece again - } - if (putEvent(*i)) - synti->putFifo.put(*i); - } - if (endPos - curPos > 0) - _mess->process(buffer, curPos-pos, endPos - curPos); - el->erase(el->begin(), i); - } - else { - // this happens if the synth has stereo and we switch the - // channel to mono - - printf("MessSynthIF::getData - ports %d < channels %d\n", - ports, channels()); - } - } - -//--------------------------------------------------------- -// putEvent -// return true on error (busy), event will later be -// resend -//--------------------------------------------------------- - -bool MessSynthIF::putEvent(const MidiEvent& ev) - { - bool rv = true; - if (_mess) { - rv = _mess->processEvent(ev); - if (midiOutputTrace && !rv) { - printf("MidiOut<%s>", synti->name().toLatin1().data()); - ev.dump(); - } - } - return rv; - } - -//--------------------------------------------------------- -// collectInputData -//--------------------------------------------------------- - -void SynthI::collectInputData() - { - bufferEmpty = false; - _sif->getData(&_schedEvents, audioDriver->frameTime(), channels(), - segmentSize, buffer); - } - -//------------------------------------------------------------------- -// process -// Collect all midi events for the current process cycle and put -// into _schedEvents queue. For note on events create the proper -// note off events. The note off events maybe played after the -// current process cycle. -//------------------------------------------------------------------- - -void SynthI::processMidi(SeqTime* t) - { - if (mute()) - return; - MidiOut::processMidi(_schedEvents, t); - } - |