summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Schweer <ws.seh.de>2006-12-05 12:48:32 +0000
committerWerner Schweer <ws.seh.de>2006-12-05 12:48:32 +0000
commitd9cd5e6490cc940116930fa631ad75ccbe1227a4 (patch)
tree142d00821c048524450537131f33fdbaa01c9b0f
parent4e1abfd39f9be895d16835bf2fac26f2b1ea0c3b (diff)
fixed dropping midi events
-rw-r--r--muse/muse/audio.cpp26
-rw-r--r--muse/muse/audio.h1
-rw-r--r--muse/muse/driver/audiodev.h3
-rw-r--r--muse/muse/driver/dummyaudio.cpp3
-rw-r--r--muse/muse/driver/jackaudio.h7
-rw-r--r--muse/muse/midievent.cpp8
-rw-r--r--muse/muse/midififo.cpp19
-rw-r--r--muse/muse/midififo.h2
-rw-r--r--muse/muse/midiinport.cpp6
-rw-r--r--muse/muse/synth.cpp17
10 files changed, 73 insertions, 19 deletions
diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp
index 9d719d33..f706edcf 100644
--- a/muse/muse/audio.cpp
+++ b/muse/muse/audio.cpp
@@ -309,6 +309,9 @@ void Audio::process(unsigned frames, int jackState)
extern int watchAudio;
++watchAudio; // make a simple watchdog happy
+ //
+ // process messages from gui
+ //
if (msg) {
processMsg();
msg = 0; // dont process again
@@ -344,15 +347,15 @@ void Audio::process(unsigned frames, int jackState)
startRolling();
}
- if (idle || state == START_PLAY) {
+ if (idle || (state == START_PLAY)) {
// deliver silence
OutputList* ol = song->outputs();
for (iAudioOutput i = ol->begin(); i != ol->end(); ++i)
(*i)->silence(frames);
return;
}
- unsigned framePos = _pos.frame();
+ unsigned framePos = _pos.frame();
if (state == PLAY) {
//
// clear prefetch FIFO if left/right locators
@@ -436,6 +439,8 @@ void Audio::process(unsigned frames, int jackState)
// process midi
//-----------------------------------------
+ unsigned startFrame = _pos.frame();
+ unsigned endFrame = startFrame + segmentSize;
SynthIList* sl = song->syntis();
{
MidiOutPortList* ol = song->midiOutPorts();
@@ -448,11 +453,11 @@ void Audio::process(unsigned frames, int jackState)
for (iMidiInPort i = mil->begin(); i != mil->end(); ++i)
(*i)->beforeProcess();
for (iMidiTrack i = mtl->begin(); i != mtl->end(); ++i)
- (*i)->processMidi(_curTickPos, _nextTickPos, _pos.frame(), _pos.frame() + segmentSize);
+ (*i)->processMidi(_curTickPos, _nextTickPos, startFrame, endFrame);
for (iMidiOutPort i = ol->begin(); i != ol->end(); ++i)
- (*i)->processMidi(_curTickPos, _nextTickPos, _pos.frame(), _pos.frame() + segmentSize);
+ (*i)->processMidi(_curTickPos, _nextTickPos, startFrame, endFrame);
for (iSynthI i = sl->begin(); i != sl->end(); ++i)
- (*i)->processMidi(_curTickPos, _nextTickPos, _pos.frame(), _pos.frame() + segmentSize);
+ (*i)->processMidi(_curTickPos, _nextTickPos, startFrame, endFrame);
for (iMidiInPort i = mil->begin(); i != mil->end(); ++i)
(*i)->afterProcess();
@@ -715,3 +720,14 @@ void Audio::sendMsgToGui(char c)
write(sigFd, &c, 1);
}
+//---------------------------------------------------------
+// timestamp
+// on stop we return a free running frame counter
+//---------------------------------------------------------
+
+unsigned Audio::timestamp() const
+ {
+ return audio->isPlaying() ? audioDriver->framePos()
+ : audioDriver->frameTime();
+ }
+
diff --git a/muse/muse/audio.h b/muse/muse/audio.h
index 56ce1976..56c85f05 100644
--- a/muse/muse/audio.h
+++ b/muse/muse/audio.h
@@ -268,6 +268,7 @@ class Audio {
MidiEvent* getMidiEvent();
void popMidiEvent();
int curReadIndex() const { return _curReadIndex; }
+ unsigned timestamp() const;
};
extern int processAudio(unsigned long, void*);
diff --git a/muse/muse/driver/audiodev.h b/muse/muse/driver/audiodev.h
index 0494116f..e0bf554d 100644
--- a/muse/muse/driver/audiodev.h
+++ b/muse/muse/driver/audiodev.h
@@ -36,12 +36,13 @@ class AudioDriver : public Driver {
virtual void start(int priority) = 0;
virtual bool restart() { return false; } // return true on error
virtual void stop () = 0;
+// virtual unsigned getCurFrame() = 0;
virtual unsigned framePos() const = 0;
+ virtual unsigned frameTime() const = 0;
virtual float* getBuffer(Port, unsigned long nframes) = 0;
virtual void registerClient() = 0;
virtual Port registerOutPort(const QString& name, bool midi) = 0;
virtual Port registerInPort(const QString& name, bool midi) = 0;
- virtual unsigned getCurFrame() = 0;
virtual int realtimePriority() const = 0; // return zero if not realtime
virtual void startTransport() = 0;
virtual void stopTransport() = 0;
diff --git a/muse/muse/driver/dummyaudio.cpp b/muse/muse/driver/dummyaudio.cpp
index 796e8b58..85997824 100644
--- a/muse/muse/driver/dummyaudio.cpp
+++ b/muse/muse/driver/dummyaudio.cpp
@@ -57,6 +57,9 @@ class DummyAudio : public AudioDriver {
virtual unsigned framePos() const {
return lrint((curTime()-startTime) * AL::sampleRate);
}
+ virtual unsigned frameTime() const {
+ return lrint(curTime() * AL::sampleRate);
+ }
virtual float* getBuffer(Port /*port*/, unsigned long nframes)
{
diff --git a/muse/muse/driver/jackaudio.h b/muse/muse/driver/jackaudio.h
index 43da338b..98d8e493 100644
--- a/muse/muse/driver/jackaudio.h
+++ b/muse/muse/driver/jackaudio.h
@@ -77,13 +77,14 @@ class JackAudio : public AudioDriver {
void graphChanged();
virtual void putEvent(Port, const MidiEvent&);
virtual void startMidiCycle(Port);
- virtual unsigned int getCurFrame() { return pos.frame; }
+// virtual unsigned int getCurFrame() { return pos.frame; }
virtual unsigned framePos() const {
return pos.frame + jack_frames_since_cycle_start(_client);
}
- unsigned lastFrameTime() { return jack_last_frame_time(_client); }
- unsigned framesSinceCyleStart() { return jack_frames_since_cycle_start(_client); }
+// unsigned lastFrameTime() { return jack_last_frame_time(_client); }
+// unsigned framesSinceCyleStart() { return jack_frames_since_cycle_start(_client); }
+ virtual unsigned frameTime() const { return jack_frame_time(_client); }
};
#endif
diff --git a/muse/muse/midievent.cpp b/muse/muse/midievent.cpp
index 8dbf4dc2..88539a1c 100644
--- a/muse/muse/midievent.cpp
+++ b/muse/muse/midievent.cpp
@@ -79,9 +79,13 @@ MidiEvent::MidiEvent(unsigned tick, int channel, const Event& e)
void MidiEvent::dump() const
{
printf("chan:%d ", _channel+1);
- if (_type == ME_NOTEON) { // NoteOn
+ if (_type == ME_NOTEON) {
QString s = pitch2string(_a);
- printf("NoteOn %3s(0x%02x) %3d\n", s.toLatin1().data(), _a, _b);
+ printf("NoteOn %3s(0x%02x) %3d\n", s.toLatin1().data(), _a, _b);
+ }
+ else if (_type == ME_NOTEOFF) {
+ QString s = pitch2string(_a);
+ printf("NoteOff %3s(0x%02x) %3d\n", s.toLatin1().data(), _a, _b);
}
else if (_type == ME_SYSEX) {
printf("SysEx len %d ", len());
diff --git a/muse/muse/midififo.cpp b/muse/muse/midififo.cpp
index 4bb43346..dbf16942 100644
--- a/muse/muse/midififo.cpp
+++ b/muse/muse/midififo.cpp
@@ -49,6 +49,25 @@ MidiEvent MidiFifo::get()
}
//---------------------------------------------------------
+// peek
+//---------------------------------------------------------
+
+MidiEvent MidiFifo::peek()
+ {
+ return fifo[rIndex];
+ }
+
+//---------------------------------------------------------
+// remove
+//---------------------------------------------------------
+
+void MidiFifo::remove()
+ {
+ rIndex = (rIndex + 1) % MIDI_FIFO_SIZE;
+ q_atomic_decrement(&size);
+ }
+
+//---------------------------------------------------------
// put
// return true on fifo overflow
//---------------------------------------------------------
diff --git a/muse/muse/midififo.h b/muse/muse/midififo.h
index e5964e99..d8b95bcc 100644
--- a/muse/muse/midififo.h
+++ b/muse/muse/midififo.h
@@ -40,6 +40,8 @@ class MidiFifo {
MidiFifo() { clear(); }
bool put(const MidiEvent& event); // returns true on fifo overflow
MidiEvent get();
+ MidiEvent peek();
+ void remove();
bool isEmpty() const { return size == 0; }
void clear() { size = 0, wIndex = 0, rIndex = 0; }
};
diff --git a/muse/muse/midiinport.cpp b/muse/muse/midiinport.cpp
index 42ceff2c..878a5797 100644
--- a/muse/muse/midiinport.cpp
+++ b/muse/muse/midiinport.cpp
@@ -102,7 +102,7 @@ void MidiInPort::eventReceived(snd_seq_event_t* ev)
{
MidiEvent event;
event.setB(0);
- event.setTime(audioDriver->framePos());
+ event.setTime(audio->timestamp());
switch(ev->type) {
case SND_SEQ_EVENT_NOTEON:
@@ -211,6 +211,7 @@ void MidiInPort::afterProcess()
//---------------------------------------------------------
// beforeProcess
+// "freeze" fifo for this process cycle
//---------------------------------------------------------
void MidiInPort::beforeProcess()
@@ -221,6 +222,9 @@ void MidiInPort::beforeProcess()
//---------------------------------------------------------
// getEvents
// called from jack process context
+// This method can be called multiple times in a process
+// cycle so we have to empty the fifo at
+// "afterProcess()".
//---------------------------------------------------------
void MidiInPort::getEvents(unsigned, unsigned, int ch, MidiEventList* dst)
diff --git a/muse/muse/synth.cpp b/muse/muse/synth.cpp
index 7c6de9f1..14610669 100644
--- a/muse/muse/synth.cpp
+++ b/muse/muse/synth.cpp
@@ -529,14 +529,14 @@ void MessSynthIF::getData(MidiEventList* el, unsigned pos, int ports, unsigned n
for (int port = 0; port < ports; ++port)
memset(buffer[port], 0, n * sizeof(float));
- // seems to be negative when sequencer not running, still
- // working when entering notes from editor though. weird :-) (ml)
-
int curPos = pos;
int endPos = pos + n;
- while (!synti->putFifo.isEmpty())
- putEvent(synti->putFifo.get());
+ while (!synti->putFifo.isEmpty()) {
+ if (putEvent(synti->putFifo.peek()))
+ break;
+ synti->putFifo.remove();
+ }
if (ports >= channels()) {
iMidiEvent i = el->begin();
@@ -577,9 +577,11 @@ bool MessSynthIF::putEvent(const MidiEvent& ev)
if (_mess) {
rv = _mess->processEvent(ev);
if (midiOutputTrace && !rv) {
- printf("<%s>", synti->name().toLatin1().data());
+ printf("MidiOut<%s>", synti->name().toLatin1().data());
ev.dump();
}
+if (rv)
+ printf("SYNT BUSY\n");
}
return rv;
}
@@ -591,7 +593,8 @@ bool MessSynthIF::putEvent(const MidiEvent& ev)
void SynthI::collectInputData()
{
bufferEmpty = false;
- unsigned pos = audio->pos().frame();
+ unsigned pos = audio->isPlaying() ? audio->pos().frame()
+ : audio->timestamp();
_sif->getData(&_schedEvents, pos, channels(), segmentSize, buffer);
}