summaryrefslogtreecommitdiff
path: root/muse2/muse/driver
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/driver')
-rw-r--r--muse2/muse/driver/CMakeLists.txt11
-rw-r--r--muse2/muse/driver/alsamidi.cpp392
-rw-r--r--muse2/muse/driver/alsamidi.h35
-rw-r--r--muse2/muse/driver/alsatimer.cpp15
-rw-r--r--muse2/muse/driver/alsatimer.h15
-rw-r--r--muse2/muse/driver/audiodev.h15
-rw-r--r--muse2/muse/driver/dummyaudio.cpp77
-rw-r--r--muse2/muse/driver/jack.cpp137
-rw-r--r--muse2/muse/driver/jackaudio.h20
-rw-r--r--muse2/muse/driver/jackmidi.cpp898
-rw-r--r--muse2/muse/driver/jackmidi.h104
-rw-r--r--muse2/muse/driver/rtctimer.cpp25
-rw-r--r--muse2/muse/driver/rtctimer.h17
-rw-r--r--muse2/muse/driver/timerdev.h15
14 files changed, 634 insertions, 1142 deletions
diff --git a/muse2/muse/driver/CMakeLists.txt b/muse2/muse/driver/CMakeLists.txt
index 0f9857f1..2833da04 100644
--- a/muse2/muse/driver/CMakeLists.txt
+++ b/muse2/muse/driver/CMakeLists.txt
@@ -3,10 +3,12 @@
# Linux Music Editor
# $Id:$
#
-# Copyright (C) 2002-2006 by Werner Schweer and others
+# Copyright (C) 1999-2011 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.
+# it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -14,8 +16,9 @@
# 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.
+# along with this program; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#=============================================================================
##
diff --git a/muse2/muse/driver/alsamidi.cpp b/muse2/muse/driver/alsamidi.cpp
index c7ae07b5..9a62dbdd 100644
--- a/muse2/muse/driver/alsamidi.cpp
+++ b/muse2/muse/driver/alsamidi.cpp
@@ -3,6 +3,22 @@
// Linux Music Editor
// $Id: alsamidi.cpp,v 1.8.2.7 2009/11/19 04:20:33 terminator356 Exp $
// (C) Copyright 2000-2001 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#include <stdio.h>
@@ -10,16 +26,18 @@
#include "alsamidi.h"
#include "globals.h"
#include "midi.h"
-#include "mididev.h"
+//#include "mididev.h"
#include "../midiport.h"
#include "../midiseq.h"
#include "../midictrl.h"
#include "../audio.h"
-#include "mpevent.h"
+//#include "mpevent.h"
//#include "sync.h"
#include "utils.h"
#include "audiodev.h"
#include "xml.h"
+#include "part.h"
+#include "gconfig.h"
static int alsaSeqFdi = -1;
static int alsaSeqFdo = -1;
@@ -35,6 +53,8 @@ MidiAlsaDevice::MidiAlsaDevice(const snd_seq_addr_t& a, const QString& n)
: MidiDevice(n)
{
adr = a;
+ stopPending = false;
+ seekPending = false;
init();
}
@@ -117,7 +137,7 @@ void MidiAlsaDevice::close()
// Allocated on stack, no need to call snd_seq_port_subscribe_free() later.
snd_seq_port_subscribe_alloca(&subs);
- // Changed by T356. This function appears to be called only by MidiPort::setMidiDevice(),
+ // This function appears to be called only by MidiPort::setMidiDevice(),
// which closes then opens the device.
// Because the open flags are set BEFORE setMidiDevice() is called, we must ignore the flags.
//
@@ -131,7 +151,7 @@ void MidiAlsaDevice::close()
// dst 16:0
// only sometimes (not when playing notes), but with jack midi turned on,
// we don't get the messages. With jack stopped we get the messages
- // no matter if jack midi is turned on or not.
+ // no matter if jack midi is turned on or not. Tim.
//if (_openFlags & 1) {
//if (!(_openFlags & 1))
@@ -176,95 +196,27 @@ void MidiAlsaDevice::close()
void MidiAlsaDevice::writeRouting(int level, Xml& xml) const
{
- // p3.3.45
// If this device is not actually in use by the song, do not write any routes.
- // This prevents bogus routes from being saved and propagated in the med file.
+ // This prevents bogus routes from being saved and propagated in the med file. Tim.
if(midiPort() == -1)
return;
QString s;
- /*
- //if(rwFlags() & 2) // Readable
- {
- //RouteList* rl = _inRoutes;
- //for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- for (ciRoute r = _inRoutes.begin(); r != _inRoutes.end(); ++r)
- {
- // Since an ALSA midi device supports read + write, this is the only way we can tell if this route is using the device as input.
- if(r->type == Route::TRACK_ROUTE)
- continue;
-
- if(!r->name().isEmpty())
- {
- xml.tag(level++, "Route");
-
- //xml.strTag(level, "srcNode", r->name());
- xml.tag(level, "source type=\"%d\" name=\"%s\"/", r->type, r->name().toLatin1().constData());
-
- //xml.strTag(level, "dstNode", name());
- xml.tag(level, "dest type=\"%d\" name=\"%s\"/", Route::ALSA_MIDI_ROUTE, name().toLatin1().constData());
-
- xml.etag(level--, "Route");
- }
- }
- }
- */
-
for (ciRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r)
{
- //if(r->type != Route::TRACK_ROUTE)
- //{
- // printf("MidiAlsaDevice::writeRouting Warning out route is not TRACK_ROUTE type\n");
- // continue;
- //}
-
if(!r->name().isEmpty())
{
- //xml.tag(level++, "Route");
-
s = QT_TRANSLATE_NOOP("@default", "Route");
if(r->channel != -1)
s += QString(QT_TRANSLATE_NOOP("@default", " channel=\"%1\"")).arg(r->channel);
xml.tag(level++, s.toLatin1().constData());
-
- /*
- //xml.strTag(level, "srcNode", name());
- if(r->channel != -1)
- //xml.tag(level, "source type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::ALSA_MIDI_ROUTE, r->channel, name().toLatin1().constData());
- //xml.tag(level, "source type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::MIDI_DEVICE_ROUTE, r->channel, name().toLatin1().constData());
- xml.tag(level, "source devtype=\"%d\" channel=\"%d\" name=\"%s\"/", MidiDevice::ALSA_MIDI, r->channel, name().toLatin1().constData());
- else
- //xml.tag(level, "source type=\"%d\" name=\"%s\"/", Route::ALSA_MIDI_ROUTE, name().toLatin1().constData());
- //xml.tag(level, "source type=\"%d\" name=\"%s\"/", Route::MIDI_DEVICE_ROUTE, name().toLatin1().constData());
- */
- //xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::ALSA_MIDI, name().toLatin1().constData());
- xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::ALSA_MIDI, Xml::xmlString(name()).toLatin1().constData());
-
- /*
- //xml.strTag(level, "dstNode", r->name());
- if(r->channel != -1)
- {
- if(r->type == Route::MIDI_DEVICE_ROUTE)
- xml.tag(level, "dest devtype=\"%d\" channel=\"%d\" name=\"%s\"/", r->device->deviceType(), r->channel, r->name().toLatin1().constData());
- else
- xml.tag(level, "dest type=\"%d\" channel=\"%d\" name=\"%s\"/", r->type, r->channel, r->name().toLatin1().constData());
- }
- else
- {
- if(r->type == Route::MIDI_DEVICE_ROUTE)
- xml.tag(level, "dest devtype=\"%d\" name=\"%s\"/", r->device->deviceType(), r->name().toLatin1().constData());
- else
- xml.tag(level, "dest type=\"%d\" name=\"%s\"/", r->type, r->name().toLatin1().constData());
- }
- */
-
+ xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::ALSA_MIDI, Xml::xmlString(name()).toLatin1().constData());
s = QT_TRANSLATE_NOOP("@default", "dest");
if(r->type == Route::MIDI_DEVICE_ROUTE)
s += QString(QT_TRANSLATE_NOOP("@default", " devtype=\"%1\"")).arg(r->device->deviceType());
else
if(r->type != Route::TRACK_ROUTE)
s += QString(QT_TRANSLATE_NOOP("@default", " type=\"%1\"")).arg(r->type);
- //s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(r->name());
s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(r->name()));
xml.tag(level, s.toLatin1().constData());
@@ -279,7 +231,7 @@ void MidiAlsaDevice::writeRouting(int level, Xml& xml) const
bool MidiAlsaDevice::putMidiEvent(const MidiPlayEvent& e)
{
- if (midiOutputTrace) {
+ if (MusEGlobal::midiOutputTrace) {
printf("MidiOut: midiAlsa: ");
e.dump();
}
@@ -311,12 +263,9 @@ bool MidiAlsaDevice::putMidiEvent(const MidiPlayEvent& e)
int a = e.dataA();
int b = e.dataB();
int chn = e.channel();
- // p3.3.37
- //if (a < 0x1000) { // 7 Bit Controller
if (a < CTRL_14_OFFSET) { // 7 Bit Controller
snd_seq_ev_set_controller(&event, chn, a, b);
}
- //else if (a < 0x20000) { // 14 bit high resolution controller
else if (a < CTRL_RPN_OFFSET) { // 14 bit high resolution controller
int ctrlH = (a >> 8) & 0x7f;
int ctrlL = a & 0x7f;
@@ -324,7 +273,6 @@ bool MidiAlsaDevice::putMidiEvent(const MidiPlayEvent& e)
snd_seq_ev_set_controller(&event, chn, a, b);
event.type = SND_SEQ_EVENT_CONTROL14;
}
- //else if (a < 0x30000) { // RPN 7-Bit Controller
else if (a < CTRL_NRPN_OFFSET) { // RPN 7-Bit Controller
int ctrlH = (a >> 8) & 0x7f;
int ctrlL = a & 0x7f;
@@ -333,7 +281,6 @@ bool MidiAlsaDevice::putMidiEvent(const MidiPlayEvent& e)
snd_seq_ev_set_controller(&event, chn, a, b);
event.type = SND_SEQ_EVENT_REGPARAM;
}
- //else if (a < 0x40000) { // NRPN 7-Bit Controller
else if (a < CTRL_INTERNAL_OFFSET) { // NRPN 7-Bit Controller
int ctrlH = (a >> 8) & 0x7f;
int ctrlL = a & 0x7f;
@@ -342,7 +289,6 @@ bool MidiAlsaDevice::putMidiEvent(const MidiPlayEvent& e)
snd_seq_ev_set_controller(&event, chn, a, b);
event.type = SND_SEQ_EVENT_NONREGPARAM;
}
- //else if (a < 0x60000) { // RPN14 Controller
else if (a < CTRL_NRPN14_OFFSET) { // RPN14 Controller
int ctrlH = (a >> 8) & 0x7f;
int ctrlL = a & 0x7f;
@@ -350,7 +296,6 @@ bool MidiAlsaDevice::putMidiEvent(const MidiPlayEvent& e)
snd_seq_ev_set_controller(&event, chn, a, b);
event.type = SND_SEQ_EVENT_REGPARAM;
}
- //else if (a < 0x70000) { // NRPN14 Controller
else if (a < CTRL_NONE_OFFSET) { // NRPN14 Controller
int ctrlH = (a >> 8) & 0x7f;
int ctrlL = a & 0x7f;
@@ -451,13 +396,257 @@ bool MidiAlsaDevice::putEvent(snd_seq_event_t* event)
}
//---------------------------------------------------------
+// processMidi
+// Called from ALSA midi sequencer thread only.
+//---------------------------------------------------------
+
+void MidiAlsaDevice::processMidi()
+{
+ bool stop = stopPending; // Snapshots
+ bool seek = seekPending; //
+ seekPending = stopPending = false;
+ // Transfer the stuck notes FIFO to the play events list.
+ // FIXME It would be faster to have MidiAlsaDevice automatically add the stuck note so that only
+ // one FIFO would be needed. But that requires passing an extra 'tick' and 'off velocity' in
+ // addScheduledEvent, which felt too weird.
+ while(!stuckNotesFifo.isEmpty())
+ _stuckNotes.add(stuckNotesFifo.get());
+
+ bool extsync = extSyncFlag.value();
+ //int frameOffset = getFrameOffset();
+ //int nextTick = audio->nextTick();
+
+ // We're in the ALSA midi thread. audio->isPlaying() might not be true during seek right now.
+ //if(stop || (seek && audio->isPlaying()))
+ if(stop || seek)
+ {
+ //---------------------------------------------------
+ // Clear all notes and handle stuck notes
+ //---------------------------------------------------
+ playEventFifo.clear();
+ _playEvents.clear();
+ //printf("transferring stuck notes\n");
+ for(iMPEvent i = _stuckNotes.begin(); i != _stuckNotes.end(); ++i)
+ {
+ //printf(" stuck note\n");
+ MidiPlayEvent ev = *i;
+ ev.setTime(0);
+ _playEvents.add(ev);
+ }
+ _stuckNotes.clear();
+ }
+ else
+ {
+ // Transfer the play events FIFO to the play events list.
+ while(!playEventFifo.isEmpty())
+ _playEvents.add(playEventFifo.get());
+
+ /* TODO Handle these more directly than putting them into play events list.
+ //if(audio->isPlaying())
+ {
+ iMPEvent k;
+ for (k = _stuckNotes.begin(); k != _stuckNotes.end(); ++k) {
+ if (k->time() >= nextTick)
+ break;
+ MidiPlayEvent ev(*k);
+ if(extsync) // p3.3.25
+ ev.setTime(k->time());
+ else
+ ev.setTime(tempomap.tick2frame(k->time()) + frameOffset);
+ _playEvents.add(ev);
+ }
+ _stuckNotes.erase(_stuckNotes.begin(), k);
+ }
+ */
+ processStuckNotes();
+ }
+
+ /* Instead, done immediately in handleStop and handleSeek using putEvent.
+ if(stop)
+ {
+ // reset sustain...
+ MidiPort* mp = &midiPorts[_port];
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ {
+ if(mp->hwCtrlState(ch, CTRL_SUSTAIN) == 127)
+ {
+ //printf("send clear sustain!!!!!!!! port %d ch %d\n", i,ch);
+ MidiPlayEvent ev(0, _port, ch, ME_CONTROLLER, CTRL_SUSTAIN, 0);
+ _playEvents.add(ev);
+ }
+ }
+ }
+ if(seek)
+ {
+ // Send new contoller values...
+ for(iMidiCtrlValList ivl = cll->begin(); ivl != cll->end(); ++ivl)
+ {
+ MidiCtrlValList* vl = ivl->second;
+ iMidiCtrlVal imcv = vl->iValue(pos);
+ if(imcv != vl->end()) {
+ Part* p = imcv->second.part;
+ unsigned t = (unsigned)imcv->first;
+ // Do not add values that are outside of the part.
+ if(p && t >= p->tick() && t < (p->tick() + p->lenTick()) )
+ _playEvents.add(MidiPlayEvent(0, _port, ivl->first >> 24, ME_CONTROLLER, vl->num(), imcv->second.val));
+ }
+ }
+ } */
+
+ if (_playEvents.empty())
+ return;
+
+ int port = midiPort();
+ MidiPort* mp = port != -1 ? &midiPorts[port] : 0;
+ unsigned curFrame = audio->curFrame();
+ int tickpos = audio->tickPos();
+
+ // Play all events up to current frame.
+ iMPEvent i = _playEvents.begin();
+ for (; i != _playEvents.end(); ++i) {
+ if (i->time() > (extsync ? tickpos : curFrame)) // p3.3.25 Check: Should be nextTickPos? p4.0.34
+ break;
+ if(mp){
+ if (mp->sendEvent(*i))
+ break;
+ }
+ else
+ if(putMidiEvent(*i))
+ break;
+ }
+ _playEvents.erase(_playEvents.begin(), i);
+}
+
+//---------------------------------------------------------
+// handleStop
+//---------------------------------------------------------
+
+void MidiAlsaDevice::handleStop()
+{
+ // If the device is not in use by a port, don't bother it.
+ if(_port == -1)
+ return;
+
+ stopPending = true; // Trigger stop handling in processMidi.
+
+ //---------------------------------------------------
+ // reset sustain
+ //---------------------------------------------------
+
+ MidiPort* mp = &midiPorts[_port];
+ for(int ch = 0; ch < MIDI_CHANNELS; ++ch)
+ {
+ if(mp->hwCtrlState(ch, CTRL_SUSTAIN) == 127)
+ {
+ //printf("send clear sustain!!!!!!!! port %d ch %d\n", i,ch);
+ MidiPlayEvent ev(0, _port, ch, ME_CONTROLLER, CTRL_SUSTAIN, 0);
+ putMidiEvent(ev);
+ }
+ }
+
+ //---------------------------------------------------
+ // send midi stop
+ //---------------------------------------------------
+
+ // Don't send if external sync is on. The master, and our sync routing system will take care of that.
+ if(!extSyncFlag.value())
+ {
+ // Shall we check open flags?
+ //if(!(dev->rwFlags() & 0x1) || !(dev->openFlags() & 1))
+ //if(!(dev->openFlags() & 1))
+ // return;
+
+ MidiSyncInfo& si = mp->syncInfo();
+ if(si.MMCOut())
+ mp->sendMMCStop();
+
+ if(si.MRTOut())
+ {
+ // Send STOP
+ mp->sendStop();
+
+ // Added check of option send continue not start. p3.3.31
+ // Hmm, is this required? Seems to make other devices unhappy.
+ // (Could try now that this is in MidiDevice. p4.0.22 )
+ //if(!si.sendContNotStart())
+ // mp->sendSongpos(audio->tickPos() * 4 / config.division);
+ }
+ }
+}
+
+//---------------------------------------------------------
+// handleSeek
+//---------------------------------------------------------
+
+void MidiAlsaDevice::handleSeek()
+{
+ // If the device is not in use by a port, don't bother it.
+ if(_port == -1)
+ return;
+
+ seekPending = true; // Trigger seek handling in processMidi.
+
+ MidiPort* mp = &midiPorts[_port];
+ MidiCtrlValListList* cll = mp->controller();
+ int pos = audio->tickPos();
+
+ //---------------------------------------------------
+ // Send new contoller values
+ //---------------------------------------------------
+
+ for(iMidiCtrlValList ivl = cll->begin(); ivl != cll->end(); ++ivl)
+ {
+ MidiCtrlValList* vl = ivl->second;
+ iMidiCtrlVal imcv = vl->iValue(pos);
+ if(imcv != vl->end())
+ {
+ Part* p = imcv->second.part;
+ unsigned t = (unsigned)imcv->first;
+ // Do not add values that are outside of the part.
+ if(p && t >= p->tick() && t < (p->tick() + p->lenTick()) )
+ //_playEvents.add(MidiPlayEvent(0, _port, ivl->first >> 24, ME_CONTROLLER, vl->num(), imcv->second.val));
+ // Hmm, play event list for immediate playback? Try putEvent instead. p4.0.34
+ putMidiEvent(MidiPlayEvent(0, _port, ivl->first >> 24, ME_CONTROLLER, vl->num(), imcv->second.val));
+ }
+ }
+
+ //---------------------------------------------------
+ // Send STOP and "set song position pointer"
+ //---------------------------------------------------
+
+ // Don't send if external sync is on. The master, and our sync routing system will take care of that. p3.3.31
+ if(!extSyncFlag.value())
+ {
+ if(mp->syncInfo().MRTOut())
+ {
+ // Shall we check for device write open flag to see if it's ok to send?...
+ // This means obey what the user has chosen for read/write in the midi port config dialog,
+ // which already takes into account whether the device is writable or not.
+ //if(!(rwFlags() & 0x1) || !(openFlags() & 1))
+ //if(!(openFlags() & 1))
+ // continue;
+
+ int beat = (pos * 4) / MusEConfig::config.division;
+
+ //bool isPlaying = (state == PLAY);
+ bool isPlaying = audio->isPlaying(); // TODO Check this it includes LOOP1 and LOOP2 besides PLAY. p4.0.22
+
+ mp->sendStop();
+ mp->sendSongpos(beat);
+ if(isPlaying)
+ mp->sendContinue();
+ }
+ }
+}
+
+//---------------------------------------------------------
// initMidiAlsa
// return true on error
//---------------------------------------------------------
bool initMidiAlsa()
{
- if (debugMsg)
+ if (MusEGlobal::debugMsg)
printf("initMidiAlsa\n");
int error = snd_seq_open(&alsaSeq, "hw", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK);
if (error < 0) {
@@ -495,7 +684,7 @@ bool initMidiAlsa()
if (capability & inCap)
flags |= 2;
dev->setrwFlags(flags);
- if (debugMsg)
+ if (MusEGlobal::debugMsg)
printf("ALSA port add: <%s>, %d:%d flags %d 0x%0x\n",
snd_seq_port_info_get_name(pinfo),
adr.client, adr.port,
@@ -524,7 +713,6 @@ bool initMidiAlsa()
}
}
- // p3.3.38
//snd_seq_set_client_name(alsaSeq, "MusE Sequencer");
snd_seq_set_client_name(alsaSeq, audioDevice->clientName());
@@ -750,7 +938,7 @@ void alsaProcessMidiInput()
}
if (mdev == 0 || curPort == -1) {
- if (debugMsg) {
+ if (MusEGlobal::debugMsg) {
fprintf(stderr, "no port %d:%d found for received alsa event\n",
ev->source.client, ev->source.port);
}
@@ -758,31 +946,6 @@ void alsaProcessMidiInput()
return;
}
- /*
- if(curPort == -1)
- {
- if(mdev == 0)
- {
- if (debugMsg)
- {
- fprintf(stderr, "no port %d:%d found for received alsa event\n",
- ev->source.client, ev->source.port);
- }
- }
- else
- {
- // Allow the sync detect mechanisms to work, even if device is not assigned to a port.
- if(ev->type == SND_SEQ_EVENT_CLOCK)
- mdev->syncInfo().trigMCSyncDetect();
- else
- if(ev->type == SND_SEQ_EVENT_TICK)
- mdev->syncInfo().trigTickDetect();
- }
- snd_seq_free_event(ev);
- return;
- }
- */
-
event.setType(0); // mark as unused
event.setPort(curPort);
event.setB(0);
@@ -852,7 +1015,6 @@ void alsaProcessMidiInput()
break;
case SND_SEQ_EVENT_SYSEX:
-
// TODO: Deal with large sysex, which are broken up into chunks!
// For now, do not accept if the first byte is not SYSEX or the last byte is not EOX,
// meaning it's a chunk, possibly with more chunks to follow.
@@ -901,13 +1063,7 @@ void alsaProcessMidiInput()
break;
}
if(event.type())
- {
mdev->recordEvent(event);
- // p3.3.26 1/23/10 Moved to MidiDevice now. Anticipating Jack midi support, so don't make it ALSA specific. Tim.
- //if(ev->type != SND_SEQ_EVENT_SYSEX)
- // Trigger general activity indicator detector. Sysex has no channel, don't trigger.
- // midiPorts[curPort].syncInfo().trigActDetect(event.channel());
- }
snd_seq_free_event(ev);
if (rv == 0)
diff --git a/muse2/muse/driver/alsamidi.h b/muse2/muse/driver/alsamidi.h
index a2480c5c..13e07ca4 100644
--- a/muse2/muse/driver/alsamidi.h
+++ b/muse2/muse/driver/alsamidi.h
@@ -3,6 +3,22 @@
// Linux Music Editor
// $Id: alsamidi.h,v 1.2 2004/01/14 09:06:43 wschweer Exp $
// (C) Copyright 2001 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#ifndef __ALSAMIDI_H__
@@ -11,6 +27,7 @@
#include <config.h>
#include <alsa/asoundlib.h>
+#include "mpevent.h"
#include "mididev.h"
class Xml;
@@ -24,6 +41,13 @@ class MidiAlsaDevice : public MidiDevice {
snd_seq_addr_t adr;
private:
+ // Special for ALSA midi device: Play event list is processed in the ALSA midi sequencer thread.
+ // Need this FIFO, to decouple from audio thread which adds events to the list.
+ MidiFifo playEventFifo;
+ MidiFifo stuckNotesFifo;
+ volatile bool stopPending;
+ volatile bool seekPending;
+
virtual QString open();
virtual void close();
virtual void processInput() {}
@@ -34,17 +58,22 @@ class MidiAlsaDevice : public MidiDevice {
virtual bool putMidiEvent(const MidiPlayEvent&);
public:
- //MidiAlsaDevice() {} // p3.3.55 Removed
MidiAlsaDevice(const snd_seq_addr_t&, const QString& name);
virtual ~MidiAlsaDevice() {}
- //virtual void* clientPort() { return (void*)&adr; }
- // p3.3.55
virtual void* inClientPort() { return (void*)&adr; } // For ALSA midi, in/out client ports are the same.
virtual void* outClientPort() { return (void*)&adr; } // That is, ALSA midi client ports can be both r/w.
virtual void writeRouting(int, Xml&) const;
virtual inline int deviceType() const { return ALSA_MIDI; }
+ // Schedule an event for playback. Returns false if event cannot be delivered.
+ virtual bool addScheduledEvent(const MidiPlayEvent& ev) { return !playEventFifo.put(ev); }
+ // Add a stuck note. Returns false if event cannot be delivered.
+ virtual bool addStuckNote(const MidiPlayEvent& ev) { return !stuckNotesFifo.put(ev); }
+ // Play all events up to current frame.
+ virtual void processMidi();
+ virtual void handleStop();
+ virtual void handleSeek();
};
extern bool initMidiAlsa();
diff --git a/muse2/muse/driver/alsatimer.cpp b/muse2/muse/driver/alsatimer.cpp
index d851410d..dee661fe 100644
--- a/muse2/muse/driver/alsatimer.cpp
+++ b/muse2/muse/driver/alsatimer.cpp
@@ -7,6 +7,21 @@
// alsalib 1.0.7
//
// (C) Copyright 2004 Robert Jonsson (rj@spamatica.se)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#include "alsatimer.h"
diff --git a/muse2/muse/driver/alsatimer.h b/muse2/muse/driver/alsatimer.h
index 211ba5ec..b906c02d 100644
--- a/muse2/muse/driver/alsatimer.h
+++ b/muse2/muse/driver/alsatimer.h
@@ -7,6 +7,21 @@
// alsalib 1.0.7
//
// (C) Copyright 2004 Robert Jonsson (rj@spamatica.se)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#ifndef __ALSATIMER_H__
diff --git a/muse2/muse/driver/audiodev.h b/muse2/muse/driver/audiodev.h
index 4685b89a..3fe06fb9 100644
--- a/muse2/muse/driver/audiodev.h
+++ b/muse2/muse/driver/audiodev.h
@@ -4,6 +4,21 @@
// $Id: audiodev.h,v 1.5.2.2 2009/12/20 05:00:35 terminator356 Exp $
//
// (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#ifndef __AUDIODEV_H__
diff --git a/muse2/muse/driver/dummyaudio.cpp b/muse2/muse/driver/dummyaudio.cpp
index 55f091c2..4466e293 100644
--- a/muse2/muse/driver/dummyaudio.cpp
+++ b/muse2/muse/driver/dummyaudio.cpp
@@ -3,6 +3,21 @@
// Linux Music Editor
// $Id: dummyaudio.cpp,v 1.3.2.16 2009/12/20 05:00:35 terminator356 Exp $
// (C) Copyright 2002-2003 Werner Schweer (ws@seh.de)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#include <stdio.h>
@@ -83,7 +98,7 @@ class DummyAudioDevice : public AudioDevice {
// p3.3.30
//if (nframes > dummyFrames) {
//printf("error: segment size > 1024\n");
- if (nframes > segmentSize) {
+ if (nframes > MusEGlobal::segmentSize) {
printf("DummyAudioDevice::getBuffer nframes > segment size\n");
exit(-1);
@@ -125,7 +140,7 @@ class DummyAudioDevice : public AudioDevice {
return _framePos; }
virtual unsigned frameTime() const {
- return lrint(curTime() * sampleRate);
+ return lrint(MusEUtil::curTime() * MusEGlobal::sampleRate);
}
virtual bool isRealtime() { return realtimeFlag; }
//virtual int realtimePriority() const { return 40; }
@@ -200,18 +215,20 @@ DummyAudioDevice::DummyAudioDevice()
// Added by Tim. p3.3.15
// p3.3.30
//posix_memalign((void**)&buffer, 16, sizeof(float) * dummyFrames);
- posix_memalign((void**)&buffer, 16, sizeof(float) * config.dummyAudioBufSize);
+ posix_memalign((void**)&buffer, 16, sizeof(float) * MusEConfig::config.dummyAudioBufSize);
dummyThread = 0;
realtimeFlag = false;
seekflag = false;
state = Audio::STOP;
- //startTime = curTime();
+ //startTime = MusEUtil::curTime();
_framePos = 0;
playPos = 0;
cmdQueue.clear();
}
+namespace MusEApp {
+
//---------------------------------------------------------
// exitDummyAudio
//---------------------------------------------------------
@@ -224,6 +241,8 @@ void exitDummyAudio()
audioDevice = NULL;
}
+} // namespace MusEApp
+
//---------------------------------------------------------
// initDummyAudio
//---------------------------------------------------------
@@ -274,13 +293,13 @@ static void* dummyLoop(void* ptr)
//unsigned int tickRate = 25;
// p3.3.30
- //sampleRate = 25600;
- sampleRate = config.dummyAudioSampleRate;
- //segmentSize = dummyFrames;
- segmentSize = config.dummyAudioBufSize;
+ //MusEGlobal::sampleRate = 25600;
+ MusEGlobal::sampleRate = MusEConfig::config.dummyAudioSampleRate;
+ //MusEGlobal::segmentSize = dummyFrames;
+ MusEGlobal::segmentSize = MusEConfig::config.dummyAudioBufSize;
#if 0
- //unsigned int tickRate = sampleRate / dummyFrames;
- unsigned int tickRate = sampleRate / segmentSize;
+ //unsigned int tickRate = MusEGlobal::sampleRate / dummyFrames;
+ unsigned int tickRate = MusEGlobal::sampleRate / MusEGlobal::segmentSize;
AlsaTimer timer;
fprintf(stderr, "Get alsa timer for dummy driver:\n");
@@ -297,7 +316,7 @@ static void* dummyLoop(void* ptr)
/* Depending on nature of the timer, the requested tickRate might not
* be available. The return value is the nearest available frequency,
- * so use this to reset our dummpy sampleRate to keep everything
+ * so use this to reset our dummpy MusEGlobal::sampleRate to keep everything
* consistent.
*/
tickRate = timer.setTimerFreq( /*250*/ tickRate );
@@ -307,7 +326,7 @@ static void* dummyLoop(void* ptr)
if(tickRate == 0)
tickRate = timer.getTimerFreq();
- sampleRate = tickRate * segmentSize;
+ MusEGlobal::sampleRate = tickRate * MusEGlobal::segmentSize;
timer.startTimer();
#endif
@@ -320,7 +339,7 @@ static void* dummyLoop(void* ptr)
/*
- doSetuid();
+ MusEGlobal::doSetuid();
struct sched_param rt_param;
int rv;
memset(&rt_param, 0, sizeof(sched_param));
@@ -349,13 +368,13 @@ static void* dummyLoop(void* ptr)
fprintf(stderr, "Unable to set thread to SCHED_FIFO\n");
}
}
- undoSetuid();
+ MusEGlobal::undoSetuid();
*/
#ifndef __APPLE__
- doSetuid();
+ MusEGlobal::doSetuid();
//if (realTimePriority) {
- if (realTimeScheduling) {
+ if (MusEGlobal::realTimeScheduling) {
//
// check if we really got realtime priviledges
//
@@ -367,7 +386,7 @@ static void* dummyLoop(void* ptr)
{
if (policy != SCHED_FIFO)
printf("audio dummy thread _NOT_ running SCHED_FIFO\n");
- else if (debugMsg) {
+ else if (MusEGlobal::debugMsg) {
struct sched_param rt_param;
memset(&rt_param, 0, sizeof(sched_param));
int type;
@@ -379,7 +398,7 @@ static void* dummyLoop(void* ptr)
}
}
}
- undoSetuid();
+ MusEGlobal::undoSetuid();
#endif
#if 0
@@ -423,8 +442,8 @@ static void* dummyLoop(void* ptr)
}
}
}
- audio->process(segmentSize);
- int increment = segmentSize; // 1 //tickRate / sampleRate * segmentSize;
+ audio->process(MusEGlobal::segmentSize);
+ int increment = MusEGlobal::segmentSize; // 1 //tickRate / MusEGlobal::sampleRate * MusEGlobal::segmentSize;
drvPtr->_framePos+=increment;
if (drvPtr->state == Audio::PLAY)
{
@@ -437,12 +456,12 @@ static void* dummyLoop(void* ptr)
{
//if(audioState == AUDIO_RUNNING)
if(audio->isRunning())
- //audio->process(segmentSize, drvPtr->state);
- audio->process(segmentSize);
+ //audio->process(MusEGlobal::segmentSize, drvPtr->state);
+ audio->process(MusEGlobal::segmentSize);
//else if (audioState == AUDIO_START1)
// audioState = AUDIO_START2;
- //usleep(dummyFrames*1000000/AL::sampleRate);
- usleep(segmentSize*1000000/sampleRate);
+ //usleep(dummyFrames*1000000/AL::MusEGlobal::sampleRate);
+ usleep(MusEGlobal::segmentSize*1000000/MusEGlobal::sampleRate);
//if(dummyAudio->seekflag)
if(drvPtr->seekflag)
{
@@ -456,9 +475,9 @@ static void* dummyLoop(void* ptr)
//if(dummyAudio->state == Audio::PLAY)
// dummyAudio->pos += dummyFrames;
- drvPtr->_framePos += segmentSize;
+ drvPtr->_framePos += MusEGlobal::segmentSize;
if(drvPtr->state == Audio::PLAY)
- drvPtr->playPos += segmentSize;
+ drvPtr->playPos += MusEGlobal::segmentSize;
}
#endif
@@ -472,7 +491,7 @@ void DummyAudioDevice::start(int priority)
_realTimePriority = priority;
pthread_attr_t* attributes = 0;
- if (realTimeScheduling && _realTimePriority > 0) {
+ if (MusEGlobal::realTimeScheduling && _realTimePriority > 0) {
attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t));
pthread_attr_init(attributes);
@@ -499,11 +518,11 @@ void DummyAudioDevice::start(int priority)
int rv = pthread_create(&dummyThread, attributes, ::dummyLoop, this);
if(rv)
{
- // p4.0.16: realTimeScheduling is unreliable. It is true even in some clearly non-RT cases.
+ // p4.0.16: MusEGlobal::realTimeScheduling is unreliable. It is true even in some clearly non-RT cases.
// I cannot seem to find a reliable answer to the question of "are we RT or not".
// MusE was failing with a stock kernel because of PTHREAD_EXPLICIT_SCHED.
// So we'll just have to try again without attributes.
- if (realTimeScheduling && _realTimePriority > 0)
+ if (MusEGlobal::realTimeScheduling && _realTimePriority > 0)
rv = pthread_create(&dummyThread, NULL, ::dummyLoop, this);
}
diff --git a/muse2/muse/driver/jack.cpp b/muse2/muse/driver/jack.cpp
index 529e8a60..31179ea3 100644
--- a/muse2/muse/driver/jack.cpp
+++ b/muse2/muse/driver/jack.cpp
@@ -3,6 +3,21 @@
// Linux Music Editor
// $Id: jack.cpp,v 1.30.2.17 2009/12/20 05:00:35 terminator356 Exp $
// (C) Copyright 2002 Werner Schweer (ws@seh.de)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#include "config.h"
@@ -39,8 +54,8 @@
//#include "errorhandler.h"
#ifndef RTCAP
-extern void doSetuid();
-extern void undoSetuid();
+extern void MusEGlobal::doSetuid();
+extern void MusEGlobal::undoSetuid();
#endif
#ifdef VST_SUPPORT
@@ -69,19 +84,6 @@ inline bool checkJackClient(jack_client_t* _client)
}
return true;
}
-//---------------------------------------------------------
-// checkAudioDevice - make sure audioDevice exists
-//---------------------------------------------------------
-bool checkAudioDevice()
- {
- if (audioDevice == NULL) {
- if(debugMsg)
- printf("Muse:checkAudioDevice: no audioDevice\n");
- return false;
- }
- return true;
- }
-
//---------------------------------------------------------
// jack_thread_init
@@ -89,7 +91,7 @@ bool checkAudioDevice()
static void jack_thread_init (void* ) // data
{
- doSetuid();
+ MusEGlobal::doSetuid();
/*
if (jackAudio->isRealtime()) {
struct sched_param rt_param;
@@ -123,7 +125,7 @@ static void jack_thread_init (void* ) // data
if (loadVST)
fst_adopt_thread();
#endif
- undoSetuid();
+ MusEGlobal::undoSetuid();
}
/*
@@ -272,11 +274,11 @@ int JackAudioDevice::processAudio(jack_nframes_t frames, void*)
// if (JACK_DEBUG)
// printf("processAudio - >>>>\n");
- segmentSize = frames;
+ MusEGlobal::segmentSize = frames;
if (audio->isRunning())
audio->process((unsigned long)frames);
else {
- if (debugMsg)
+ if (MusEGlobal::debugMsg)
puts("jack calling when audio is disconnected!\n");
}
// if (JACK_DEBUG)
@@ -396,7 +398,7 @@ static void processShutdown(void*)
audio->shutdown();
int c=0;
- while(midiSeqRunning == true) {
+ while(MusEGlobal::midiSeqRunning == true) {
if(c++ >10) {
fprintf(stderr, "sequencer still running, something is very wrong.\n");
break;
@@ -540,13 +542,13 @@ bool initJackAudio()
if (JACK_DEBUG)
printf("initJackAudio()\n");
- if (debugMsg) {
+ if (MusEGlobal::debugMsg) {
fprintf(stderr,"initJackAudio()\n");
jack_set_error_function(jackError);
}
else
jack_set_error_function(noJackError);
- doSetuid();
+ MusEGlobal::doSetuid();
//jack_client_t* client = 0;
//int i = 0;
@@ -574,25 +576,25 @@ bool initJackAudio()
if (status & JackVersionError)
printf("jack server has wrong version\n");
printf("cannot create jack client\n");
- undoSetuid(); // p3.3.51
+ MusEGlobal::undoSetuid(); // p3.3.51
return true;
}
- if (debugMsg)
+ if (MusEGlobal::debugMsg)
fprintf(stderr, "initJackAudio(): client %s opened.\n", jack_get_client_name(client));
if (client) {
jack_set_error_function(jackError);
//jackAudio = new JackAudioDevice(client, jackIdString);
jackAudio = new JackAudioDevice(client, jack_get_client_name(client));
- if (debugMsg)
+ if (MusEGlobal::debugMsg)
fprintf(stderr, "initJackAudio(): registering client...\n");
jackAudio->registerClient();
- sampleRate = jack_get_sample_rate(client);
- segmentSize = jack_get_buffer_size(client);
+ MusEGlobal::sampleRate = jack_get_sample_rate(client);
+ MusEGlobal::segmentSize = jack_get_buffer_size(client);
jack_set_thread_init_callback(client, (JackThreadInitCallback) jack_thread_init, 0);
//jack_set_timebase_callback(client, 0, (JackTimebaseCallback) timebase_callback, 0);
}
- undoSetuid();
+ MusEGlobal::undoSetuid();
/*
// setup midi input/output
@@ -647,14 +649,14 @@ static int bufsize_callback(jack_nframes_t n, void*)
static void freewheel_callback(int starting, void*)
{
- if (debugMsg || JACK_DEBUG)
+ if (MusEGlobal::debugMsg || JACK_DEBUG)
printf("JACK: freewheel_callback: starting%d\n", starting);
audio->setFreewheel(starting);
}
static int srate_callback(jack_nframes_t n, void*)
{
- if (debugMsg || JACK_DEBUG)
+ if (MusEGlobal::debugMsg || JACK_DEBUG)
printf("JACK: sample rate changed: %d\n", n);
return 0;
}
@@ -665,7 +667,7 @@ static int srate_callback(jack_nframes_t n, void*)
static void registration_callback(jack_port_id_t, int, void*)
{
- if(debugMsg || JACK_DEBUG)
+ if(MusEGlobal::debugMsg || JACK_DEBUG)
printf("JACK: registration changed\n");
audio->sendMsgToGui('R');
@@ -743,7 +745,7 @@ void JackAudioDevice::connectJackMidiPorts()
// Ignore our own client ports.
if(jack_port_is_mine(_client, port))
{
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf(" ignoring own port: %s\n", *p);
continue;
}
@@ -754,7 +756,7 @@ void JackAudioDevice::connectJackMidiPorts()
//if(strncmp(buffer, "MusE", 4) == 0)
// continue;
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf(" found port: %s ", buffer);
// If there are aliases for this port, use the first one - much better for identifying.
@@ -770,7 +772,7 @@ void JackAudioDevice::connectJackMidiPorts()
//char* namep = (na >= 1) ? aliases[0] : buffer;
char* namep = aliases[0];
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("alias: %s\n", aliases[0]);
//int flags = 0;
@@ -847,7 +849,7 @@ void JackAudioDevice::connectJackMidiPorts()
static void client_registration_callback(const char *name, int isRegister, void*)
{
- if (debugMsg || JACK_DEBUG)
+ if (MusEGlobal::debugMsg || JACK_DEBUG)
printf("JACK: client registration changed:%s register:%d\n", name, isRegister);
}
@@ -857,7 +859,7 @@ static void client_registration_callback(const char *name, int isRegister, void*
static void port_connect_callback(jack_port_id_t a, jack_port_id_t b, int isConnect, void*)
{
- if (debugMsg || JACK_DEBUG)
+ if (MusEGlobal::debugMsg || JACK_DEBUG)
{
//jack_port_t* ap = jack_port_by_id(_client, a);
//jack_port_t* bp = jack_port_by_id(_client, b);
@@ -880,7 +882,7 @@ static int graph_callback(void*)
// context, so we send a message to the gui thread which in turn
// calls graphChanged()
audio->sendMsgToGui('C');
- if (debugMsg)
+ if (MusEGlobal::debugMsg)
printf("JACK: graph changed\n");
return 0;
}
@@ -1368,6 +1370,26 @@ void* JackAudioDevice::registerOutPort(const char* name, bool midi)
return p;
}
+namespace MusEGlobal {
+
+//---------------------------------------------------------
+// checkAudioDevice - make sure audioDevice exists
+//---------------------------------------------------------
+
+bool checkAudioDevice()
+ {
+ if (audioDevice == NULL) {
+ if(MusEGlobal::debugMsg)
+ printf("Muse:checkAudioDevice: no audioDevice\n");
+ return false;
+ }
+ return true;
+ }
+
+} // namespace MusEGlobal
+
+namespace MusEApp {
+
//---------------------------------------------------------
// exitJackAudio
//---------------------------------------------------------
@@ -1386,6 +1408,7 @@ void exitJackAudio()
audioDevice = NULL;
}
+} // namespace MusEApp
//---------------------------------------------------------
// connect
@@ -1458,10 +1481,10 @@ void JackAudioDevice::start(int /*priority*/)
printf("JackAudioDevice::start()\n");
if(!checkJackClient(_client)) return;
- doSetuid();
+ MusEGlobal::doSetuid();
if (jack_activate(_client)) {
- undoSetuid(); // p3.3.51
+ MusEGlobal::undoSetuid(); // p3.3.51
fprintf (stderr, "JACK: cannot activate client\n");
exit(-1);
}
@@ -1503,7 +1526,7 @@ void JackAudioDevice::start(int /*priority*/)
// Connect the Jack midi client ports to device ports.
connectJackMidiPorts();
- undoSetuid();
+ MusEGlobal::undoSetuid();
//MUSE_DEBUG("JackAudioDevice::start()\n");
fflush(stdin);
@@ -1594,7 +1617,7 @@ int JackAudioDevice::framesSinceCycleStart() const
int JackAudioDevice::frameDelay() const
{
- jack_nframes_t n = (segmentSize * (segmentCount-1)) - jack_frames_since_cycle_start(client);
+ jack_nframes_t n = (MusEGlobal::segmentSize * (segmentCount-1)) - jack_frames_since_cycle_start(client);
return (int)n;
}
#endif
@@ -1625,7 +1648,7 @@ std::list<QString> JackAudioDevice::outputPorts(bool midi, int aliases)
strncpy(buffer, *p, nsz);
//if (strncmp(buffer, "MusE", 4) == 0)
//{
- // if(debugMsg)
+ // if(MusEGlobal::debugMsg)
// printf("JackAudioDevice::outputPorts ignoring own MusE port: %s\n", *p);
// continue;
//}
@@ -1633,7 +1656,7 @@ std::list<QString> JackAudioDevice::outputPorts(bool midi, int aliases)
// Ignore our own client ports.
if(jack_port_is_mine(_client, port))
{
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("JackAudioDevice::outputPorts ignoring own port: %s\n", *p);
continue;
}
@@ -1698,7 +1721,7 @@ std::list<QString> JackAudioDevice::inputPorts(bool midi, int aliases)
strncpy(buffer, *p, nsz);
//if (strncmp(buffer, "MusE", 4) == 0)
//{
- // if(debugMsg)
+ // if(MusEGlobal::debugMsg)
// printf("JackAudioDevice::inputPorts ignoring own MusE port: %s\n", *p);
// continue;
//}
@@ -1706,7 +1729,7 @@ std::list<QString> JackAudioDevice::inputPorts(bool midi, int aliases)
// Ignore our own client ports.
if(jack_port_is_mine(_client, port))
{
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("JackAudioDevice::inputPorts ignoring own port: %s\n", *p);
continue;
}
@@ -1842,14 +1865,14 @@ void JackAudioDevice::setFreewheel(bool f)
bool JackAudioDevice::dummySync(int state)
{
// Roughly segment time length.
- //timespec ts = { 0, (1000000000 * segmentSize) / sampleRate }; // In nanoseconds.
- unsigned int sl = (1000000 * segmentSize) / sampleRate; // In microseconds.
+ //timespec ts = { 0, (1000000000 * MusEGlobal::segmentSize) / MusEGlobal::sampleRate }; // In nanoseconds.
+ unsigned int sl = (1000000 * MusEGlobal::segmentSize) / MusEGlobal::sampleRate; // In microseconds.
- double ct = curTime();
+ double ct = MusEUtil::curTime();
// Wait for a default maximum of 5 seconds.
// Similar to how Jack is supposed to wait a default of 2 seconds for slow clients.
// TODO: Make this timeout a 'settings' option so it can be applied both to Jack and here.
- while((curTime() - ct) < 5.0)
+ while((MusEUtil::curTime() - ct) < 5.0)
{
// Is MusE audio ready to roll?
if(audio->sync(state, dummyPos))
@@ -2057,7 +2080,7 @@ int JackAudioDevice::setMaster(bool f)
{
// Make Muse the Jack timebase master. Do it unconditionally (second param = 0).
r = jack_set_timebase_callback(_client, 0, (JackTimebaseCallback) timebase_callback, 0);
- if(debugMsg || JACK_DEBUG)
+ if(MusEGlobal::debugMsg || JACK_DEBUG)
{
if(r)
printf("JackAudioDevice::setMaster jack_set_timebase_callback failed: result:%d\n", r);
@@ -2072,7 +2095,7 @@ int JackAudioDevice::setMaster(bool f)
else
{
r = jack_release_timebase(_client);
- if(debugMsg || JACK_DEBUG)
+ if(MusEGlobal::debugMsg || JACK_DEBUG)
{
if(r)
printf("JackAudioDevice::setMaster jack_release_timebase failed: result:%d\n", r);
@@ -2087,7 +2110,7 @@ int JackAudioDevice::setMaster(bool f)
void JackAudioDevice::scanMidiPorts()
{
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("JackAudioDevice::scanMidiPorts:\n");
/*
@@ -2103,7 +2126,7 @@ void JackAudioDevice::scanMidiPorts()
// Ignore our own client ports.
if(jack_port_is_mine(_client, port))
{
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf(" ignoring own port: %s\n", *p);
continue;
}
@@ -2115,7 +2138,7 @@ void JackAudioDevice::scanMidiPorts()
//if(strncmp(buffer, "MusE", 4) == 0)
// continue;
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf(" found port: %s ", buffer);
// If there are aliases for this port, use the first one - much better for identifying.
@@ -2131,7 +2154,7 @@ void JackAudioDevice::scanMidiPorts()
//char* namep = (na >= 1) ? aliases[0] : buffer;
//char* namep = aliases[0];
//names.insert(std::string(*p));
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("alias: %s\n", aliases[0]);
names.insert(std::string(aliases[0]));
@@ -2151,7 +2174,7 @@ void JackAudioDevice::scanMidiPorts()
for(std::list<MidiDevice*>::iterator imd = to_del.begin(); imd != to_del.end(); ++imd)
{
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf(" removing port device:%s\n", (*imd)->name().toLatin1());
midiDevices.remove(*imd);
// This will close (and unregister) the client port.
@@ -2212,7 +2235,7 @@ void JackAudioDevice::scanMidiPorts()
//JackPort jp(0, QString(buffer), flags);
//portList.append(jp);
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf(" adding port device:%s\n", qname.toLatin1());
MidiJackDevice* dev = new MidiJackDevice(0, qname);
diff --git a/muse2/muse/driver/jackaudio.h b/muse2/muse/driver/jackaudio.h
index 5be0797f..d116a2ff 100644
--- a/muse2/muse/driver/jackaudio.h
+++ b/muse2/muse/driver/jackaudio.h
@@ -3,6 +3,21 @@
// Linux Music Editor
// $Id: jackaudio.h,v 1.20.2.4 2009/12/20 05:00:35 terminator356 Exp $
// (C) Copyright 2002 Werner Schweer (ws@seh.de)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#ifndef __JACKAUDIO_H__
@@ -13,10 +28,13 @@
class MidiPlayEvent;
+namespace MusEGlobal {
+bool checkAudioDevice();
+}
+
//---------------------------------------------------------
// JackAudioDevice
//---------------------------------------------------------
-bool checkAudioDevice();
class JackAudioDevice : public AudioDevice {
diff --git a/muse2/muse/driver/jackmidi.cpp b/muse2/muse/driver/jackmidi.cpp
index e514af7a..a4577f0b 100644
--- a/muse2/muse/driver/jackmidi.cpp
+++ b/muse2/muse/driver/jackmidi.cpp
@@ -3,6 +3,22 @@
// Linux Music Editor
// $Id: jackmidi.cpp,v 1.1.1.1 2010/01/27 09:06:43 terminator356 Exp $
// (C) Copyright 1999-2010 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#include <QString>
@@ -33,128 +49,16 @@
extern unsigned int volatile lastExtMidiSyncTick;
-///int jackmidi_pi[2];
-///int jackmidi_po[2];
-
-//extern muse_jack_midi_buffer jack_midi_out_data[JACK_MIDI_CHANNELS];
-//extern muse_jack_midi_buffer jack_midi_in_data[JACK_MIDI_CHANNELS];
-///extern jack_port_t *midi_port_in[JACK_MIDI_CHANNELS];
-///extern jack_port_t *midi_port_out[JACK_MIDI_CHANNELS];
-
-///MidiJackDevice* gmdev = NULL;
-
-///int* jackSeq;
-//static snd_seq_addr_t musePort;
-
-//int MidiJackDevice::_nextOutIdNum = 0;
-//int MidiJackDevice::_nextInIdNum = 0;
-
-//int JackMidiPortList::_nextOutIdNum = 0;
-//int JackMidiPortList::_nextInIdNum = 0;
-
-//JackMidiPortList jackMidiClientPorts;
-
-
-/*
-//---------------------------------------------------------
-// JackMidiPortList
-//---------------------------------------------------------
-
-JackMidiPortList::JackMidiPortList()
-{
-
-}
-
-JackMidiPortList::~JackMidiPortList()
-{
-
-}
-
-iJackMidiPort JackMidiPortList::createClientPort(int flags) // 1 = writable, 2 = readable - do not mix
-{
- if(flags & 1)
- {
- char buf[80];
- snprintf(buf, 80, "muse-jack-midi-out-%d", _nextOutIdNum);
- jack_port_t* _client_jackport = (jack_port_t*)audioDevice->registerOutPort(buf, true);
- if(_client_jackport == NULL)
- {
- fprintf(stderr, "JackMidiPortList::createClientPort failed to register jack-midi-out\n");
- //return QString("Could not register jack-midi-out client port");
- return end();
- }
- else
- {
- JackMidiPort jmp(_client_jackport, QString(buf), flags);
- _nextOutIdNum++;
- return insert(begin(), std::pair<jack_port_t*, JackMidiPort>(_client_jackport, jmp));
- }
- }
- else
- if(flags & 2)
- {
- char buf[80];
- snprintf(buf, 80, "muse-jack-midi-in-%d", _nextInIdNum);
- jack_port_t* _client_jackport = (jack_port_t*)audioDevice->registerInPort(buf, true);
- if(_client_jackport == NULL)
- {
- fprintf(stderr, "JackMidiPortList::createClientPort failed to register jack-midi-in\n");
- return end();
- }
- else
- {
- JackMidiPort jmp(_client_jackport, QString(buf), flags);
- _nextInIdNum++;
- return insert(begin(), std::pair<jack_port_t*, JackMidiPort>(_client_jackport, jmp));
- }
- }
- return end();
-}
-
-// Return true if removed.
-bool JackMidiPortList::removeClientPort(jack_port_t* port)
-{
- iJackMidiPort ijp = find(port);
- if(ijp == end())
- return false;
-
- // Is output?
- if(ijp->second._flags & 1)
- _nextOutIdNum--;
- // Is input?
- if(ijp->second._flags & 2)
- _nextInIdNum--;
-
- erase(ijp);
-
- audioDevice->unregisterPort(port);
-
- return true;
-}
-*/
-
//---------------------------------------------------------
// MidiJackDevice
// in_jack_port or out_jack_port can be null
//---------------------------------------------------------
-//MidiJackDevice::MidiJackDevice(const int& a, const QString& n)
-//MidiJackDevice::MidiJackDevice(jack_port_t* jack_port, const QString& n)
-// p3.3.55
-//MidiJackDevice::MidiJackDevice(jack_port_t* in_jack_port, jack_port_t* out_jack_port, const QString& n)
MidiJackDevice::MidiJackDevice(const QString& n)
: MidiDevice(n)
{
- //_client_jackport = 0;
-
- //_client_jackport = jack_port;
- // p3.3.55
- //_in_client_jackport = in_jack_port;
- //_out_client_jackport = out_jack_port;
_in_client_jackport = NULL;
_out_client_jackport = NULL;
-
- //adr = a;
init();
}
@@ -164,10 +68,6 @@ MidiJackDevice::~MidiJackDevice()
printf("MidiJackDevice::~MidiJackDevice()\n");
#endif
- //if(_client_jackport)
- // audioDevice->unregisterPort(_client_jackport);
- // p3.3.55
-
if(audioDevice)
{
if(_in_client_jackport)
@@ -179,69 +79,13 @@ MidiJackDevice::~MidiJackDevice()
//close();
}
-/*
-//---------------------------------------------------------
-// select[RW]fd
-//---------------------------------------------------------
-
-int MidiJackDevice::selectRfd()
-{
- return jackmidi_pi[0];
-}
-
-int MidiJackDevice::selectWfd()
-{
- return jackmidi_po[0];
-}
-*/
-
//---------------------------------------------------------
// createJackMidiDevice
// If name parameter is blank, creates a new (locally) unique one.
//---------------------------------------------------------
-//QString MidiJackDevice::createJackMidiDevice(int rwflags) // 1:Writable 2: Readable. Do not mix.
-//MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1:Writable 2: Readable. Do not mix.
-MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // p3.3.55 1:Writable 2: Readable 3: Writable + Readable
+MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // 1:Writable 2: Readable 3: Writable + Readable
{
-/// _openFlags &= _rwFlags; // restrict to available bits
-
-/// #ifdef JACK_MIDI_DEBUG
-/// printf("MidiJackDevice::open %s\n", name.toLatin1().constData());
-/// #endif
-
- //jack_port_t* jp = jack_port_by_name(_client, name().toLatin1().constData());
-/// jack_port_t* jp = (jack_port_t*)audioDevice->findPort(name().toLatin1().constData());
-
-/// if(!jp)
-/// {
-/// printf("MidiJackDevice::open: Jack midi port %s not found!\n", name().toLatin1().constData());
-/// _writeEnable = false;
-/// _readEnable = false;
-/// return QString("Jack midi port not found");
-/// }
-
-/// int pf = jack_port_flags(jp);
-
- //if(!name.isEmpty())
- //{
- // Does not work.
- // if(audioDevice->findPort(name.toLatin1().constData()))
- // {
- // fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed! Given port name %s already exists!\n", name.toLatin1().constData());
- // return 0;
- // }
- //}
-
- //jack_port_t* client_jackport = NULL;
- // p3.3.55
- ///jack_port_t* in_client_jackport = NULL;
- ///jack_port_t* out_client_jackport = NULL;
-
- //char buf[80];
-
-
- // p3.3.55
int ni = 0;
if(name.isEmpty())
{
@@ -258,188 +102,7 @@ MidiDevice* MidiJackDevice::createJackMidiDevice(QString name, int rwflags) // p
return 0;
}
- // If Jack port can receive data from us and we actually want to...
- //if((pf & JackPortIsInput) && (_openFlags & 1))
- ///if(rwflags & 1)
- ///{
- /* p3.3.55 Removed.
- if(name.isEmpty())
- {
- //snprintf(buf, 80, "muse-jack-midi-out-%d", _nextOutIdNum);
- for(int i = 0; ; ++i)
- {
- //snprintf(buf, 80, "midi-out-%d", i);
- name.sprintf("midi-out-%d", i);
-
- if(!midiDevices.find(name))
- {
- // Does not work.
- //if(!audioDevice->findPort(buf))
- // break;
- //client_jackport = (jack_port_t*)audioDevice->registerOutPort(buf, true);
- if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO) // p3.3.52
- {
- //client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.toLatin1().constData(), true);
- out_client_jackport = (jack_port_t*)audioDevice->registerOutPort((name + QString("_out")).toLatin1().constData(), true); // p3.3.55
- //if(client_jackport)
- if(out_client_jackport) // p3.3.55
- break;
- }
- else
- break;
- }
-
- if(i == 65535)
- {
- fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed! Can't find unused output port name!\n");
- return 0;
- }
- }
- //name = QString(buf);
- }
- else
- */
-
- /*
- {
- if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO) // p3.3.52
- {
- //client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.toLatin1().constData(), true);
- out_client_jackport = (jack_port_t*)audioDevice->registerOutPort((name + QString(JACK_MIDI_OUT_PORT_SUFFIX)).toLatin1().constData(), true); // p3.3.55
- //if(!client_jackport)
- if(!out_client_jackport) // p3.3.55
- {
- //fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed creating output port name %s\n", name.toLatin1().constData());
- fprintf(stderr, "MusE: createJackMidiDevice failed creating output port name %s\n", (name + QString(JACK_MIDI_OUT_PORT_SUFFIX)).toLatin1().constData()); // p3.3.55
-
- //return 0;
- rwflags &= ~1; // p3.3.55 Remove the output r/w flag, but continue on...
- }
- }
- }
- */
-
- /*
- else
- {
- client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.toLatin1().constData(), true);
- if(!client_jackport)
- {
- for(int i = 0; ; ++i)
- {
- snprintf(buf, 80, "midi-out-%d", i);
- // Does not work!
- //if(!audioDevice->findPort(buf))
- // break;
- client_jackport = (jack_port_t*)audioDevice->registerOutPort(buf, true);
- if(client_jackport)
- break;
-
- if(i == 65535)
- {
- fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed! Can't find unused output port name!\n");
- return 0;
- }
- }
- name = QString(buf);
- }
- }
- */
-
- //client_jackport = (jack_port_t*)audioDevice->registerOutPort(name.toLatin1().constData(), true);
- //if(client_jackport == NULL)
- //{
- // fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed to register jack midi client output port %s\n", name.toLatin1().constData());
- // return 0;
- //}
- //else
- // _nextOutIdNum++;
-
- ///}
- //else // Note docs say it can't be both input and output. // p3.3.55 Removed
-
- // If Jack port can send data to us and we actually want it...
- //if((pf & JackPortIsOutput) && (_openFlags & 2))
- ///if(rwflags & 2)
- ///{
- /* p3.3.55 Removed.
- if(name.isEmpty())
- {
- //snprintf(buf, 80, "muse-jack-midi-in-%d", _nextInIdNum);
- for(int i = 0; ; ++i)
- {
- //snprintf(buf, 80, "midi-in-%d", i);
- name.sprintf("midi-in-%d", i);
-
- if(!midiDevices.find(name))
- {
- // Does not work.
- //if(!audioDevice->findPort(buf))
- // break;
- //client_jackport = (jack_port_t*)audioDevice->registerInPort(buf, true);
- if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO) // p3.3.52
- {
- //client_jackport = (jack_port_t*)audioDevice->registerInPort(name.toLatin1().constData(), true);
- in_client_jackport = (jack_port_t*)audioDevice->registerInPort(name.toLatin1().constData(), true); // p3.3.55
- //if(client_jackport)
- if(in_client_jackport) // p3.3.55
- break;
- }
- else
- break;
- }
-
- if(i == 65535)
- {
- fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed! Can't find unused input port name!\n");
- return 0;
- }
- }
- //name = QString(buf);
- }
- else
- */
-
- /*
- {
- if(audioDevice->deviceType() == AudioDevice::JACK_AUDIO) // p3.3.52
- {
- //client_jackport = (jack_port_t*)audioDevice->registerInPort(name.toLatin1().constData(), true);
- in_client_jackport = (jack_port_t*)audioDevice->registerInPort((name + QString(JACK_MIDI_IN_PORT_SUFFIX)).toLatin1().constData(), true); // p3.3.55
- //if(!client_jackport)
- if(!in_client_jackport) // p3.3.55
- {
- //fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed creating input port name %s\n", name.toLatin1().constData());
- fprintf(stderr, "MusE: createJackMidiDevice failed creating input port name %s\n", (name + QString(JACK_MIDI_IN_PORT_SUFFIX)).toLatin1().constData());
-
- //return 0;
- rwflags &= ~2; // p3.3.55 Remove the input r/w flag, but continue on...
- }
- }
- }
- */
-
- //client_jackport = (jack_port_t*)audioDevice->registerInPort(name.toLatin1().constData(), true);
-
- //if(client_jackport == NULL)
- //{
- // fprintf(stderr, "MidiJackDevice::createJackMidiDevice failed to register jack midi client input port %s\n", name.toLatin1().constData());
- //_readEnable = false;
- //return QString("Could not register jack-midi-in client port");
- // return 0;
- //}
- //else
- // _nextInIdNum++;
-
- ///}
-
- //if(client_jackport == NULL) // p3.3.52 Removed. Allow the device to be created even if Jack isn't running.
- // return 0;
-
- //MidiJackDevice* dev = new MidiJackDevice(client_jackport, name);
- //MidiJackDevice* dev = new MidiJackDevice(in_client_jackport, out_client_jackport, name); // p3.3.55
- //MidiJackDevice* dev = new MidiJackDevice(NULL, NULL, name); // p3.3.55
- MidiJackDevice* dev = new MidiJackDevice(name); // p3.3.55
+ MidiJackDevice* dev = new MidiJackDevice(name);
dev->setrwFlags(rwflags);
midiDevices.add(dev);
return dev;
@@ -456,9 +119,6 @@ void MidiJackDevice::setName(const QString& s)
#endif
_name = s;
- //if(clientPort()) // p3.3.52 Added check.
- // audioDevice->setPortName(clientPort(), s.toLatin1().constData());
- // p3.3.55
if(inClientPort())
audioDevice->setPortName(inClientPort(), (s + QString(JACK_MIDI_IN_PORT_SUFFIX)).toLatin1().constData());
if(outClientPort())
@@ -477,65 +137,7 @@ QString MidiJackDevice::open()
printf("MidiJackDevice::open %s\n", name().toLatin1().constData());
#endif
- /*
- //jack_port_t* jp = jack_port_by_name(_client, name().toLatin1().constData());
- jack_port_t* jp = (jack_port_t*)audioDevice->findPort(name().toLatin1().constData());
-
- if(!jp)
- {
- printf("MidiJackDevice::open: Jack midi port %s not found!\n", name().toLatin1().constData());
- _writeEnable = false;
- _readEnable = false;
- return QString("Jack midi port not found");
- }
-
- int pf = jack_port_flags(jp);
-
- // If Jack port can receive data from us and we actually want to...
- if((pf & JackPortIsInput) && (_openFlags & 1))
- {
- char buf[80];
- snprintf(buf, 80, "muse-jack-midi-out-%d", _nextOutIdNum);
- _client_jackport = (jack_port_t*)audioDevice->registerOutPort(buf, true);
- if(_client_jackport == NULL)
- {
- fprintf(stderr, "MidiJackDevice::open failed to register jack-midi-out\n");
- _writeEnable = false;
- return QString("Could not register jack-midi-out client port");
- }
- else
- {
- _nextOutIdNum++;
- // src, dest
- ///audioDevice->connect(_client_jackport, jp);
- _writeEnable = true;
- }
- }
- else // Note docs say it can't be both input and output.
- // If Jack port can send data to us and we actually want it...
- if((pf & JackPortIsOutput) && (_openFlags & 2))
- {
- char buf[80];
- snprintf(buf, 80, "muse-jack-midi-in-%d", _nextInIdNum);
- _client_jackport = (jack_port_t*)audioDevice->registerInPort(buf, true);
- if(_client_jackport == NULL)
- {
- fprintf(stderr, "MidiJackDevice::open failed to register jack-midi-in\n");
- _readEnable = false;
- return QString("Could not register jack-midi-in client port");
- }
- else
- {
- _nextInIdNum++;
- ///audioDevice->connect(jp, _client_jackport);
- _readEnable = true;
- }
- }
- */
-
-
QString s;
- // p3.3.55 Moved from createJackMidiDevice()
if(_openFlags & 1)
{
if(!_out_client_jackport)
@@ -608,9 +210,6 @@ QString MidiJackDevice::open()
_in_client_jackport = NULL;
}
- //if(client_jackport == NULL) // p3.3.52 Removed. Allow the device to be created even if Jack isn't running.
- // return 0;
-
_writeEnable = bool(_openFlags & 1);
_readEnable = bool(_openFlags & 2);
@@ -627,10 +226,10 @@ void MidiJackDevice::close()
printf("MidiJackDevice::close %s\n", name().toLatin1().constData());
#endif
- // p3.3.55 TODO: I don't really want to unregister the
+ // TODO: I don't really want to unregister the
// Jack midi ports because then we lose the connections
// to Jack every time we click the read/write lights
- // or change a port's device.
+ // or change a port's device. p3.3.55
/*
if(_client_jackport)
@@ -652,38 +251,6 @@ void MidiJackDevice::close()
_writeEnable = false;
_readEnable = false;
-
- /*
- //jack_port_t* jp = jack_port_by_name(_client, name().toLatin1().constData());
- jack_port_t* jp = (jack_port_t*)audioDevice->findPort(name().toLatin1().constData());
-
- if(!jp)
- {
- printf("MidiJackDevice::close: Jack midi port %s not found!\n", name().toLatin1().constData());
- _writeEnable = false;
- _readEnable = false;
- return;
- }
-
- //int pf = jack_port_flags(jp);
-
- // If Jack port can receive data from us and we actually want to...
- //if((pf & JackPortIsInput) && (_openFlags & 1))
- if(jack_port_connected_to(midi_port_out[0], name().toLatin1().constData()))
- {
- // src, dest
-/// audioDevice->disconnect(midi_port_out[0], jp);
- _writeEnable = false;
- }
- else // Note docs say it can't be both input and output.
- // If Jack port can send data to us and we actually want it...
- //if((pf & JackPortIsOutput) && (_openFlags & 2))
- if(jack_port_connected_to(midi_port_in[0], name().toLatin1().constData()))
- {
-/// audioDevice->disconnect(jp, midi_port_in[0]);
- _readEnable = false;
- }
- */
}
//---------------------------------------------------------
@@ -692,7 +259,6 @@ void MidiJackDevice::close()
void MidiJackDevice::writeRouting(int level, Xml& xml) const
{
- // p3.3.45
// If this device is not actually in use by the song, do not write any routes.
// This prevents bogus routes from being saved and propagated in the med file.
if(midiPort() == -1)
@@ -701,30 +267,17 @@ void MidiJackDevice::writeRouting(int level, Xml& xml) const
QString s;
if(rwFlags() & 2) // Readable
{
- //RouteList* rl = _inRoutes;
- //for (ciRoute r = rl->begin(); r != rl->end(); ++r)
for (ciRoute r = _inRoutes.begin(); r != _inRoutes.end(); ++r)
{
if(!r->name().isEmpty())
{
xml.tag(level++, "Route");
-
- //xml.strTag(level, "srcNode", r->name());
- //xml.tag(level, "source type=\"%d\" name=\"%s\"/", r->type, r->name().toLatin1().constData());
s = QT_TRANSLATE_NOOP("@default", "source");
if(r->type != Route::TRACK_ROUTE)
s += QString(QT_TRANSLATE_NOOP("@default", " type=\"%1\"")).arg(r->type);
-
- //s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(r->name());
s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(r->name()));
xml.tag(level, s.toLatin1().constData());
-
- //xml.strTag(level, "dstNode", name());
- //xml.tag(level, "dest type=\"%d\" name=\"%s\"/", Route::JACK_MIDI_ROUTE, name().toLatin1().constData());
- //xml.tag(level, "dest type=\"%d\" name=\"%s\"/", Route::MIDI_DEVICE_ROUTE, name().toLatin1().constData());
- //xml.tag(level, "dest devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, name().toLatin1().constData());
xml.tag(level, "dest devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, Xml::xmlString(name()).toLatin1().constData());
-
xml.etag(level--, "Route");
}
}
@@ -737,49 +290,14 @@ void MidiJackDevice::writeRouting(int level, Xml& xml) const
s = QT_TRANSLATE_NOOP("@default", "Route");
if(r->channel != -1)
s += QString(QT_TRANSLATE_NOOP("@default", " channel=\"%1\"")).arg(r->channel);
-
- //xml.tag(level++, "Route");
xml.tag(level++, s.toLatin1().constData());
-
- /*
- //xml.strTag(level, "srcNode", name());
- if(r->channel != -1)
- //xml.tag(level, "source type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::JACK_MIDI_ROUTE, r->channel, name().toLatin1().constData());
- //xml.tag(level, "source type=\"%d\" channel=\"%d\" name=\"%s\"/", Route::MIDI_DEVICE_ROUTE, r->channel, name().toLatin1().constData());
- xml.tag(level, "source devtype=\"%d\" channel=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, r->channel, name().toLatin1().constData());
- else
- //xml.tag(level, "source type=\"%d\" name=\"%s\"/", Route::JACK_MIDI_ROUTE, name().toLatin1().constData());
- //xml.tag(level, "source type=\"%d\" name=\"%s\"/", Route::MIDI_DEVICE_ROUTE, name().toLatin1().constData());
- */
- //xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, name().toLatin1().constData());
- xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, Xml::xmlString(name()).toLatin1().constData());
-
- /*
- //xml.strTag(level, "dstNode", r->name());
- if(r->channel != -1)
- {
- if(r->type == Route::MIDI_DEVICE_ROUTE)
- xml.tag(level, "dest devtype=\"%d\" channel=\"%d\" name=\"%s\"/", r->device->deviceType(), r->channel, r->name().toLatin1().constData());
- else
- xml.tag(level, "dest type=\"%d\" channel=\"%d\" name=\"%s\"/", r->type, r->channel, r->name().toLatin1().constData());
- }
- else
- {
- if(r->type == Route::MIDI_DEVICE_ROUTE)
- xml.tag(level, "dest devtype=\"%d\" name=\"%s\"/", r->device->deviceType(), r->name().toLatin1().constData());
- else
- xml.tag(level, "dest type=\"%d\" name=\"%s\"/", r->type, r->name().toLatin1().constData());
- }
- */
-
+ xml.tag(level, "source devtype=\"%d\" name=\"%s\"/", MidiDevice::JACK_MIDI, Xml::xmlString(name()).toLatin1().constData());
s = QT_TRANSLATE_NOOP("@default", "dest");
if(r->type == Route::MIDI_DEVICE_ROUTE)
s += QString(QT_TRANSLATE_NOOP("@default", " devtype=\"%1\"")).arg(r->device->deviceType());
else
if(r->type != Route::TRACK_ROUTE)
s += QString(QT_TRANSLATE_NOOP("@default", " type=\"%1\"")).arg(r->type);
-
- //s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(r->name());
s += QString(QT_TRANSLATE_NOOP("@default", " name=\"%1\"/")).arg(Xml::xmlString(r->name()));
xml.tag(level, s.toLatin1().constData());
@@ -787,33 +305,6 @@ void MidiJackDevice::writeRouting(int level, Xml& xml) const
xml.etag(level--, "Route");
}
}
-
- /*
- else
- if(rwFlags() & 1) // Writable
- {
- //RouteList* rl = _outRoutes;
- //for (ciRoute r = rl->begin(); r != rl->end(); ++r)
- for (ciRoute r = _outRoutes.begin(); r != _outRoutes.end(); ++r)
- {
- if(!r->name().isEmpty())
- {
- xml.tag(level++, "Route");
-
- //xml.strTag(level, "srcNode", name());
- //if(r->channel != -1)
- // xml.tag(level, "srcNode type=\"%d\" channel=\"%d\" name=\"%s\"", Route::JACK_MIDI_ROUTE, r->channel, name().toLatin1().constData());
- //else
- xml.tag(level, "source type=\"%d\" name=\"%s\"/", Route::JACK_MIDI_ROUTE, name().toLatin1().constData());
-
- //xml.strTag(level, "dstNode", r->name());
- xml.tag(level, "dest type=\"%d\" name=\"%s\"/", r->type, r->name().toLatin1().constData());
-
- xml.etag(level--, "Route");
- }
- }
- }
- */
}
//---------------------------------------------------------
@@ -826,80 +317,8 @@ void MidiJackDevice::writeRouting(int level, Xml& xml) const
*/
bool MidiJackDevice::putMidiEvent(const MidiPlayEvent& /*event*/)
{
- /*
- int give, channel = event.channel();
- int x;
-
- if(channel >= JACK_MIDI_CHANNELS) return false;
-
- // buffer up events, because jack eats them in chunks, if
- // the buffer is full, there isn't so much to do, than
- // drop the event
-
- give = jack_midi_out_data[channel].give;
- if(jack_midi_out_data[channel].buffer[give*4+3]){
- fprintf(stderr, "WARNING: muse-to-jack midi-buffer is full, channel=%u\n", channel);
- return false;
- }
- // copy event(note-on etc..), pitch and volume
- // see http://www.midi.org/techspecs/midimessages.php
- switch(event.type()){
- case ME_NOTEOFF:
- jack_midi_out_data[channel].buffer[give*4+0] = 0x80;
- jack_midi_out_data[channel].buffer[give*4+1] = event.dataA() & 0x7f;
- jack_midi_out_data[channel].buffer[give*4+2] = event.dataB() & 0x7f;
- break;
- case ME_NOTEON:
- jack_midi_out_data[channel].buffer[give*4+0] = 0x90;
- jack_midi_out_data[channel].buffer[give*4+1] = event.dataA() & 0x7f;
- jack_midi_out_data[channel].buffer[give*4+2] = event.dataB() & 0x7f;
- break;
- case ME_CONTROLLER:
- jack_midi_out_data[channel].buffer[give*4+0] = 0xb0;
- jack_midi_out_data[channel].buffer[give*4+1] = event.dataA() & 0x7f;
- jack_midi_out_data[channel].buffer[give*4+2] = event.dataB() & 0x7f;
- break;
- case ME_PROGRAM:
- jack_midi_out_data[channel].buffer[give*4+0] = 0xc0;
- jack_midi_out_data[channel].buffer[give*4+1] = event.dataA() & 0x7f;
- jack_midi_out_data[channel].buffer[give*4+2] = 0;
- break;
- case ME_PITCHBEND:
- jack_midi_out_data[channel].buffer[give*4+0] = 0xE0;
- // convert muse pitch-bend to midi standard
- x = 0x2000 + event.dataA();
- jack_midi_out_data[channel].buffer[give*4+1] = x & 0x7f;
- jack_midi_out_data[channel].buffer[give*4+2] = (x >> 8) & 0x7f;
- break;
- default:
- fprintf(stderr, "jack-midi-out %u WARNING: unknown event %x\n", channel, event.type());
- return false;
- }
- jack_midi_out_data[channel].buffer[give*4+3] = 1; // mark state of this slot
- // finally increase give position
- give++;
- if(give >= JACK_MIDI_BUFFER_SIZE){
- give = 0;
- }
- jack_midi_out_data[channel].give = give;
- return false;
- */
-
- return false;
-}
-
-/*
-//---------------------------------------------------------
-// putEvent
-// return false if event is delivered
-//---------------------------------------------------------
-
-bool MidiJackDevice::putEvent(int* event)
-{
- int *y; y = event;
return false;
}
-*/
//---------------------------------------------------------
// recordEvent
@@ -912,7 +331,7 @@ void MidiJackDevice::recordEvent(MidiRecordEvent& event)
if(audio->isPlaying())
event.setLoopNum(audio->loopCount());
- if (midiInputTrace) {
+ if (MusEGlobal::midiInputTrace) {
printf("Jack MidiInput: ");
event.dump();
}
@@ -964,11 +383,11 @@ void MidiJackDevice::recordEvent(MidiRecordEvent& event)
processMidiInputTransformPlugins(event);
- if (filterEvent(event, midiRecordType, false))
+ if (filterEvent(event, MusEGlobal::midiRecordType, false))
return;
if (!applyMidiInputTransformation(event)) {
- if (midiInputTrace)
+ if (MusEGlobal::midiInputTrace)
printf(" midi input transformation: event filtered\n");
return;
}
@@ -989,9 +408,8 @@ void MidiJackDevice::recordEvent(MidiRecordEvent& event)
//if(_recordFifo.put(MidiPlayEvent(event)))
// printf("MidiJackDevice::recordEvent: fifo overflow\n");
- // p3.3.38
// Do not bother recording if it is NOT actually being used by a port.
- // Because from this point on, process handles things, by selected port.
+ // Because from this point on, process handles things, by selected port. p3.3.38
if(_port == -1)
return;
@@ -1010,8 +428,8 @@ void MidiJackDevice::eventReceived(jack_midi_event_t* ev)
MidiRecordEvent event;
event.setB(0);
- // NOTE: From MusE-2. Not done here in Muse-1 (yet).
- // move all events 2*segmentSize into the future to get
+ // NOTE: From muse_qt4_evolution. Not done here in Muse-2 (yet).
+ // move all events 2*MusEGlobal::segmentSize into the future to get
// jitterfree playback
//
// cycle n-1 n n+1
@@ -1019,15 +437,11 @@ void MidiJackDevice::eventReceived(jack_midi_event_t* ev)
// ^ ^ ^
// catch process play
//
-// const SeqTime* st = audio->seqTime();
-
- //unsigned curFrame = st->startFrame() + segmentSize;
-// unsigned curFrame = st->lastFrameTime;
+
//int frameOffset = audio->getFrameOffset();
unsigned pos = audio->pos().frame();
- //event.setTime(pos + ev->time);
- event.setTime(extSyncFlag.value() ? lastExtMidiSyncTick : (pos + ev->time));
+ event.setTime(extSyncFlag.value() ? lastExtMidiSyncTick : (pos + ev->time)); // p3.3.25
event.setChannel(*(ev->buffer) & 0xf);
int type = *(ev->buffer) & 0xf0;
@@ -1061,7 +475,7 @@ void MidiJackDevice::eventReceived(jack_midi_event_t* ev)
// For now, do not accept if the last byte is not EOX, meaning it's a chunk with more chunks to follow.
if(*(((unsigned char*)ev->buffer) + ev->size - 1) != ME_SYSEX_END)
{
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("MidiJackDevice::eventReceived sysex chunks not supported!\n");
return;
}
@@ -1093,7 +507,7 @@ void MidiJackDevice::eventReceived(jack_midi_event_t* ev)
//break;
// return;
default:
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("MidiJackDevice::eventReceived unsupported system event 0x%02x\n", type);
return;
}
@@ -1101,13 +515,13 @@ void MidiJackDevice::eventReceived(jack_midi_event_t* ev)
//return;
break;
default:
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("MidiJackDevice::eventReceived unknown event 0x%02x\n", type);
//printf("MidiJackDevice::eventReceived unknown event 0x%02x size:%d buf:0x%02x 0x%02x 0x%02x ...0x%02x\n", type, ev->size, *(ev->buffer), *(ev->buffer + 1), *(ev->buffer + 2), *(ev->buffer + (ev->size - 1)));
return;
}
- if (midiInputTrace) {
+ if (MusEGlobal::midiInputTrace) {
printf("MidiInput<%s>: ", name().toLatin1().constData());
event.dump();
}
@@ -1129,13 +543,10 @@ void MidiJackDevice::collectMidiEvents()
if(!_readEnable)
return;
- //if(!_client_jackport)
- if(!_in_client_jackport) // p3.3.55
+ if(!_in_client_jackport)
return;
- //void* port_buf = jack_port_get_buffer(_client_jackport, segmentSize);
- void* port_buf = jack_port_get_buffer(_in_client_jackport, segmentSize); // p3.3.55
-
+ void* port_buf = jack_port_get_buffer(_in_client_jackport, MusEGlobal::segmentSize);
jack_midi_event_t event;
jack_nframes_t eventCount = jack_midi_get_event_count(port_buf);
for (jack_nframes_t i = 0; i < eventCount; ++i)
@@ -1157,9 +568,7 @@ void MidiJackDevice::collectMidiEvents()
bool MidiJackDevice::putEvent(const MidiPlayEvent& ev)
{
- //if(!_writeEnable)
- if(!_writeEnable || !_out_client_jackport) // p4.0.15
- //return true;
+ if(!_writeEnable || !_out_client_jackport)
return false;
#ifdef JACK_MIDI_DEBUG
@@ -1178,9 +587,7 @@ bool MidiJackDevice::putEvent(const MidiPlayEvent& ev)
// return true if successful
//---------------------------------------------------------
-//void JackAudioDevice::putEvent(Port port, const MidiEvent& e)
bool MidiJackDevice::queueEvent(const MidiPlayEvent& e)
-//bool MidiJackDevice::queueEvent(const MidiPlayEvent& e)
{
// Perhaps we can find use for this value later, together with the Jack midi MusE port(s).
// No big deal if not. Not used for now.
@@ -1194,14 +601,12 @@ bool MidiJackDevice::queueEvent(const MidiPlayEvent& e)
// e.dump();
// }
- //if(debugMsg)
+ //if(MusEGlobal::debugMsg)
// printf("MidiJackDevice::queueEvent\n");
- //if(!_client_jackport)
- if(!_out_client_jackport) // p3.3.55
+ if(!_out_client_jackport)
return false;
- //void* pb = jack_port_get_buffer(_client_jackport, segmentSize);
- void* pb = jack_port_get_buffer(_out_client_jackport, segmentSize); // p3.3.55
+ void* pb = jack_port_get_buffer(_out_client_jackport, MusEGlobal::segmentSize);
//unsigned frameCounter = ->frameTime();
int frameOffset = audio->getFrameOffset();
@@ -1210,10 +615,10 @@ bool MidiJackDevice::queueEvent(const MidiPlayEvent& e)
if (ft < 0)
ft = 0;
- if (ft >= (int)segmentSize) {
- printf("MidiJackDevice::queueEvent: Event time:%d out of range. offset:%d ft:%d (seg=%d)\n", e.time(), frameOffset, ft, segmentSize);
- if (ft > (int)segmentSize)
- ft = segmentSize - 1;
+ if (ft >= (int)MusEGlobal::segmentSize) {
+ printf("MidiJackDevice::queueEvent: Event time:%d out of range. offset:%d ft:%d (seg=%d)\n", e.time(), frameOffset, ft, MusEGlobal::segmentSize);
+ if (ft > (int)MusEGlobal::segmentSize)
+ ft = MusEGlobal::segmentSize - 1;
}
#ifdef JACK_MIDI_DEBUG
@@ -1293,7 +698,7 @@ bool MidiJackDevice::queueEvent(const MidiPlayEvent& e)
case ME_START:
case ME_CONTINUE:
case ME_STOP:
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("MidiJackDevice::queueEvent: event type %x not supported\n", e.type());
//return false;
return true; // Absorb the event. Don't want it hanging around in the list. FIXME: Support these? p4.0.15 Tim.
@@ -1325,7 +730,7 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event)
// Just do this 'standard midi 64T timing thing' for now until we figure out more precise external timings.
// Does require relatively short audio buffers, in order to catch the resolution, but buffer <= 256 should be OK...
// Tested OK so far with 128.
- ///if(extSyncFlag.value())
+ //if(extSyncFlag.value())
// p4.0.15 Or, is the event marked to be played immediately?
// Nothing to do but stamp the event to be queued for frame 0+.
if(t == 0 || extSyncFlag.value())
@@ -1362,17 +767,13 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event)
if(event.type() == ME_PITCHBEND)
{
int v = a + 8192;
- // p3.3.44
//printf("MidiJackDevice::processEvent ME_PITCHBEND v:%d time:%d type:%d ch:%d A:%d B:%d\n", v, event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
-
if(!queueEvent(MidiPlayEvent(t, port, chn, ME_PITCHBEND, v & 0x7f, (v >> 7) & 0x7f)))
return false;
}
else
if(event.type() == ME_CONTROLLER)
{
- //int a = event.dataA();
- //int b = event.dataB();
// Perhaps we can find use for this value later, together with the Jack midi MusE port(s).
// No big deal if not. Not used for now.
//int port = event.port();
@@ -1392,9 +793,7 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event)
if(a == CTRL_PITCH)
{
int v = b + 8192;
- // p3.3.44
//printf("MidiJackDevice::processEvent CTRL_PITCH v:%d time:%d type:%d ch:%d A:%d B:%d\n", v, event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
-
if(!queueEvent(MidiPlayEvent(t, port, chn, ME_PITCHBEND, v & 0x7f, (v >> 7) & 0x7f)))
return false;
}
@@ -1405,8 +804,6 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event)
int hb = (b >> 16) & 0xff;
int lb = (b >> 8) & 0xff;
int pr = b & 0x7f;
-
- // p3.3.44
//printf("MidiJackDevice::processEvent CTRL_PROGRAM time:%d type:%d ch:%d A:%d B:%d hb:%d lb:%d pr:%d\n",
// event.time(), event.type(), event.channel(), event.dataA(), event.dataB(), hb, lb, pr);
@@ -1425,7 +822,7 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event)
// }
}
- else if (a == CTRL_MASTER_VOLUME) // Enabled p4.0.15 Tim.
+ else if (a == CTRL_MASTER_VOLUME)
{
unsigned char sysex[] = {
0x7f, 0x7f, 0x04, 0x01, 0x00, 0x00
@@ -1565,7 +962,7 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event)
}
else
{
- if(debugMsg)
+ if(MusEGlobal::debugMsg)
printf("MidiJackDevice::processEvent: unknown controller type 0x%x\n", a);
//return false; // Just ignore it.
}
@@ -1581,65 +978,41 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event)
}
//---------------------------------------------------------
-// processMidi called from audio process only.
+// processMidi
+// Called from audio thread only.
//---------------------------------------------------------
void MidiJackDevice::processMidi()
{
- //if(!_client_jackport)
- //if(!_out_client_jackport) // p3.3.55
- // return;
+ processStuckNotes();
- //void* port_buf = jack_port_get_buffer(_client_jackport, segmentSize);
- //void* port_buf = jack_port_get_buffer(_out_client_jackport, segmentSize); // p3.3.55
void* port_buf = 0;
- if(_out_client_jackport && _writeEnable) // p4.0.15
+ if(_out_client_jackport && _writeEnable)
{
- port_buf = jack_port_get_buffer(_out_client_jackport, segmentSize);
+ port_buf = jack_port_get_buffer(_out_client_jackport, MusEGlobal::segmentSize);
jack_midi_clear_buffer(port_buf);
}
while(!eventFifo.isEmpty())
{
- ///MidiPlayEvent e(eventFifo.get());
- MidiPlayEvent e(eventFifo.peek()); // p4.0.15
-
- ///int evTime = e.time();
- // Is event marked to be played immediately? p4.0.15 Moved into processEvent().
- ///if(evTime == 0)
- ///{
- // Nothing to do but stamp the event to be queued for frame 0+.
- //e.setTime(frameOffset + pos);
- /// e.setTime(audio->getFrameOffset() + audio->pos().frame());
- ///}
-
- //#ifdef JACK_MIDI_DEBUG
- //printf("MidiJackDevice::processMidi eventFifo time:%d type:%d ch:%d A:%d B:%d\n", e.time(), e.type(), e.channel(), e.dataA(), e.dataB());
- //#endif
-
- //el->insert(eventFifo.get());
- //el->insert(e);
- ///processEvent(e);
- // p4.0.15 Try to process only until full, keep rest for next cycle. If no out client port or no write enable, eat up events.
+ MidiPlayEvent e(eventFifo.peek());
+ // Try to process only until full, keep rest for next cycle. If no out client port or no write enable, eat up events. p4.0.15
if(port_buf && !processEvent(e))
return; // Give up. The Jack buffer is full. Nothing left to do.
eventFifo.remove(); // Successfully processed event. Remove it from FIFO.
}
- MPEventList* el = playEvents();
- if(el->empty())
+ if(_playEvents.empty())
{
//printf("MidiJackDevice::processMidi play events empty\n");
return;
}
- //printf("MidiJackDevice::processMidi play events:\n");
- ///iMPEvent i = nextPlayEvent();
- iMPEvent i = el->begin(); // p4.0.15
- for(; i != el->end(); ++i)
+ iMPEvent i = _playEvents.begin();
+ for(; i != _playEvents.end(); ++i)
{
//printf("MidiJackDevice::processMidi playEvent time:%d type:%d ch:%d A:%d B:%d\n", i->time(), i->type(), i->channel(), i->dataA(), i->dataB());
- // p3.3.39 Update hardware state so knobs and boxes are updated. Optimize to avoid re-setting existing values.
+ // Update hardware state so knobs and boxes are updated. Optimize to avoid re-setting existing values.
// Same code as in MidiPort::sendEvent()
if(_port != -1)
{
@@ -1657,12 +1030,10 @@ void MidiJackDevice::processMidi()
if(i->type() == ME_PITCHBEND)
{
//printf("MidiJackDevice::processMidi playEvents ME_PITCHBEND time:%d type:%d ch:%d A:%d B:%d\n", (*i).time(), (*i).type(), (*i).channel(), (*i).dataA(), (*i).dataB());
-
int da = mp->limitValToInstrCtlRange(CTRL_PITCH, i->dataA());
if(!mp->setHwCtrlState(i->channel(), CTRL_PITCH, da))
continue;
//mp->setHwCtrlState(i->channel(), CTRL_PITCH, da);
-
//(MidiPlayEvent(t, port, chn, ME_PITCHBEND, v & 0x7f, (v >> 7) & 0x7f));
}
else
@@ -1674,25 +1045,11 @@ void MidiJackDevice::processMidi()
}
}
- ///processEvent(*i);
- // p4.0.15 Try to process only until full, keep rest for next cycle. If no out client port or no write enable, eat up events.
- if(port_buf && !processEvent(*i))
- {
- //setNextPlayEvent(i);
- //return;
+ // Try to process only until full, keep rest for next cycle. If no out client port or no write enable, eat up events. p4.0.15
+ if(port_buf && !processEvent(*i))
break;
- }
}
-
- ///setNextPlayEvent(i);
- // p4.0.15 We are done with these events. Let us erase them here instead of Audio::processMidi.
- // That way we can simply set the next play event to the beginning.
- // This also allows other events to be inserted without the problems caused by the next play event
- // being at the 'end' iterator and not being *easily* set to some new place beginning of the newer insertions.
- // The way that MPEventList sorts made it difficult to predict where the iterator of the first newly inserted items was.
- // The erasure in Audio::processMidi was missing some events because of that.
- el->erase(el->begin(), i);
- // setNextPlayEvent(el->begin()); // Removed p4.0.15 Tim.
+ _playEvents.erase(_playEvents.begin(), i);
}
@@ -1703,139 +1060,6 @@ void MidiJackDevice::processMidi()
bool initMidiJack()
{
- /*
- int adr = 0;
-
- memset(jack_midi_out_data, 0, JACK_MIDI_CHANNELS * sizeof(muse_jack_midi_buffer));
- memset(jack_midi_in_data, 0, JACK_MIDI_CHANNELS * sizeof(muse_jack_midi_buffer));
-
- MidiJackDevice* dev = new MidiJackDevice(adr, QString("jack-midi"));
- dev->setrwFlags(3); // set read and write flags
-
- if(pipe(jackmidi_pi) < 0){
- fprintf(stderr, "cant create midi-jack input pipe\n");
- }
- if(pipe(jackmidi_po) < 0){
- fprintf(stderr, "cant create midi-jack output pipe\n");
- }
-
- midiDevices.add(dev);
-
- gmdev = dev; // proclaim the global jack-midi instance
-
- //jackScanMidiPorts();
- */
-
return false;
}
-/*
-struct JackPort {
- int adr;
- //char* name;
- QString name;
- int flags;
- //JackPort(int a, const char* s, int f) {
- JackPort(int a, const QString& s, int f) {
- adr = a;
- //name = strdup(s);
- name = QString(s);
- flags = f;
- }
- };
-
-
-static std::list<JackPort> portList;
-
-//---------------------------------------------------------
-// jackScanMidiPorts
-//---------------------------------------------------------
-
-void jackScanMidiPorts()
-{
- int adr;
- const char* name;
-
- portList.clear();
- adr = 0;
- name = strdup("namex");
- portList.push_back(JackPort(adr, name, 0));
- //
- // check for devices to add
- //
- for (std::list<JackPort>::iterator k = portList.begin(); k != portList.end(); ++k) {
- iMidiDevice i = midiDevices.begin();
- for (;i != midiDevices.end(); ++i) {
- //MidiJackDevice* d = dynamic_cast<MidiJackDevice*>(*i);
- break;
- //if (d == 0) continue;
- //if ((k->adr.client == d->adr.client) && (k->adr.port == d->adr.port)) {
- // break;
- //}
- }
- if (i == midiDevices.end()) {
- // add device
- MidiJackDevice* dev = new MidiJackDevice(k->adr, QString(k->name));
- dev->setrwFlags(k->flags);
- midiDevices.add(dev);
- }
- }
-}
-*/
-
-/*
-//---------------------------------------------------------
-// processInput
-//---------------------------------------------------------
-static void handle_jack_midi_in(int channel)
-{
- MidiRecordEvent event;
- int t,n,v;
- t = jack_midi_in_data[channel].buffer[0];
- n = jack_midi_in_data[channel].buffer[1];
- v = jack_midi_in_data[channel].buffer[2];
-
- event.setType(0); // mark as unused
- event.setPort(gmdev->midiPort());
- event.setB(0);
-
- if(t == 0x90){ // note on
- fprintf(stderr, "jackProcessMidiInput note-on\n");
- event.setChannel(channel);
- event.setType(ME_NOTEON);
- event.setA(n);
- event.setB(v);
- }else if (t == 0x80){ // note off
- fprintf(stderr, "jackProcessMidiInput note-off\n");
- event.setChannel(channel);
- event.setType(ME_NOTEOFF);
- event.setA(n);
- event.setB(v);
- }else{
- fprintf(stderr, "WARNING: unknown midi-in on channel %d: %x,%x,%x\n",
- channel, t, n, v);
- return;
- }
- if(event.type()){
- gmdev->recordEvent(event);
- midiPorts[gmdev->midiPort()].syncInfo().trigActDetect(event.channel());
- }
-}
-
-void MidiJackDevice::processInput()
-{
- char buf;
- int i,s;
- read(gmdev->selectRfd(), &buf, 1);
-
- s = 1;
- for(i = 0; i < JACK_MIDI_CHANNELS; i++){
- if(jack_midi_in_data[i].buffer[3]){
- s = 0;
- handle_jack_midi_in(i);
- jack_midi_in_data[i].buffer[3] = 0;
- }
- }
-}
-
-*/
diff --git a/muse2/muse/driver/jackmidi.h b/muse2/muse/driver/jackmidi.h
index 2dcf2fbb..e79e9288 100644
--- a/muse2/muse/driver/jackmidi.h
+++ b/muse2/muse/driver/jackmidi.h
@@ -3,6 +3,22 @@
// Linux Music Editor
// $Id: jackmidi.h,v 1.1.1.1 2010/01/27 09:06:43 terminator356 Exp $
// (C) Copyright 1999-2010 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#ifndef __JACKMIDI_H__
@@ -25,81 +41,17 @@ class MidiPlayEvent;
//class RouteList;
class Xml;
-// Turn on to show multiple devices, work in progress,
-// not working fully yet, can't seem to connect...
-//#define JACK_MIDI_SHOW_MULTIPLE_DEVICES
-
// It appears one client port per remote port will be necessary.
// Jack doesn't seem to like manipulation of non-local ports buffers.
//#define JACK_MIDI_USE_MULTIPLE_CLIENT_PORTS
-/* jack-midi channels */
-//#define JACK_MIDI_CHANNELS 32
-
-/* jack-midi buffer size */
-//#define JACK_MIDI_BUFFER_SIZE 32
-
-/*
-typedef struct {
- int give;
- int take;
- // 32 parallel midi events, where each event contains three
- // midi-bytes and one busy-byte
- char buffer[4 * JACK_MIDI_BUFFER_SIZE];
-} muse_jack_midi_buffer;
-*/
-
-/*
-struct JackMidiPort
-{
- jack_port_t* _jackPort;
- QString _name;
- int _flags; // 1 = writable, 2 = readable - do not mix
- JackMidiPort(jack_port_t* jp, const QString& s, int f)
- {
- _jackPort = jp;
- _name = QString(s);
- _flags = f;
- }
-};
-
-typedef std::map<jack_port_t*, JackMidiPort, std::less<jack_port_t*> >::iterator iJackMidiPort;
-typedef std::map<jack_port_t*, JackMidiPort, std::less<jack_port_t*> >::const_iterator ciJackMidiPort;
-
-class JackMidiPortList : public std::map<jack_port_t*, JackMidiPort, std::less<jack_port_t*> >
-{
- private:
- static int _nextOutIdNum;
- static int _nextInIdNum;
-
- public:
- JackMidiPortList();
- ~JackMidiPortList();
- iJackMidiPort createClientPort(int flags);
- bool removeClientPort(jack_port_t* port);
-};
-
-extern JackMidiPortList jackMidiClientPorts;
-*/
-
//---------------------------------------------------------
// MidiJackDevice
//---------------------------------------------------------
class MidiJackDevice : public MidiDevice {
- public:
- //int adr;
-
private:
- // fifo for midi events sent from gui
- // direct to midi port:
- //MidiFifo eventFifo; // Moved into MidiDevice p4.0.15
-
- //static int _nextOutIdNum;
- //static int _nextInIdNum;
- //jack_port_t* _client_jackport;
- // p3.3.55
jack_port_t* _in_client_jackport;
jack_port_t* _out_client_jackport;
@@ -119,49 +71,27 @@ class MidiJackDevice : public MidiDevice {
void eventReceived(jack_midi_event_t*);
public:
- //MidiJackDevice() {} // p3.3.55 Removed.
- //MidiJackDevice(const int&, const QString& name);
-
- //MidiJackDevice(jack_port_t* jack_port, const QString& name);
- //MidiJackDevice(jack_port_t* in_jack_port, jack_port_t* out_jack_port, const QString& name); // p3.3.55 In or out port can be null.
MidiJackDevice(const QString& name);
- //static MidiDevice* createJackMidiDevice(QString /*name*/, int /*rwflags*/); // 1:Writable 2: Readable. Do not mix.
- static MidiDevice* createJackMidiDevice(QString name = "", int rwflags = 3); // p3.3.55 1:Writable 2: Readable 3: Writable + Readable
-
+ static MidiDevice* createJackMidiDevice(QString name = "", int rwflags = 3); // 1:Writable 2: Readable 3: Writable + Readable
virtual inline int deviceType() const { return JACK_MIDI; }
-
virtual void setName(const QString&);
virtual void processMidi();
virtual ~MidiJackDevice();
- //virtual int selectRfd();
- //virtual int selectWfd();
- //virtual void processInput();
virtual void recordEvent(MidiRecordEvent&);
virtual bool putEvent(const MidiPlayEvent&);
virtual void collectMidiEvents();
- //virtual jack_port_t* jackPort() { return _jackport; }
- //virtual jack_port_t* clientJackPort() { return _client_jackport; }
-
- //virtual void* clientPort() { return (void*)_client_jackport; }
- // p3.3.55
virtual void* inClientPort() { return (void*) _in_client_jackport; }
virtual void* outClientPort() { return (void*) _out_client_jackport; }
- //RouteList* routes() { return &_routes; }
- //bool noRoute() const { return _routes.empty(); }
virtual void writeRouting(int, Xml&) const;
};
extern bool initMidiJack();
-//extern int jackSelectRfd();
-//extern int jackSelectWfd();
-//extern void jackProcessMidiInput();
-//extern void jackScanMidiPorts();
#endif
diff --git a/muse2/muse/driver/rtctimer.cpp b/muse2/muse/driver/rtctimer.cpp
index 1a3cefa6..8410bb04 100644
--- a/muse2/muse/driver/rtctimer.cpp
+++ b/muse2/muse/driver/rtctimer.cpp
@@ -5,8 +5,23 @@
//
// Most code moved from midiseq.cpp by Werner Schweer.
//
- // (C) Copyright 2004 Robert Jonsson (rj@spamatica.se)
// (C) Copyright -2004 Werner Schweer (werner@seh.de)
+ // (C) Copyright 2004 Robert Jonsson (rj@spamatica.se)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#include <linux/version.h>
@@ -46,16 +61,16 @@ signed int RtcTimer::initTimer()
fprintf(stderr,"RtcTimer::initTimer(): called on initialised timer!\n");
return -1;
}
- doSetuid();
+ MusEGlobal::doSetuid();
timerFd = ::open("/dev/rtc", O_RDONLY);
if (timerFd == -1) {
fprintf(stderr, "fatal error: open /dev/rtc failed: %s\n", strerror(errno));
fprintf(stderr, "hint: check if 'rtc' kernel module is loaded, or used by something else\n");
- undoSetuid();
+ MusEGlobal::undoSetuid();
return timerFd;
}
- if (!setTimerFreq(config.rtcTicks)) {
+ if (!setTimerFreq(MusEConfig::config.rtcTicks)) {
// unable to set timer frequency
return -1;
}
@@ -118,7 +133,7 @@ bool RtcTimer::startTimer()
}
if (ioctl(timerFd, RTC_PIE_ON, 0) == -1) {
perror("MidiThread: start: RTC_PIE_ON failed");
- undoSetuid();
+ MusEGlobal::undoSetuid();
return false;
}
return true;
diff --git a/muse2/muse/driver/rtctimer.h b/muse2/muse/driver/rtctimer.h
index fa58b032..5befdf22 100644
--- a/muse2/muse/driver/rtctimer.h
+++ b/muse2/muse/driver/rtctimer.h
@@ -5,8 +5,23 @@
//
// Most code moved from midiseq.cpp
//
- // (C) Copyright 2004 Robert Jonsson (rj@spamatica.se)
// (C) Copyright -2004 Werner Schweer (werner@seh.de)
+ // (C) Copyright 2004 Robert Jonsson (rj@spamatica.se)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#ifndef __RTCTIMER_H__
diff --git a/muse2/muse/driver/timerdev.h b/muse2/muse/driver/timerdev.h
index 944bc213..960cf2f4 100644
--- a/muse2/muse/driver/timerdev.h
+++ b/muse2/muse/driver/timerdev.h
@@ -7,6 +7,21 @@
// alsalib 1.0.7
//
// (C) Copyright 2004 Robert Jonsson (rj@spamatica.se)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
//=========================================================
#ifndef __TIMERDEV_H__