From e3e166d62ba123e43b6383bdcc7b325e43c083f7 Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Sat, 6 Feb 2010 06:12:13 +0000 Subject: See ChangeLog --- muse/ChangeLog | 3 +++ muse/muse/driver/jack.cpp | 26 ++++++++++++++++++++++++-- muse/muse/driver/jackmidi.cpp | 15 +++++++++------ muse/muse/midi.cpp | 16 +++++++++++----- muse/muse/mididev.cpp | 9 ++++++++- muse/muse/sync.cpp | 31 +++++++++++++++++++++++-------- 6 files changed, 78 insertions(+), 22 deletions(-) diff --git a/muse/ChangeLog b/muse/ChangeLog index 9451c5ac..e4d60b27 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,6 @@ +06.02.2010 + * Fixed: MusE hanging on close, with Jack driver. (T356) + - Unregister Jack midi ports on destruction of JackAudioDevice. 05.02.2010 * Fixed: Top level windows: Do not open if there are no parts. Case: bogus -1 top-level part index stored in med file. (T356) - Changed MusE::readToplevels() and stuff in listedit.cpp diff --git a/muse/muse/driver/jack.cpp b/muse/muse/driver/jack.cpp index 41092cea..4cd471b0 100644 --- a/muse/muse/driver/jack.cpp +++ b/muse/muse/driver/jack.cpp @@ -266,6 +266,7 @@ int JackAudioDevice::processAudio(jack_nframes_t frames, void*) handle_jack_midi_in_events(frames); handle_jack_midi_out_events(frames); + // if (JACK_DEBUG) // printf("processAudio - >>>>\n"); segmentSize = frames; @@ -451,11 +452,23 @@ JackAudioDevice::~JackAudioDevice() if (JACK_DEBUG) printf("~JackAudioDevice()\n"); if (_client) { + + // p3.3.35 + for(int i = 0; i < JACK_MIDI_CHANNELS; i++) + { + if(midi_port_in[i]) + jack_port_unregister(_client, midi_port_in[i]); + if(midi_port_out[i]) + jack_port_unregister(_client, midi_port_out[i]); + } + if (jack_client_close(_client)) { //error->logError("jack_client_close() failed: %s\n", strerror(errno)); fprintf(stderr,"jack_client_close() failed: %s\n", strerror(errno)); } } + if (JACK_DEBUG) + printf("~JackAudioDevice() after jack_client_close()\n"); } //--------------------------------------------------------- @@ -499,6 +512,13 @@ char* JackAudioDevice::getJackName() bool initJackAudio() { + // p3.3.35 + for(int i = 0; i < JACK_MIDI_CHANNELS; i++) + { + midi_port_in[i] = 0; + midi_port_out[i] = 0; + } + if (JACK_DEBUG) printf("initJackAudio()\n"); if (debugMsg) { @@ -538,7 +558,7 @@ bool initJackAudio() } undoSetuid(); - /* setup midi input/output */ + // setup midi input/output 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)); if(client){ @@ -564,7 +584,6 @@ bool initJackAudio() }else{ fprintf(stderr, "WARNING NO muse-jack midi connection\n"); } - /* char buf[80]; @@ -890,6 +909,9 @@ void exitJackAudio() if (jackAudio) delete jackAudio; + if (JACK_DEBUG) + printf("exitJackAudio() after delete jackAudio\n"); + // Added by Tim. p3.3.14 audioDevice = NULL; diff --git a/muse/muse/driver/jackmidi.cpp b/muse/muse/driver/jackmidi.cpp index b4e88683..52a696f0 100644 --- a/muse/muse/driver/jackmidi.cpp +++ b/muse/muse/driver/jackmidi.cpp @@ -281,12 +281,15 @@ bool initMidiJack() 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"); - } + +// Removed p3.3.35 +/// 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 */ diff --git a/muse/muse/midi.cpp b/muse/muse/midi.cpp index 4efd3ece..ffb40ba2 100644 --- a/muse/muse/midi.cpp +++ b/muse/muse/midi.cpp @@ -1106,8 +1106,13 @@ void Audio::processMidi() //unsigned time = event.time() + (extsync ? config.division/24 : segmentSize*(segmentCount-1)); // p3.3.34 // Oops, use the current tick. - unsigned time = extsync ? curTickPos : (event.time() + segmentSize*(segmentCount-1)); - event.setTime(time); + //unsigned time = extsync ? curTickPos : (event.time() + segmentSize*(segmentCount-1)); + //event.setTime(time); + // p3.3.35 + // If ext sync, events are now time-stamped with last tick in MidiDevice::recordEvent(). + // TODO: Tested, but record resolution not so good. Switch to wall clock based separate list in MidiDevice. + if(!extsync) + event.setTime(event.time() + segmentSize*(segmentCount-1)); // dont't echo controller changes back to software // synthesizer: @@ -1140,9 +1145,10 @@ void Audio::processMidi() // If syncing externally the event time is already in units of ticks, set above. if(!extsync) { - - time = tempomap.frame2tick(event.time()); - event.setTime(time); // set tick time + // p3.3.35 + //time = tempomap.frame2tick(event.time()); + //event.setTime(time); // set tick time + event.setTime(tempomap.frame2tick(event.time())); // set tick time } // Special handling of events stored in rec-lists. a bit hACKish. TODO: Clean up (after 0.7)! :-/ (ml) diff --git a/muse/muse/mididev.cpp b/muse/muse/mididev.cpp index 48a8fa9f..7d02cc74 100644 --- a/muse/muse/mididev.cpp +++ b/muse/muse/mididev.cpp @@ -34,6 +34,8 @@ extern bool initMidiJack(); MidiDeviceList midiDevices; extern void processMidiInputTransformPlugins(MEvent&); +extern unsigned int volatile lastExtMidiSyncTick; + //--------------------------------------------------------- // initMidiDevices //--------------------------------------------------------- @@ -50,6 +52,7 @@ void initMidiDevices() "your configuration."); exit(-1); } + if(initMidiJack()) { QMessageBox::critical(NULL, "MusE fatal error.", "MusE failed to initialize the\n" @@ -158,7 +161,11 @@ MREventList* MidiDevice::recordEvents() void MidiDevice::recordEvent(MidiRecordEvent& event) { - event.setTime(audio->timestamp()); + // p3.3.35 + // TODO: Tested, but record resolution not so good. Switch to wall clock based separate list in MidiDevice. And revert this line. + //event.setTime(audio->timestamp()); + event.setTime(extSyncFlag.value() ? lastExtMidiSyncTick : audio->timestamp()); + // Added by Tim. p3.3.8 // By T356. Set the loop number which the event came in at. diff --git a/muse/muse/sync.cpp b/muse/muse/sync.cpp index f5b983fc..6b8e959c 100644 --- a/muse/muse/sync.cpp +++ b/muse/muse/sync.cpp @@ -51,6 +51,9 @@ static bool playPendingFirstClock = false; unsigned int syncSendFirstClockDelay = 1; // In milliseconds. //static int lastStoppedBeat = 0; static unsigned int curExtMidiSyncTick = 0; +unsigned int volatile lastExtMidiSyncTick = 0; +double volatile curExtMidiSyncTime = 0.0; +double volatile lastExtMidiSyncTime = 0.0; // Not used yet. // static bool mcStart = false; @@ -799,6 +802,8 @@ void MidiSeq::setSongPosition(int port, int midiBeat) midiPorts[p].sendSongpos(midiBeat); curExtMidiSyncTick = (config.division * midiBeat) / 4; + lastExtMidiSyncTick = curExtMidiSyncTick; + //Pos pos((config.division * midiBeat) / 4, true); Pos pos(curExtMidiSyncTick, true); @@ -931,8 +936,11 @@ void MidiSeq::realtimeSystemInput(int port, int c) //if(audio->isPlaying()) if(playStateExt) { + lastExtMidiSyncTime = curExtMidiSyncTime; + curExtMidiSyncTime = curTime(); int div = config.division/24; midiExtSyncTicks += div; + lastExtMidiSyncTick = curExtMidiSyncTick; curExtMidiSyncTick += div; } @@ -1222,6 +1230,7 @@ void MidiSeq::realtimeSystemInput(int port, int c) if(midiPorts[port].syncInfo().recRewOnStart()) { curExtMidiSyncTick = 0; + lastExtMidiSyncTick = curExtMidiSyncTick; //audioDevice->seekTransport(0); audioDevice->seekTransport(Pos(0, false)); } @@ -1279,35 +1288,41 @@ void MidiSeq::realtimeSystemInput(int port, int c) break; case 0xfc: // stop { + // p3.3.35 + // Stop the increment right away. + midiExtSyncTicks = 0; + playStateExt = false; + playPendingFirstClock = false; + // Re-transmit stop to other devices if clock out turned on. for(int p = 0; p < MIDI_PORTS; ++p) //if(p != port && midiPorts[p].syncInfo().MCOut()) if(p != port && midiPorts[p].syncInfo().MRTOut()) midiPorts[p].sendStop(); - playPendingFirstClock = false; + //playPendingFirstClock = false; //lastStoppedBeat = (audio->tickPos() * 4) / config.division; //curExtMidiSyncTick = (config.division * lastStoppedBeat) / 4; - if (debugSync) - printf("realtimeSystemInput stop\n"); - // p3.3.31 //printf("stop:%f\n", curTime()); if (audio->isPlaying() /*state == PLAY*/) { audio->msgPlay(false); - playStateExt = false; + //playStateExt = false; } + if (debugSync) + printf("realtimeSystemInput stop\n"); + // Just in case the process still runs a cycle or two and causes the // audio tick position to increment, reset the incrementer and force // the transport position to what the hardware thinks is the current position. - midiExtSyncTicks = 0; + //midiExtSyncTicks = 0; //Pos pos((config.division * lastStoppedBeat) / 4, true); - Pos pos(curExtMidiSyncTick, true); - audioDevice->seekTransport(pos); + //Pos pos(curExtMidiSyncTick, true); + //audioDevice->seekTransport(pos); } break; -- cgit v1.2.3