From 2c03edf215192f735a3d941a343a71c41b86a560 Mon Sep 17 00:00:00 2001 From: Werner Schweer Date: Sun, 29 Oct 2006 10:44:07 +0000 Subject: fixed crash during midi recording --- muse/ChangeLog | 3 +++ muse/muse/midi.cpp | 7 ++++--- muse/muse/midiinport.cpp | 44 +++++++++++++++++++++++++++++++++++++------- muse/muse/midiinport.h | 8 +++++++- muse/muse/synth.cpp | 1 + 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) -- cgit v1.2.3