summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/muse/synth.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse_qt4_evolution/muse/synth.cpp')
-rw-r--r--muse_qt4_evolution/muse/synth.cpp588
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);
- }
-