From 09443effa75b28b0aac02e66503945b08d60fd2f Mon Sep 17 00:00:00 2001 From: Werner Schweer Date: Wed, 18 Oct 2006 14:02:49 +0000 Subject: jack midi, part II --- muse/ChangeLog | 2 + muse/muse/audioinput.cpp | 5 +- muse/muse/audioinput.h | 2 +- muse/muse/audiooutput.cpp | 6 +- muse/muse/audiooutput.h | 2 +- muse/muse/audiotrack.cpp | 1 - muse/muse/driver/alsamidi.cpp | 18 ++-- muse/muse/driver/alsamidi.h | 8 +- muse/muse/driver/audiodev.h | 4 +- muse/muse/driver/driver.h | 8 +- muse/muse/driver/dummyaudio.cpp | 48 +++++----- muse/muse/driver/jack.cpp | 44 +++++---- muse/muse/driver/jackaudio.h | 8 +- muse/muse/midi.cpp | 2 +- muse/muse/midiport.cpp | 206 +++++++++++++++++++++++++++------------- muse/muse/mixer/astrip.cpp | 4 +- muse/muse/mixer/mstrip.cpp | 109 +++++++++++---------- muse/muse/preferences.cpp | 4 +- muse/muse/route.cpp | 46 ++++----- muse/muse/route.h | 5 +- muse/muse/seqmsg.cpp | 26 +++-- muse/muse/song.cpp | 4 +- muse/muse/track.cpp | 31 +++--- muse/muse/track.h | 15 ++- muse/synti/mus/CMakeLists.txt | 1 + muse/synti/mus/mus.cpp | 18 ++-- 26 files changed, 369 insertions(+), 258 deletions(-) diff --git a/muse/ChangeLog b/muse/ChangeLog index ca965719..4d53eb2f 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,5 @@ +18.10 (ws) + - added routing for jack midi ports. Fixes for "mus". 17.10 (ws) - added new program "mus". Mus is a wrapper to operate MusE MESS synthesizer standalone with JACK audio/midi interface. The diff --git a/muse/muse/audioinput.cpp b/muse/muse/audioinput.cpp index 93bf7b5c..6fe50c12 100644 --- a/muse/muse/audioinput.cpp +++ b/muse/muse/audioinput.cpp @@ -100,7 +100,7 @@ void AudioInput::activate1() if (jackPorts[i]) printf("AudioInput::activate(): already active!\n"); else - jackPorts[i] = audioDriver->registerInPort(buffer); + jackPorts[i] = audioDriver->registerInPort(buffer, false); } } @@ -116,9 +116,8 @@ void AudioInput::activate2() printf("AudioInput::activate2(): no audio running !\n"); abort(); } - for (iRoute i = _inRoutes.begin(); i != _inRoutes.end(); ++i) { + for (iRoute i = _inRoutes.begin(); i != _inRoutes.end(); ++i) audioDriver->connect(i->port, jackPorts[i->channel]); - } } //--------------------------------------------------------- diff --git a/muse/muse/audioinput.h b/muse/muse/audioinput.h index 0fb3d409..fbbff14b 100644 --- a/muse/muse/audioinput.h +++ b/muse/muse/audioinput.h @@ -30,7 +30,7 @@ class AudioInput : public AudioTrack { Q_OBJECT - void* jackPorts[MAX_CHANNELS]; + Port jackPorts[MAX_CHANNELS]; void collectInputData(); public: diff --git a/muse/muse/audiooutput.cpp b/muse/muse/audiooutput.cpp index acdeeed1..103a5d3e 100644 --- a/muse/muse/audiooutput.cpp +++ b/muse/muse/audiooutput.cpp @@ -149,7 +149,7 @@ void AudioOutput::activate1() printf("AudioOutput::activate(): already active!\n"); } else - jackPorts[i] = audioDriver->registerOutPort(QString(buffer)); + jackPorts[i] = audioDriver->registerOutPort(QString(buffer), false); } } @@ -163,10 +163,8 @@ void AudioOutput::activate2() printf("AudioOutput::activate2(): no audio running !\n"); abort(); } - for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) { - i->port = audioDriver->findPort(i->name()); + for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) audioDriver->connect(jackPorts[i->channel], i->port); - } } //--------------------------------------------------------- diff --git a/muse/muse/audiooutput.h b/muse/muse/audiooutput.h index 055929ab..062c9fde 100644 --- a/muse/muse/audiooutput.h +++ b/muse/muse/audiooutput.h @@ -30,7 +30,7 @@ class AudioOutput : public AudioTrack { Q_OBJECT - void* jackPorts[MAX_CHANNELS]; + Port jackPorts[MAX_CHANNELS]; public: AudioOutput(); diff --git a/muse/muse/audiotrack.cpp b/muse/muse/audiotrack.cpp index 65c3f5a1..c66ecbd9 100644 --- a/muse/muse/audiotrack.cpp +++ b/muse/muse/audiotrack.cpp @@ -566,7 +566,6 @@ void AudioTrack::collectInputData() bool copyFlag = true; for (iRoute ir = rl->begin(); ir != rl->end(); ++ir) { float** ptr; - float* b[channels()]; int ch; if (ir->type == Route::TRACK) { AudioTrack* track = (AudioTrack*)ir->track; diff --git a/muse/muse/driver/alsamidi.cpp b/muse/muse/driver/alsamidi.cpp index c64d2451..48001261 100644 --- a/muse/muse/driver/alsamidi.cpp +++ b/muse/muse/driver/alsamidi.cpp @@ -97,7 +97,7 @@ bool AlsaMidi::init() // outputPorts //--------------------------------------------------------- -QList AlsaMidi::outputPorts() +QList AlsaMidi::outputPorts(bool) { QList clientList; snd_seq_client_info_t* cinfo; @@ -133,7 +133,7 @@ QList AlsaMidi::outputPorts() // inputPorts //--------------------------------------------------------- -QList AlsaMidi::inputPorts() +QList AlsaMidi::inputPorts(bool) { QList clientList; @@ -170,7 +170,7 @@ QList AlsaMidi::inputPorts() // registerOutPort //--------------------------------------------------------- -Port AlsaMidi::registerOutPort(const QString& name) +Port AlsaMidi::registerOutPort(const QString& name, bool) { int port = snd_seq_create_simple_port(alsaSeq, name.toLatin1().data(), outCap | SND_SEQ_PORT_CAP_WRITE, SND_SEQ_PORT_TYPE_APPLICATION); @@ -199,7 +199,7 @@ bool AlsaMidi::equal(Port p1, Port p2) // registerInPort //--------------------------------------------------------- -Port AlsaMidi::registerInPort(const QString& name) +Port AlsaMidi::registerInPort(const QString& name, bool) { int port = snd_seq_create_simple_port(alsaSeq, name.toLatin1().data(), inCap | SND_SEQ_PORT_CAP_READ, SND_SEQ_PORT_TYPE_APPLICATION); @@ -360,7 +360,7 @@ void AlsaMidi::addConnection(snd_seq_connect_t* ev) MidiOutPortList* opl = song->midiOutPorts(); for (iMidiOutPort i = opl->begin(); i != opl->end(); ++i) { MidiOutPort* oport = *i; - Port src = oport->port(); + Port src = oport->alsaPort(); if (equal(src, rs)) { RouteList* orl = oport->outRoutes(); @@ -381,7 +381,7 @@ void AlsaMidi::addConnection(snd_seq_connect_t* ev) MidiInPortList* ipl = song->midiInPorts(); for (iMidiInPort i = ipl->begin(); i != ipl->end(); ++i) { MidiInPort* iport = *i; - Port dst = iport->port(); + Port dst = iport->alsaPort(); if (equal(dst, rd)) { RouteList* irl = iport->inRoutes(); @@ -413,7 +413,7 @@ void AlsaMidi::removeConnection(snd_seq_connect_t* ev) MidiInPortList* ipl = song->midiInPorts(); for (iMidiInPort i = ipl->begin(); i != ipl->end(); ++i) { MidiInPort* iport = *i; - Port dst = iport->port(); + Port dst = iport->alsaPort(); if (equal(dst, rd)) { RouteList* irl = iport->inRoutes(); @@ -432,7 +432,7 @@ void AlsaMidi::removeConnection(snd_seq_connect_t* ev) MidiOutPortList* opl = song->midiOutPorts(); for (iMidiOutPort i = opl->begin(); i != opl->end(); ++i) { MidiOutPort* oport = *i; - Port src = oport->port(); + Port src = oport->alsaPort(); if (equal(src, rs)) { RouteList* orl = oport->outRoutes(); @@ -528,7 +528,7 @@ void AlsaMidi::read(MidiSeq* seq) MidiInPortList* mpl = song->midiInPorts(); for (iMidiInPort i = mpl->begin(); i != mpl->end(); ++i) { MidiInPort* inPort = *i; - if (equal(port, inPort->port())) { + if (equal(port, inPort->alsaPort())) { inPort->eventReceived(ev); } } diff --git a/muse/muse/driver/alsamidi.h b/muse/muse/driver/alsamidi.h index 4d9910f7..9e5e54f5 100644 --- a/muse/muse/driver/alsamidi.h +++ b/muse/muse/driver/alsamidi.h @@ -45,11 +45,11 @@ class AlsaMidi : public Driver { AlsaMidi(); virtual bool init(); - virtual QList outputPorts(); - virtual QList inputPorts(); + virtual QList outputPorts(bool midi); + virtual QList inputPorts(bool midi); - virtual Port registerOutPort(const QString& name); - virtual Port registerInPort(const QString& name); + virtual Port registerOutPort(const QString& name, bool midi); + virtual Port registerInPort(const QString& name, bool midi); virtual void unregisterPort(Port); virtual void setPortName(Port p, const QString& n); virtual QString portName(Port); diff --git a/muse/muse/driver/audiodev.h b/muse/muse/driver/audiodev.h index 607162b0..d83e5dd0 100644 --- a/muse/muse/driver/audiodev.h +++ b/muse/muse/driver/audiodev.h @@ -38,8 +38,8 @@ class AudioDriver : public Driver { virtual unsigned framePos() const = 0; virtual float* getBuffer(void* port, unsigned long nframes) = 0; virtual void registerClient() = 0; - virtual Port registerOutPort(const QString& name) = 0; - virtual Port registerInPort(const QString& name) = 0; + virtual Port registerOutPort(const QString& name, bool midi) = 0; + virtual Port registerInPort(const QString& name, bool midi) = 0; virtual int getState() = 0; virtual unsigned getCurFrame() = 0; virtual int realtimePriority() const = 0; // return zero if not realtime diff --git a/muse/muse/driver/driver.h b/muse/muse/driver/driver.h index 96ba26ec..bd6a826a 100644 --- a/muse/muse/driver/driver.h +++ b/muse/muse/driver/driver.h @@ -41,11 +41,11 @@ class Driver { virtual ~Driver() {} virtual bool init() = 0; - virtual QList outputPorts() = 0; - virtual QList inputPorts() = 0; + virtual QList outputPorts(bool midi) = 0; + virtual QList inputPorts(bool midi) = 0; - virtual Port registerOutPort(const QString&) = 0; - virtual Port registerInPort(const QString&) = 0; + virtual Port registerOutPort(const QString&, bool midi) = 0; + virtual Port registerInPort(const QString&, bool midi) = 0; virtual void unregisterPort(Port) = 0; virtual void setPortName(Port p, const QString&) = 0; virtual QString portName(Port) = 0; diff --git a/muse/muse/driver/dummyaudio.cpp b/muse/muse/driver/dummyaudio.cpp index 7f669923..768e3d04 100644 --- a/muse/muse/driver/dummyaudio.cpp +++ b/muse/muse/driver/dummyaudio.cpp @@ -68,16 +68,16 @@ class DummyAudio : public AudioDriver { return buffer; } - virtual QList outputPorts(); - virtual QList inputPorts(); + virtual QList outputPorts(bool midi = false); + virtual QList inputPorts(bool midi = false); virtual void registerClient() {} - virtual void* registerOutPort(const QString& s) { + virtual void* registerOutPort(const QString& s, bool midi = false) { iPorts.push_back(QString(s)); return (void*)(iPorts.size() + 3000); } - virtual void* registerInPort(const QString& s) { + virtual void* registerInPort(const QString& s, bool midi = false) { oPorts.push_back(QString(s)); return (void*)(oPorts.size() + 4000); } @@ -162,17 +162,19 @@ bool initDummyAudio() // outputPorts //--------------------------------------------------------- -QList DummyAudio::outputPorts() +QList DummyAudio::outputPorts(bool midi) { QList clientList; - PortName p1; - p1.name = QString("output1"); - p1.port = (void*)100; - PortName p2; - p2.name = QString("output2"); - p2.port = (void*)101; - clientList.append(p1); - clientList.append(p2); + if (!midi) { + PortName p1; + p1.name = QString("output1"); + p1.port = (void*)100; + PortName p2; + p2.name = QString("output2"); + p2.port = (void*)101; + clientList.append(p1); + clientList.append(p2); + } return clientList; } @@ -180,17 +182,19 @@ QList DummyAudio::outputPorts() // inputPorts //--------------------------------------------------------- -QList DummyAudio::inputPorts() +QList DummyAudio::inputPorts(bool midi) { QList clientList; - PortName p1; - p1.name = QString("input1"); - p1.port = (void*)0; - PortName p2; - p2.name = QString("input2"); - p2.port = (void*)1; - clientList.append(p1); - clientList.append(p2); + if (!midi) { + PortName p1; + p1.name = QString("input1"); + p1.port = (void*)0; + PortName p2; + p2.name = QString("input2"); + p2.port = (void*)1; + clientList.append(p1); + clientList.append(p2); + } return clientList; } diff --git a/muse/muse/driver/jack.cpp b/muse/muse/driver/jack.cpp index 5df57475..7a2168b4 100644 --- a/muse/muse/driver/jack.cpp +++ b/muse/muse/driver/jack.cpp @@ -493,10 +493,11 @@ void JackAudio::registerClient() // registerInPort //--------------------------------------------------------- -Port JackAudio::registerInPort(const QString& name) +Port JackAudio::registerInPort(const QString& name, bool midi) { - void* p = jack_port_register(_client, name.toLatin1().data(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); - //printf("JACK: registerInPort: <%s> %p\n", name.toLatin1().data(), p); + const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE; + void* p = jack_port_register(_client, name.toLatin1().data(), type, JackPortIsInput, 0); +// printf("JACK: registerInPort<%s>: <%s> %p\n", type, name.toLatin1().data(), p); return p; } @@ -504,10 +505,11 @@ Port JackAudio::registerInPort(const QString& name) // registerOutPort //--------------------------------------------------------- -Port JackAudio::registerOutPort(const QString& name) +Port JackAudio::registerOutPort(const QString& name, bool midi) { - void* p = jack_port_register(_client, name.toLatin1().data(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - //printf("JACK: registerOutPort: <%s> %p\n", name.toLatin1().data(), p); + const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE; + void* p = jack_port_register(_client, name.toLatin1().data(), type, JackPortIsOutput, 0); +// printf("JACK: registerOutPort<%s>: <%s> %p\n", type, name.toLatin1().data(), p); return p; } @@ -528,13 +530,17 @@ void exitJackAudio() bool JackAudio::connect(Port src, Port dst) { + if (src == 0 || dst == 0) { + fprintf(stderr, "JackAudio::connect(1): unknown jack ports\n"); + return false; + } const char* sn = jack_port_name((jack_port_t*) src); const char* dn = jack_port_name((jack_port_t*) dst); // printf("jack connect <%s>%p - <%s>%p\n", sn, src, dn, dst); if (sn == 0 || dn == 0) { - fprintf(stderr, "JackAudio::connect: unknown jack ports\n"); + fprintf(stderr, "JackAudio::connect(2): unknown jack ports\n"); return false; } int rv = jack_connect(_client, sn, dn); @@ -543,6 +549,14 @@ bool JackAudio::connect(Port src, Port dst) rv, sn, dn); if (rv == EEXIST) fprintf(stderr, " connection already made\n"); + else { + int pf = jack_port_flags((jack_port_t*)src); + if (!(pf & JackPortIsOutput)) + fprintf(stderr, " src is not an output port\n"); + pf = jack_port_flags((jack_port_t*)dst); + if (!(pf & JackPortIsInput)) + fprintf(stderr, " dst is not an input port\n"); + } return false; } return true; @@ -609,15 +623,13 @@ unsigned JackAudio::framePos() const // outputPorts //--------------------------------------------------------- -QList JackAudio::outputPorts() +QList JackAudio::outputPorts(bool midi) { - const char** ports = jack_get_ports(_client, 0, 0, 0); + const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE; + const char** ports = jack_get_ports(_client, 0, type, JackPortIsOutput); QList clientList; for (const char** p = ports; p && *p; ++p) { jack_port_t* port = jack_port_by_name(_client, *p); - int flags = jack_port_flags(port); - if (!(flags & JackPortIsOutput)) - continue; char buffer[128]; strncpy(buffer, *p, 128); if (strncmp(buffer, "MusE", 4) == 0) @@ -634,15 +646,13 @@ QList JackAudio::outputPorts() // inputPorts //--------------------------------------------------------- -QList JackAudio::inputPorts() +QList JackAudio::inputPorts(bool midi) { - const char** ports = jack_get_ports(_client, 0, 0, 0); + const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE; + const char** ports = jack_get_ports(_client, 0, type, JackPortIsInput); QList clientList; for (const char** p = ports; p && *p; ++p) { jack_port_t* port = jack_port_by_name(_client, *p); - int flags = jack_port_flags(port); - if (!(flags & JackPortIsInput)) - continue; char buffer[128]; strncpy(buffer, *p, 128); if (strncmp(buffer, "MusE", 4) == 0) diff --git a/muse/muse/driver/jackaudio.h b/muse/muse/driver/jackaudio.h index 9225d69e..9a0a4b8b 100644 --- a/muse/muse/driver/jackaudio.h +++ b/muse/muse/driver/jackaudio.h @@ -47,13 +47,13 @@ class JackAudio : public AudioDriver { return (float*)jack_port_get_buffer((jack_port_t*)port, nframes); } - virtual QList outputPorts(); - virtual QList inputPorts(); + virtual QList outputPorts(bool midi); + virtual QList inputPorts(bool midi); virtual void registerClient(); - virtual Port registerOutPort(const QString& name); - virtual Port registerInPort(const QString& name); + virtual Port registerOutPort(const QString& name, bool midi); + virtual Port registerInPort(const QString& name, bool midi); virtual char* getJackName(); diff --git a/muse/muse/midi.cpp b/muse/muse/midi.cpp index 4b037fe2..11989a7e 100644 --- a/muse/muse/midi.cpp +++ b/muse/muse/midi.cpp @@ -796,7 +796,7 @@ void MidiOutPort::process(unsigned from, unsigned to, const Pos& pos, unsigned f break; } - midiDriver->putEvent(alsaPort, *ev); + midiDriver->putEvent(_alsaPort, *ev); _nextPlayEvent = ev; _nextPlayEvent++; } diff --git a/muse/muse/midiport.cpp b/muse/muse/midiport.cpp index a4746d18..5b7245cf 100644 --- a/muse/muse/midiport.cpp +++ b/muse/muse/midiport.cpp @@ -26,6 +26,7 @@ #include "instruments/minstrument.h" #include "al/xml.h" #include "driver/mididev.h" +#include "driver/audiodev.h" #include "audio.h" #include "midiedit/drummap.h" @@ -54,7 +55,8 @@ MidiOutPort::MidiOutPort() _instrument = genericMidiInstrument; for (int ch = 0; ch < MIDI_CHANNELS; ++ch) _channel[ch] = new MidiChannel(this, ch); - alsaPort = 0; + _alsaPort = 0; + _jackPort = 0; _nextPlayEvent = _playEvents.end(); _sendSync = false; _deviceId = 127; // all @@ -77,11 +79,12 @@ void MidiOutPort::playFifo() MidiOutPort::~MidiOutPort() { - if (alsaPort) - midiDriver->unregisterPort(alsaPort); - for (int ch = 0; ch < MIDI_CHANNEL; ++ch) { + if (_alsaPort) + midiDriver->unregisterPort(_alsaPort); + if (_jackPort) + audioDriver->unregisterPort(_jackPort); + for (int ch = 0; ch < MIDI_CHANNEL; ++ch) delete _channel[ch]; - } } //--------------------------------------------------------- @@ -91,10 +94,10 @@ MidiOutPort::~MidiOutPort() void MidiOutPort::setName(const QString& s) { Track::setName(s); - if (alsaPort) - midiDriver->setPortName(alsaPort, s); - else - alsaPort = midiDriver->registerInPort(s); + if (_alsaPort) + midiDriver->setPortName(_alsaPort, s); + if (_jackPort) + audioDriver->setPortName(_jackPort, s); for (int ch = 0; ch < MIDI_CHANNELS; ++ch) _channel[ch]->setDefaultName(); } @@ -150,19 +153,35 @@ void MidiOutPort::read(QDomNode node) void MidiOutPort::activate1() { - if (alsaPort == 0) { - _outRoutes.clear(); - return; + if (_jackPort) + printf("MidiOutPort::activate1(): jack port already active!\n"); + else + _jackPort = audioDriver->registerOutPort(_name, true); + if (_alsaPort) + printf("MidiOutPort::activate1(): alsa port already active!\n"); + else + _alsaPort = midiDriver->registerInPort(_name, true); + } + +//--------------------------------------------------------- +// activate2 +// connect all routes to jack; can only be done if +// jack is activ running +//--------------------------------------------------------- + +void MidiOutPort::activate2() + { + if (audioState != AUDIO_RUNNING) { + printf("MidiOutPort::activate2(): no audio running !\n"); + abort(); } - for (iRoute i = _outRoutes.begin(); i != _outRoutes.end();) { - iRoute ni = i; - ++ni; - Route r = *i; - if (r.type == Route::MIDIPORT) { - if (!midiDriver->connect(alsaPort, i->port)) - _outRoutes.erase(i); - } - i = ni; + for (iRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) { + if (i->type == Route::JACKMIDIPORT) + audioDriver->connect(_jackPort, i->port); + else if (i->type == Route::MIDIPORT) + midiDriver->connect(_alsaPort, i->port); + else + printf("MidiOutPort::activate2(): bad route type\n"); } } @@ -172,8 +191,24 @@ void MidiOutPort::activate1() void MidiOutPort::deactivate() { - for (ciRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) - midiDriver->disconnect(alsaPort, i->port); + for (ciRoute i = _outRoutes.begin(); i != _outRoutes.end(); ++i) { + if (i->type ==Route::JACKMIDIPORT) + audioDriver->disconnect(_jackPort, i->port); + else if (i->type == Route::MIDIPORT) + midiDriver->disconnect(_alsaPort, i->port); + } + if (_jackPort) { + audioDriver->unregisterPort(_jackPort); + _jackPort = 0; + } + else + printf("MidiInPort::deactivate(): jack port not active!\n"); + if (_alsaPort) { + midiDriver->unregisterPort(_alsaPort); + _alsaPort = 0; + } + else + printf("MidiInPort::deactivate(): alsa port not active!\n"); } //--------------------------------------------------------- @@ -204,7 +239,7 @@ void MidiOutPort::putEvent(const MidiEvent& ev) } if (a == CTRL_PITCH) { - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_PITCHBEND, b, 0)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_PITCHBEND, b, 0)); return; } if (a == CTRL_PROGRAM) { @@ -214,10 +249,10 @@ void MidiOutPort::putEvent(const MidiEvent& ev) int lb = (b >> 8) & 0xff; int pr = b & 0x7f; if (hb != 0xff) - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HBANK, hb)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HBANK, hb)); if (lb != 0xff) - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LBANK, lb)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_PROGRAM, pr, 0)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LBANK, lb)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_PROGRAM, pr, 0)); return; // } } @@ -229,63 +264,63 @@ void MidiOutPort::putEvent(const MidiEvent& ev) sysex[4] = b & 0x7f; sysex[5] = (b >> 7) & 0x7f; MidiEvent e(ev.time(), ME_SYSEX, sysex, 6); - midiDriver->putEvent(alsaPort, e); + midiDriver->putEvent(_alsaPort, e); return; } #if 1 // if ALSA cannot handle RPN NRPN etc. if (a < 0x1000) { // 7 Bit Controller //putMidiEvent(MidiEvent(0, chn, ME_CONTROLLER, a, b)); - midiDriver->putEvent(alsaPort, ev); + midiDriver->putEvent(_alsaPort, ev); } else if (a < 0x20000) { // 14 bit high resolution controller int ctrlH = (a >> 8) & 0x7f; int ctrlL = a & 0x7f; int dataH = (b >> 7) & 0x7f; int dataL = b & 0x7f; - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, ctrlH, dataH)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, ctrlL, dataL)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, ctrlH, dataH)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, ctrlL, dataL)); } else if (a < 0x30000) { // RPN 7-Bit Controller int ctrlH = (a >> 8) & 0x7f; int ctrlL = a & 0x7f; - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, b)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, b)); } else if (a < 0x40000) { // NRPN 7-Bit Controller int ctrlH = (a >> 8) & 0x7f; int ctrlL = a & 0x7f; - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, b)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, b)); } else if (a < 0x60000) { // RPN14 Controller int ctrlH = (a >> 8) & 0x7f; int ctrlL = a & 0x7f; int dataH = (b >> 7) & 0x7f; int dataL = b & 0x7f; - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, dataH)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LDATA, dataL)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HRPN, ctrlH)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LRPN, ctrlL)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, dataH)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LDATA, dataL)); } else if (a < 0x70000) { // NRPN14 Controller int ctrlH = (a >> 8) & 0x7f; int ctrlL = a & 0x7f; int dataH = (b >> 7) & 0x7f; int dataL = b & 0x7f; - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, dataH)); - midiDriver->putEvent(alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LDATA, dataL)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HNRPN, ctrlH)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LNRPN, ctrlL)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_HDATA, dataH)); + midiDriver->putEvent(_alsaPort, MidiEvent(0, chn, ME_CONTROLLER, CTRL_LDATA, dataL)); } else { printf("putEvent: unknown controller type 0x%x\n", a); } #endif } - midiDriver->putEvent(alsaPort, ev); + midiDriver->putEvent(_alsaPort, ev); } //--------------------------------------------------------- @@ -295,7 +330,7 @@ void MidiOutPort::putEvent(const MidiEvent& ev) void MidiOutPort::playEventList() { for (; _nextPlayEvent != _playEvents.end(); ++_nextPlayEvent) - midiDriver->putEvent(alsaPort, *_nextPlayEvent); + midiDriver->putEvent(_alsaPort, *_nextPlayEvent); } //--------------------------------------------------------- @@ -479,7 +514,8 @@ void MidiOutPort::setSendSync(bool val) MidiInPort::MidiInPort() : MidiTrackBase(MIDI_IN) { - alsaPort = 0; + _alsaPort = 0; + _jackPort = 0; } //--------------------------------------------------------- @@ -488,8 +524,10 @@ MidiInPort::MidiInPort() MidiInPort::~MidiInPort() { - if (alsaPort) - midiDriver->unregisterPort(alsaPort); + if (_alsaPort) + midiDriver->unregisterPort(_alsaPort); + if (_jackPort) + audioDriver->unregisterPort(_jackPort); } //--------------------------------------------------------- @@ -499,10 +537,10 @@ MidiInPort::~MidiInPort() void MidiInPort::setName(const QString& s) { Track::setName(s); - if (alsaPort) - midiDriver->setPortName(alsaPort, s); - else - alsaPort = midiDriver->registerOutPort(s); + if (_alsaPort) + midiDriver->setPortName(_alsaPort, s); + if (_jackPort) + audioDriver->setPortName(_jackPort, s); } //--------------------------------------------------------- @@ -537,17 +575,35 @@ void MidiInPort::read(QDomNode node) void MidiInPort::activate1() { - if (alsaPort == 0) { - _inRoutes.clear(); - return; + if (_alsaPort) + printf("MidiInPort::activate1(): alsa port already active!\n"); + else + _alsaPort = midiDriver->registerOutPort(_name, true); + if (_jackPort) + printf("MidiInPort::activate1(): jack port already active!\n"); + else + _jackPort = audioDriver->registerInPort(_name, true); + } + +//--------------------------------------------------------- +// activate2 +// connect all routes to jack; can only be done if +// jack is activ running +//--------------------------------------------------------- + +void MidiInPort::activate2() + { + if (audioState != AUDIO_RUNNING) { + printf("MidiInPort::activate2(): no audio running !\n"); + abort(); } - for (iRoute i = _inRoutes.begin(); i != _inRoutes.end();) { - iRoute ni = i; - ++ni; - Route r = *i; - if (!midiDriver->connect(i->port, alsaPort)) - _inRoutes.erase(i); - i = ni; + for (iRoute i = _inRoutes.begin(); i != _inRoutes.end(); ++i) { + if (i->type == Route::JACKMIDIPORT) + audioDriver->connect(i->port, _jackPort); + else if (i->type == Route::MIDIPORT) + midiDriver->connect(i->port, _alsaPort); + else + printf("MidiInPort::activate2(): bad route type\n"); } } @@ -557,8 +613,26 @@ void MidiInPort::activate1() void MidiInPort::deactivate() { - for (ciRoute i = _inRoutes.begin(); i != _inRoutes.end(); ++i) - midiDriver->disconnect(i->port, alsaPort); + for (ciRoute i = _inRoutes.begin(); i != _inRoutes.end(); ++i) { + if (i->type == Route::JACKMIDIPORT) + audioDriver->disconnect(i->port, _jackPort); + else if (i->type == Route::MIDIPORT) + midiDriver->disconnect(i->port, _alsaPort); + else + printf("MidiInPort::deactivate(): bad route type\n"); + } + if (_jackPort) { + audioDriver->unregisterPort(_jackPort); + _jackPort = 0; + } + else + printf("MidiInPort::deactivate(): jack port not active!\n"); + if (_alsaPort) { + audioDriver->unregisterPort(_alsaPort); + _alsaPort = 0; + } + else + printf("MidiInPort::deactivate(): alsa port not active!\n"); } //--------------------------------------------------------- diff --git a/muse/muse/mixer/astrip.cpp b/muse/muse/mixer/astrip.cpp index 8b4b0ed7..bbaf5189 100644 --- a/muse/muse/mixer/astrip.cpp +++ b/muse/muse/mixer/astrip.cpp @@ -684,7 +684,7 @@ void AudioStrip::iRoutePressed() char buffer[128]; snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().data(), i+1); pup.addSeparator()->setText(QString(buffer)); - QList ol = audioDriver->outputPorts(); + QList ol = audioDriver->outputPorts(false); foreach (PortName ip, ol) { QAction* id = pup.addAction(ip.name); id->setCheckable(true); @@ -762,7 +762,7 @@ void AudioStrip::oRoutePressed() snprintf(buffer, 128, "%s %d", tr("Channel").toLatin1().data(), i+1); pup.addSeparator()->setText(QString(buffer)); - QList ol = audioDriver->inputPorts(); + QList ol = audioDriver->inputPorts(false); foreach (PortName ip, ol) { QAction* action = pup.addAction(ip.name); action->setCheckable(true); diff --git a/muse/muse/mixer/mstrip.cpp b/muse/muse/mixer/mstrip.cpp index 4195ec86..d0cd4c85 100644 --- a/muse/muse/mixer/mstrip.cpp +++ b/muse/muse/mixer/mstrip.cpp @@ -14,6 +14,7 @@ #include "widgets/simplebutton.h" #include "widgets/utils.h" #include "driver/mididev.h" +#include "driver/audiodev.h" #include "synth.h" #include "midirack.h" #include "midiplugin.h" @@ -377,9 +378,9 @@ void MidiChannelStrip::iRoutePressed() Route srcRoute(track, -1, Route::TRACK); if (n->isChecked()) - audio->msgRemoveRoute(srcRoute, dstRoute); - else audio->msgAddRoute(srcRoute, dstRoute); + else + audio->msgRemoveRoute(srcRoute, dstRoute); song->update(SC_ROUTE); } delete pup; @@ -918,14 +919,13 @@ void MidiOutPortStrip::oRoutePressed() pup->addSeparator()->setText(tr("MidiDevices")); RouteList* orl = track->outRoutes(); - QList ol = midiDriver->outputPorts(); - int idx = 0; + QList ol = midiDriver->outputPorts(true); foreach (PortName ip, ol) { QAction* oa = pup->addAction(ip.name); oa->setCheckable(true); - oa->setData(qVariantFromValue(ip.port)); - Route dst(ip.port, Route::MIDIPORT); + oa->setData(QVariant::fromValue(dst)); + for (iRoute ir = orl->begin(); ir != orl->end(); ++ir) { if (*ir == dst) { oa->setChecked(true); @@ -937,15 +937,14 @@ void MidiOutPortStrip::oRoutePressed() // // add software synthesizer to list // - idx = 1000; SynthIList* sl = song->syntis(); - for (iSynthI i = sl->begin(); i != sl->end(); ++i, ++idx) { + for (iSynthI i = sl->begin(); i != sl->end(); ++i) { SynthI* track = *i; QAction* oa = pup->addAction(track->name()); oa->setCheckable(true); - oa->setData(QVariant(idx)); - Route dst(track, -1, Route::SYNTIPORT); + oa->setData(QVariant::fromValue(dst)); + for (iRoute ir = orl->begin(); ir != orl->end(); ++ir) { if (*ir == dst) { oa->setChecked(true); @@ -954,32 +953,33 @@ void MidiOutPortStrip::oRoutePressed() } } - QAction* action = pup->exec(QCursor::pos()); - if (action) { - QString s(action->text()); - int n = action->data().toInt(); + // + // add JACK midi port to list + // + ol = audioDriver->inputPorts(true); + foreach (PortName ip, ol) { + QAction* oa = pup->addAction(ip.name); + oa->setCheckable(true); + Route dst(ip.port, Route::JACKMIDIPORT); + oa->setData(QVariant::fromValue(dst)); - Route srcRoute(track); - if (n < 1000) { - PortName ip = ol[n]; - Route dstRoute(ip.port, Route::MIDIPORT); - if (action->isChecked()) - audio->msgRemoveRoute(srcRoute, dstRoute); - else - audio->msgAddRoute(srcRoute, dstRoute); - } - else { - for (iSynthI i = sl->begin(); i != sl->end(); ++i) { - if ((*i)->name() == s) { - Route dstRoute(*i, -1, Route::SYNTIPORT); - if (action->isChecked()) - audio->msgRemoveRoute(srcRoute, dstRoute); - else - audio->msgAddRoute(srcRoute, dstRoute); - break; - } + for (iRoute ir = orl->begin(); ir != orl->end(); ++ir) { + if (*ir == dst) { + oa->setChecked(true); + break; } } + } + + QAction* action = pup->exec(QCursor::pos()); + if (action) { + Route dstRoute = action->data().value(); + Route srcRoute(track); + + if (action->isChecked()) + audio->msgAddRoute(srcRoute, dstRoute); + else + audio->msgRemoveRoute(srcRoute, dstRoute); song->update(SC_ROUTE); } delete pup; @@ -1263,13 +1263,31 @@ void MidiInPortStrip::iRoutePressed() RouteList* irl = track->inRoutes(); - QList ol = midiDriver->inputPorts(); + QList ol = midiDriver->inputPorts(false); foreach (PortName ip, ol) { QAction* action = pup->addAction(ip.name); action->setCheckable(true); - Route dst(ip.port, Route::MIDIPORT); + Route src(ip.port, Route::MIDIPORT); + action->setData(QVariant::fromValue(src)); for (iRoute ir = irl->begin(); ir != irl->end(); ++ir) { - if (*ir == dst) { + if (*ir == src) { + action->setChecked(true); + break; + } + } + } + // + // add JACK midi ports to list + // + ol = audioDriver->outputPorts(true); + foreach (PortName ip, ol) { + QAction* action = pup->addAction(ip.name); + action->setCheckable(true); + Route src(ip.port, Route::JACKMIDIPORT); + action->setData(QVariant::fromValue(src)); + + for (iRoute ir = irl->begin(); ir != irl->end(); ++ir) { + if (*ir == src) { action->setChecked(true); break; } @@ -1277,9 +1295,7 @@ void MidiInPortStrip::iRoutePressed() } QAction* action = pup->exec(QCursor::pos()); if (action) { - QString s(action->text()); - Port port = midiDriver->findPort(s.toAscii().data()); - Route srcRoute(port, Route::MIDIPORT); + Route srcRoute = action->data().value(); Route dstRoute(track, -1, Route::TRACK); // check if route src->dst exists: @@ -1551,12 +1567,13 @@ void MidiSyntiStrip::oRoutePressed() QString s; s.setNum(channel+1); QAction* action = m->addAction(s); - action->setData(pn * 16 + channel); MidiChannel* mc = op->channel(channel); Route r(mc, -1, Route::TRACK); + action->setData(QVariant::fromValue(r)); + action->setCheckable(true); + for (iRoute ir = orl->begin(); ir != orl->end(); ++ir) { if (r == *ir) { - action->setCheckable(true); action->setChecked(true); break; } @@ -1565,13 +1582,8 @@ void MidiSyntiStrip::oRoutePressed() } QAction* action = pup.exec(QCursor::pos()); if (action) { - int n = action->data().toInt(); - int portno = n >> 4; - int channel = n & 0xf; - MidiOutPort* mp = mpl->index(portno); - MidiChannel* mc = mp->channel(channel); + Route dstRoute = action->data().value(); Route srcRoute(track, -1, Route::TRACK); - Route dstRoute(mc, -1, Route::TRACK); // remove old route // note: audio->msgRemoveRoute() changes orl list @@ -1610,8 +1622,7 @@ void MidiSyntiStrip::iRoutePressed() RouteList* irl = t->inRoutes(); MidiInPortList* ipl = song->midiInPorts(); - int tn = 0; - for (iMidiInPort i = ipl->begin(); i != ipl->end(); ++i, ++tn) { + for (iMidiInPort i = ipl->begin(); i != ipl->end(); ++i) { QMenu* m = pup.addMenu((*i)->name()); m->addSeparator()->setText(tr("Channel")); QAction* action = m->addAction(tr("All")); diff --git a/muse/muse/preferences.cpp b/muse/muse/preferences.cpp index 6587f48c..e2385155 100644 --- a/muse/muse/preferences.cpp +++ b/muse/muse/preferences.cpp @@ -241,14 +241,14 @@ PreferencesDialog::PreferencesDialog(Arranger* a, QWidget* parent) break; } } - QList ol = midiDriver->inputPorts(); + QList ol = midiDriver->inputPorts(true); int i = 0; for (QList::iterator ip = ol.begin(); ip != ol.end(); ++ip, ++i) { preferredInput->addItem(ip->name); if (ip->name == config->defaultMidiInputDevice) preferredInput->setCurrentIndex(i); } - ol = midiDriver->outputPorts(); + ol = midiDriver->outputPorts(true); i = 0; for (QList::iterator ip = ol.begin(); ip != ol.end(); ++ip, ++i) { preferredOutput->addItem(ip->name); diff --git a/muse/muse/route.cpp b/muse/muse/route.cpp index bc8a02e8..f30355f0 100644 --- a/muse/muse/route.cpp +++ b/muse/muse/route.cpp @@ -81,14 +81,12 @@ Route::Route() bool addRoute(Route src, Route dst) { - if (!src.isValid() || !dst.isValid()) - return false; - // printf("addRoute %s.%d:<%s> %s.%d:<%s>\n", // src.tname(), src.channel, src.name().toLatin1().data(), // dst.tname(), dst.channel, dst.name().toLatin1().data()); - if (src.type == Route::AUDIOPORT || src.type == Route::MIDIPORT) { + if (src.type == Route::AUDIOPORT || src.type == Route::MIDIPORT + || src.type == Route::JACKMIDIPORT) { if (dst.type != Route::TRACK) { fprintf(stderr, "addRoute: bad route 1\n"); return false; @@ -105,8 +103,8 @@ bool addRoute(Route src, Route dst) } inRoutes->push_back(src); } - else if (dst.type == Route::AUDIOPORT || dst.type == Route::MIDIPORT) { -// || dst.type == Route::SYNTIPORT) { + else if (dst.type == Route::AUDIOPORT || dst.type == Route::MIDIPORT + || dst.type == Route::JACKMIDIPORT) { if (src.type != Route::TRACK) { fprintf(stderr, "addRoute: bad route 3\n"); return false; @@ -149,11 +147,8 @@ bool addRoute(Route src, Route dst) void removeRoute(Route src, Route dst) { -// printf("removeRoute %s.%d:<%s> %s.%d:<%s>\n", -// src.tname(), src.channel, src.name().toLatin1().data(), -// dst.tname(), dst.channel, dst.name().toLatin1().data()); - - if (src.type == Route::AUDIOPORT || src.type == Route::MIDIPORT) { + if (src.type == Route::AUDIOPORT || src.type == Route::MIDIPORT + || src.type == Route::JACKMIDIPORT) { if (dst.type != Route::TRACK && dst.type != Route::SYNTIPORT) { fprintf(stderr, "removeRoute: bad route 1\n"); goto error; @@ -173,7 +168,8 @@ void removeRoute(Route src, Route dst) } } } - else if (dst.type == Route::AUDIOPORT || dst.type == Route::MIDIPORT) { + else if (dst.type == Route::AUDIOPORT || dst.type == Route::MIDIPORT + || dst.type == Route::JACKMIDIPORT) { // | dst.type == Route::SYNTIPORT) { if (src.type != Route::TRACK) { fprintf(stderr, "removeRoute: bad route 3\n"); @@ -252,6 +248,8 @@ QString Route::name() const return track2name(track); case AUDIOPORT: return audioDriver->portName(port); + case JACKMIDIPORT: + return audioDriver->portName(port); case MIDIPORT: return midiDriver->portName(port); case AUXPLUGIN: @@ -260,16 +258,6 @@ QString Route::name() const return QString("?"); } -//--------------------------------------------------------- -// checkRoute -// return true if route is valid -//--------------------------------------------------------- - -bool checkRoute(const QString& /*s*/, const QString& /*d*/) - { - return true; - } - //--------------------------------------------------------- // read //--------------------------------------------------------- @@ -339,6 +327,8 @@ bool Route::operator==(const Route& a) const return channel == a.channel && track == a.track; case MIDIPORT: return midiDriver->equal(port, a.port); + case JACKMIDIPORT: + return audioDriver->equal(port, a.port); case AUDIOPORT: return channel == a.channel && audioDriver->equal(port, a.port); case AUXPLUGIN: @@ -354,7 +344,8 @@ bool Route::operator==(const Route& a) const const char* Route::tname(RouteType t) { static const char* names[] = { - "TRACK", "AUDIOPORT", "MIDIPORT", "SYNTIPORT", "AUX" + "TRACK", "AUDIOPORT", "MIDIPORT", "JACKMIDIPORT", + "SYNTIPORT", "AUX" }; if (t > (int)(sizeof(names)/sizeof(*names))) return "???"; @@ -374,6 +365,7 @@ void Route::write(Xml& xml, const char* label) const { switch (type) { case AUDIOPORT: + case JACKMIDIPORT: case MIDIPORT: case AUXPLUGIN: xml.put("<%s type=\"%s\" name=\"%s\"/>", @@ -432,6 +424,12 @@ void Route::read(QDomNode node) if (port == 0) printf("Route::read(): audioport not found\n"); } + else if (st == "JACKMIDIPORT") { + type = Route::JACKMIDIPORT; + port = audioDriver->findPort(s); + if (port == 0) + printf("Route::read(): jack midiport not found\n"); + } else if (st == "MIDIPORT") { type = Route::MIDIPORT; port = midiDriver->findPort(s); @@ -504,5 +502,3 @@ Track* Song::findTrack(const QString& s) const printf("track <%s> not found\n", s.toLatin1().data()); return 0; } - - diff --git a/muse/muse/route.h b/muse/muse/route.h index 35aeca95..a008a199 100644 --- a/muse/muse/route.h +++ b/muse/muse/route.h @@ -58,7 +58,8 @@ typedef void* Port; //--------------------------------------------------------- struct Route { - enum RouteType { TRACK, AUDIOPORT, MIDIPORT, SYNTIPORT, AUXPLUGIN}; + enum RouteType { TRACK, AUDIOPORT, MIDIPORT, JACKMIDIPORT, + SYNTIPORT, AUXPLUGIN}; union { Track* track; @@ -78,10 +79,8 @@ struct Route { QString name() const; void read(QDomNode node); void write(Xml&, const char* name) const; -// static void write(Xml&, const char* name, const Track*); bool operator==(const Route& a) const; - bool isValid() const { return track != 0; } void dump() const; const char* tname() const; static const char* tname(RouteType); diff --git a/muse/muse/seqmsg.cpp b/muse/muse/seqmsg.cpp index 356745d1..4692b488 100644 --- a/muse/muse/seqmsg.cpp +++ b/muse/muse/seqmsg.cpp @@ -82,15 +82,21 @@ void Audio::msgRemoveRoute(Route src, Route dst) AudioInput* ai = (AudioInput*)(dst.track); audioDriver->disconnect(src.port, ai->jackPort(dst.channel)); } + else if (src.type == Route::JACKMIDIPORT) { + audioDriver->disconnect(src.port, ((MidiInPort*)dst.track)->jackPort()); + } else if (src.type == Route::MIDIPORT) { - midiDriver->disconnect(src.port, ((MidiInPort*)dst.track)->port()); + midiDriver->disconnect(src.port, ((MidiInPort*)dst.track)->alsaPort()); } else if (dst.type == Route::AUDIOPORT) { AudioOutput* ai = (AudioOutput*)(src.track); audioDriver->disconnect(ai->jackPort(src.channel), dst.port); } else if (dst.type == Route::MIDIPORT) { - midiDriver->disconnect(((MidiOutPort*)src.track)->port(), dst.port); + midiDriver->disconnect(((MidiOutPort*)src.track)->alsaPort(), dst.port); + } + else if (dst.type == Route::JACKMIDIPORT) { + audioDriver->disconnect(((MidiOutPort*)src.track)->jackPort(), dst.port); } msgRemoveRoute1(src, dst); } @@ -119,15 +125,21 @@ void Audio::msgAddRoute(Route src, Route dst) AudioInput* ai = (AudioInput*)dst.track; audioDriver->connect(src.port, ai->jackPort(dst.channel)); } - if (src.type == Route::MIDIPORT) { - midiDriver->connect(src.port, ((MidiInPort*)dst.track)->port()); + else if (src.type == Route::JACKMIDIPORT) { + audioDriver->connect(src.port, ((MidiInPort*)dst.track)->jackPort()); + } + else if (src.type == Route::MIDIPORT) { + midiDriver->connect(src.port, ((MidiInPort*)dst.track)->alsaPort()); } else if (dst.type == Route::AUDIOPORT) { AudioOutput* ao = (AudioOutput*)src.track; audioDriver->connect(ao->jackPort(src.channel), dst.port); } else if (dst.type == Route::MIDIPORT) { - midiDriver->connect(((MidiOutPort*)src.track)->port(), dst.port); + midiDriver->connect(((MidiOutPort*)src.track)->alsaPort(), dst.port); + } + else if (dst.type == Route::JACKMIDIPORT) { + audioDriver->connect(((MidiOutPort*)src.track)->jackPort(), dst.port); } } @@ -196,7 +208,7 @@ void Audio::msgSetChannels(AudioTrack* node, int n) if (i < n && ai->jackPort(i) == 0) { char buffer[128]; snprintf(buffer, 128, "%s-%d", name.toLatin1().data(), i); - ai->setJackPort(i, audioDriver->registerInPort(QString(buffer))); + ai->setJackPort(i, audioDriver->registerInPort(QString(buffer), false)); } else if ((i >= n) && ai->jackPort(i)) { RouteList* ir = node->inRoutes(); @@ -219,7 +231,7 @@ void Audio::msgSetChannels(AudioTrack* node, int n) if (i < n && jp == 0) { char buffer[128]; snprintf(buffer, 128, "%s-%d", name.toLatin1().data(), i); - ao->setJackPort(i, audioDriver->registerOutPort(QString(buffer))); + ao->setJackPort(i, audioDriver->registerOutPort(QString(buffer), false)); } else if (i >= n && jp) { RouteList* ir = node->outRoutes(); diff --git a/muse/muse/song.cpp b/muse/muse/song.cpp index 86cfb410..8b339cfc 100644 --- a/muse/muse/song.cpp +++ b/muse/muse/song.cpp @@ -1627,7 +1627,7 @@ void Song::insertTrack(Track* track, int idx) { // connect first input channel to first available jack output // etc. - QList op = audioDriver->outputPorts(); + QList op = audioDriver->outputPorts(false); QList::iterator is = op.begin(); for (int ch = 0; ch < track->channels(); ++ch) { if (is != op.end()) { @@ -1641,7 +1641,7 @@ void Song::insertTrack(Track* track, int idx) break; case Track::AUDIO_OUTPUT: { - QList op = audioDriver->inputPorts(); + QList op = audioDriver->inputPorts(false); QList::iterator is = op.begin(); for (int ch = 0; ch < track->channels(); ++ch) { if (is != op.end()) { diff --git a/muse/muse/track.cpp b/muse/muse/track.cpp index 4cc19ee3..938a202c 100644 --- a/muse/muse/track.cpp +++ b/muse/muse/track.cpp @@ -32,15 +32,17 @@ #include "part.h" #include "gui.h" +// synchronize with TrackType!: + const char* Track::_cname[] = { - "Output", "Group", "Aux", "Wave", "Input", - "Synti", "Midi", "M-Out", "M-In", "M-Ch", "M-Synt" + "Output", "Group", "Wave", "Input", + "Synti", "Midi", "MidiOut", "MidiIn", "M-Ch", "M-Synth" }; const char* Track::_clname[] = { - "Audio Output", "Audio Group", "Audio Aux", "Wave Track", "Audio Input", + "Audio Output", "Audio Group", "Wave Track", "Audio Input", "Synti", "Midi Track", "Midi Outport", "Midi Inport", "Midi Channel", - "Midi Synti" + "Midi Synth" }; //--------------------------------------------------------- @@ -143,15 +145,6 @@ void Track::setDefaultName() case WAVE: base = QString("Track"); break; - case MIDI_OUT: - base = QString("MP"); - break; - case MIDI_IN: - base = QString("M-In"); - break; - case MIDI_SYNTI: - base = QString("M-Synth"); - break; case MIDI_CHANNEL: { MidiOutPort* mop = ((MidiChannel*)this)->port(); @@ -161,20 +154,20 @@ void Track::setDefaultName() return; } break; - case AUDIO_OUTPUT: - base = QString("AudioOut"); - break; case AUDIO_GROUP: base = QString("Group"); break; - case AUDIO_INPUT: - base = QString("AudioIn"); - break; case AUDIO_SOFTSYNTH: // base = QString("Synth"); return; break; + case AUDIO_OUTPUT: + case AUDIO_INPUT: + case MIDI_OUT: + case MIDI_IN: + case MIDI_SYNTI: case TRACK_TYPES: + base = cname(); break; }; base += " "; diff --git a/muse/muse/track.h b/muse/muse/track.h index ff383f4e..6de6a19b 100644 --- a/muse/muse/track.h +++ b/muse/muse/track.h @@ -345,7 +345,9 @@ class MidiTrackBase : public Track { class MidiInPort : public MidiTrackBase { Q_OBJECT - Port alsaPort; + Port _alsaPort; + Port _jackPort; + MPEventList _recordEvents; public: @@ -353,6 +355,7 @@ class MidiInPort : public MidiTrackBase { ~MidiInPort(); virtual void activate1(); + virtual void activate2(); virtual void deactivate(); virtual void setName(const QString& s); virtual void write(Xml&) const; @@ -360,7 +363,8 @@ class MidiInPort : public MidiTrackBase { virtual Track* newTrack() const { return new MidiInPort(); } virtual bool isMute() const { return _mute; } virtual Part* newPart(Part*, bool) { return 0; } - Port port() const { return alsaPort; } + Port alsaPort() const { return _alsaPort; } + Port jackPort() const { return _jackPort; } #ifndef __APPLE__ void eventReceived(snd_seq_event_t*); @@ -423,7 +427,8 @@ class MidiOutPort : public MidiTrackBase { MidiInstrument* _instrument; MidiChannel* _channel[MIDI_CHANNELS]; - Port alsaPort; + Port _alsaPort; + Port _jackPort; bool _sendSync; // this port sends mtc mmc events int _deviceId; // 0-126; 127 == all @@ -445,6 +450,7 @@ class MidiOutPort : public MidiTrackBase { ~MidiOutPort(); virtual void activate1(); + virtual void activate2(); virtual void deactivate(); MidiChannel* channel(int n) { return _channel[n]; } @@ -462,7 +468,8 @@ class MidiOutPort : public MidiTrackBase { bool guiVisible() const; bool hasGui() const; - Port port() const { return alsaPort; } + Port alsaPort() const { return _alsaPort; } + Port jackPort() const { return _jackPort; } void putEvent(const MidiEvent&); MPEventList* playEvents() { return &_playEvents; } diff --git a/muse/synti/mus/CMakeLists.txt b/muse/synti/mus/CMakeLists.txt index 98a0c74c..f7d8a0ad 100644 --- a/muse/synti/mus/CMakeLists.txt +++ b/muse/synti/mus/CMakeLists.txt @@ -21,6 +21,7 @@ add_executable ( mus mus.cpp ) install_targets ( /bin mus ) target_link_libraries(mus + synti ${QT_LIBRARIES} ${JACK_LIB} ) diff --git a/muse/synti/mus/mus.cpp b/muse/synti/mus/mus.cpp index 5534dfab..062fd69c 100644 --- a/muse/synti/mus/mus.cpp +++ b/muse/synti/mus/mus.cpp @@ -36,9 +36,9 @@ static int segmentSize; static Mess* mess; static const int MAX_OUTPORTS = 8; -jack_port_t* inPort; -jack_port_t* outPorts[MAX_OUTPORTS]; -float* outBuffer[MAX_OUTPORTS]; +static jack_port_t* inPort; +static jack_port_t* outPorts[MAX_OUTPORTS]; +static float* outBuffer[MAX_OUTPORTS]; //--------------------------------------------------------- // processAudio @@ -48,8 +48,13 @@ float* outBuffer[MAX_OUTPORTS]; static int processAudio(jack_nframes_t nFrames, void*) { int nch = mess->channels(); - for (int i = 0; i < nch; ++i) + for (int i = 0; i < nch; ++i) { outBuffer[i] = (float*)jack_port_get_buffer(outPorts[i], nFrames); + memset(outBuffer[i], 0, sizeof(float) * nFrames); + } + while(mess->eventsPending()) + mess->processEvent(mess->receiveEvent()); + void* midi = jack_port_get_buffer(inPort, nFrames); int n = jack_midi_port_get_info(midi, nFrames)->event_count; unsigned offset = 0; @@ -185,7 +190,7 @@ int main(int argc, char* argv[]) else jack_set_error_function(noJackError); - jack_client_t* client = 0; + jack_client_t* client; int i = 0; QString instanceName; QString s(pluginName.left(pluginName.size()-3)); @@ -193,7 +198,7 @@ int main(int argc, char* argv[]) static const int MAX_INSTANCES = 500; for (i = 0; i < MAX_INSTANCES; ++i) { instanceName = s.arg(i); - const char* jackIdString = instanceName.toLocal8Bit().data(); + const char* jackIdString = strdup(instanceName.toLocal8Bit().data()); client = jack_client_new(jackIdString); if (client) break; @@ -247,6 +252,7 @@ int main(int argc, char* argv[]) JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); if (mess->hasGui()) mess->showGui(true); + jack_activate(client); qApp->exec(); } -- cgit v1.2.3