summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Schweer <ws.seh.de>2006-10-29 10:44:07 +0000
committerWerner Schweer <ws.seh.de>2006-10-29 10:44:07 +0000
commit2c03edf215192f735a3d941a343a71c41b86a560 (patch)
tree7d07b21e993cd265e08732a14420e4e54724b9e4
parenta49662bfe24c7bd24435e477a6fdb8263c5f5f2a (diff)
fixed crash during midi recording
-rw-r--r--muse/ChangeLog3
-rw-r--r--muse/muse/midi.cpp7
-rw-r--r--muse/muse/midiinport.cpp44
-rw-r--r--muse/muse/midiinport.h8
-rw-r--r--muse/muse/synth.cpp1
5 files changed, 52 insertions, 11 deletions
diff --git a/muse/ChangeLog b/muse/ChangeLog
index b3f2b6e5..65091471 100644
--- a/muse/ChangeLog
+++ b/muse/ChangeLog
@@ -1,3 +1,6 @@
+29.10 (ws)
+ - fixed crash after some time of midi recording: made midi
+ input queue thread safe.
27.10 (ws)
- added a MESS port of the Zynaddsubfx software synthesizer
25.10 (ws)
diff --git a/muse/muse/midi.cpp b/muse/muse/midi.cpp
index 987567ce..0eaeceb4 100644
--- a/muse/muse/midi.cpp
+++ b/muse/muse/midi.cpp
@@ -639,15 +639,16 @@ void Audio::initDevices()
void Audio::processMidi()
{
+ MidiInPortList* il = song->midiInPorts();
+ for (iMidiInPort id = il->begin(); id != il->end(); ++id)
+ (*id)->beforeProcess();
+
MidiOutPortList* ol = song->midiOutPorts();
for (iMidiOutPort id = ol->begin(); id != ol->end(); ++id) {
(*id)->process(_curTickPos, _nextTickPos, _pos.frame(), _pos.frame() + segmentSize);
}
-
- MidiInPortList* il = song->midiInPorts();
for (iMidiInPort id = il->begin(); id != il->end(); ++id) {
MidiInPort* port = *id;
-
//
// process routing to synti
//
diff --git a/muse/muse/midiinport.cpp b/muse/muse/midiinport.cpp
index 8d2db3c9..42fe2677 100644
--- a/muse/muse/midiinport.cpp
+++ b/muse/muse/midiinport.cpp
@@ -36,7 +36,10 @@
MidiInPort::MidiInPort()
: MidiTrackBase(MIDI_IN)
{
- _channels = 1;
+ _channels = 1;
+ recordRead = 0;
+ recordWrite = 0;
+ recordCount = 0;
}
//---------------------------------------------------------
@@ -88,6 +91,7 @@ void MidiInPort::read(QDomNode node)
//---------------------------------------------------------
// midiReceived
+// called from midiSeq context
//---------------------------------------------------------
#ifndef __APPLE__
@@ -96,6 +100,7 @@ void MidiInPort::eventReceived(snd_seq_event_t* ev)
MidiEvent event;
event.setB(0);
event.setTime(audioDriver->framePos());
+
switch(ev->type) {
case SND_SEQ_EVENT_NOTEON:
event.setChannel(ev->data.note.channel);
@@ -173,7 +178,15 @@ void MidiInPort::eventReceived(snd_seq_event_t* ev)
if (i->type() == ME_NOTEON)
addMidiMeter(i->dataB());
song->putEvent(*i);
- _recordEvents.add(*i);
+ if (recordCount == RECORD_FIFO_SIZE) {
+ printf("MusE: eventReceived(): fifo overflow\n");
+ continue;
+ }
+ recordFifo[recordWrite] = *i;
+ ++recordWrite;
+ if (recordWrite == RECORD_FIFO_SIZE)
+ recordWrite = 0;
+ ++recordCount;
}
}
#endif
@@ -185,19 +198,36 @@ void MidiInPort::eventReceived(snd_seq_event_t* ev)
void MidiInPort::afterProcess()
{
- _recordEvents.clear();
+ while (tmpRecordCount--) {
+ ++recordRead;
+ if (recordRead >= RECORD_FIFO_SIZE)
+ recordRead = 0;
+ --recordCount;
+ }
+ }
+
+//---------------------------------------------------------
+// beforeProcess
+//---------------------------------------------------------
+
+void MidiInPort::beforeProcess()
+ {
+ tmpRecordCount = recordCount;
}
//---------------------------------------------------------
// getEvents
+// called from jack process context
//---------------------------------------------------------
void MidiInPort::getEvents(unsigned, unsigned, int ch, MPEventList* dst)
{
- for (iMPEvent i = _recordEvents.begin(); i != _recordEvents.end(); ++i) {
- if (i->channel() == ch || ch == -1)
- dst->insert(*i);
+ int tmpRecordRead = recordRead;
+ for (int i = 0; i < tmpRecordCount; ++i) {
+ dst->insert(recordFifo[tmpRecordRead]);
+ ++tmpRecordRead;
+ if (tmpRecordRead >= RECORD_FIFO_SIZE)
+ tmpRecordRead = 0;
}
}
-
diff --git a/muse/muse/midiinport.h b/muse/muse/midiinport.h
index d1c294eb..9f2d5134 100644
--- a/muse/muse/midiinport.h
+++ b/muse/muse/midiinport.h
@@ -23,6 +23,8 @@
#include "track.h"
+static const int RECORD_FIFO_SIZE = 512;
+
//---------------------------------------------------------
// MidiInPort
//---------------------------------------------------------
@@ -30,7 +32,10 @@
class MidiInPort : public MidiTrackBase {
Q_OBJECT
- MPEventList _recordEvents;
+ MidiEvent recordFifo[RECORD_FIFO_SIZE];
+ int recordRead, recordWrite;
+ volatile int recordCount;
+ int tmpRecordCount;
public:
MidiInPort();
@@ -47,6 +52,7 @@ class MidiInPort : public MidiTrackBase {
void eventReceived(snd_seq_event_t*);
#endif
virtual void getEvents(unsigned from, unsigned to, int channel, MPEventList* dst);
+ void beforeProcess();
void afterProcess();
};
diff --git a/muse/muse/synth.cpp b/muse/muse/synth.cpp
index 0e75dad5..1adf3c7b 100644
--- a/muse/muse/synth.cpp
+++ b/muse/muse/synth.cpp
@@ -554,6 +554,7 @@ iMPEvent MessSynthIF::getData(MPEventList* el, iMPEvent i, unsigned pos, int por
bool MessSynthIF::putEvent(const MidiEvent& ev)
{
+// printf("put event %x %x %x\n", ev.type(), ev.dataA(), ev.dataB());
if (midiOutputTrace)
ev.dump();
if (_mess)