From 789fa3eb5a351baeb437236dcbbf60ce1bac16cf Mon Sep 17 00:00:00 2001 From: Werner Schweer Date: Fri, 27 Jun 2008 16:49:05 +0000 Subject: jack midi input update --- muse/CMakeLists.txt | 2 +- muse/ChangeLog | 2 + muse/doc/dimpl/CMakeLists.txt | 8 +--- muse/muse/audio.cpp | 12 ++--- muse/muse/audiodev.h | 2 - muse/muse/jack.cpp | 53 +++------------------- muse/muse/jackaudio.h | 7 +-- muse/muse/midi.h | 34 ++++++++------ muse/muse/midiinport.cpp | 102 ++++++++++++++++-------------------------- muse/muse/midioutport.cpp | 3 +- muse/muse/miditrack.cpp | 7 +-- 11 files changed, 85 insertions(+), 147 deletions(-) diff --git a/muse/CMakeLists.txt b/muse/CMakeLists.txt index 8404f25f..3712f50d 100644 --- a/muse/CMakeLists.txt +++ b/muse/CMakeLists.txt @@ -339,5 +339,5 @@ IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") INCLUDE(CPack) ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") -subdirs(al awl grepmidi plugins midiplugins muse share synti) +subdirs(al awl grepmidi plugins midiplugins muse share synti doc) diff --git a/muse/ChangeLog b/muse/ChangeLog index 88d7a463..6c6a0185 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,5 @@ +27.6. (ws) + JACK cleanups and implementation of JACK midi input 25.6. (ws) As part of a major code cleanup i removed ALSA midi. This also removes the need for a realtime timer (JACK midi and MusE are competing for it) and simplifies diff --git a/muse/doc/dimpl/CMakeLists.txt b/muse/doc/dimpl/CMakeLists.txt index ab88e87c..9611881e 100644 --- a/muse/doc/dimpl/CMakeLists.txt +++ b/muse/doc/dimpl/CMakeLists.txt @@ -20,8 +20,8 @@ set (SRC dimpl.tex) -add_custom_command ( - OUTPUT dimpl.pdf +add_custom_target ( + dimpl DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dimpl.tex COMMAND ${TEXEXEC_PATH}/texexec ARGS --language=en --verbose --batch --pdf @@ -30,10 +30,6 @@ add_custom_command ( WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) -add_custom_target ( program_doc - DEPENDS dimpl.pdf - ) - install_files ( /share/${MusE_INSTALL_NAME}/doc/ .pdf ${CMAKE_CURRENT_BINARY_DIR}/dimpl.pdf ) diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp index c4121e47..7238c2c1 100644 --- a/muse/muse/audio.cpp +++ b/muse/muse/audio.cpp @@ -279,7 +279,8 @@ printf("JACK: shutdown callback\n"); void Audio::process(unsigned frames, int jackState) { - _seqTime.lastFrameTime = audioDriver->lastFrameTime(); +// _seqTime.lastFrameTime = audioDriver->lastFrameTime(); + _seqTime.lastFrameTime = audioDriver->frameTime(); // // process messages from gui @@ -579,9 +580,9 @@ void Audio::processMsg() void Audio::seek(const Pos& p) { _seqTime.pos.setFrame(p.frame()); - _seqTime.curTickPos = _seqTime.pos.tick(); - _seqTime.nextTickPos = _seqTime.curTickPos; - updateController = true; + _seqTime.curTickPos = _seqTime.pos.tick(); + _seqTime.nextTickPos = _seqTime.curTickPos; + updateController = true; loopPassed = true; // for record loop mode if (state != LOOP2 && !freewheel()) @@ -602,7 +603,6 @@ void Audio::seek(const Pos& p) void Audio::startRolling() { - startRecordPos = _seqTime.pos; if (song->record()) { startRecordPos = _seqTime.pos; recording = true; @@ -641,7 +641,7 @@ void Audio::stopRolling() recording = false; endRecordPos = _seqTime.pos; - _bounce = 0; + _bounce = 0; sendMsgToGui(MSG_STOP); seek(_seqTime.pos); } diff --git a/muse/muse/audiodev.h b/muse/muse/audiodev.h index 56479c71..39521a03 100644 --- a/muse/muse/audiodev.h +++ b/muse/muse/audiodev.h @@ -38,9 +38,7 @@ 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 curFrame() const = 0; virtual unsigned frameTime() const = 0; - virtual unsigned lastFrameTime() const = 0; virtual float* getBuffer(Port, unsigned long nframes) = 0; virtual void registerClient() = 0; virtual Port registerOutPort(const QString& name, bool midi) = 0; diff --git a/muse/muse/jack.cpp b/muse/muse/jack.cpp index 7c1368b1..ff32846e 100644 --- a/muse/muse/jack.cpp +++ b/muse/muse/jack.cpp @@ -105,16 +105,9 @@ static void timebase_callback(jack_transport_state_t /* state */, // JACK callback //--------------------------------------------------------- -static int processAudio(jack_nframes_t frames, void*) +int JackAudio::processAudio(jack_nframes_t frames, void*) { -#if 0 - unsigned t1 = jackAudio->frameTime(); - unsigned t2 = jackAudio->lastFrameTime(); - unsigned t3 = jackAudio->framesSinceCyleStart(); - unsigned t4 = jackAudio->getCurFrame(); - -printf("cycle %8d %8d %8d %08d\n", t1, t2, t3, t4); -#endif + jackAudio->_frameCounter += frames; int jackState = jackAudio->getTransportState(); segmentSize = frames; @@ -223,6 +216,7 @@ JackAudio::JackAudio(jack_client_t* cl, char* name) { strcpy(jackRegisteredName, name); _client = cl; + _frameCounter = 0; } //--------------------------------------------------------- @@ -468,12 +462,6 @@ void JackAudio::graphChanged() audio->msgAddRoute1(r); } -//static int xrun_callback(void*) -// { -// printf("JACK: xrun\n"); -// return 0; -// } - //--------------------------------------------------------- // register //--------------------------------------------------------- @@ -487,7 +475,6 @@ void JackAudio::registerClient() jack_set_sample_rate_callback(_client, srate_callback, 0); jack_set_port_registration_callback(_client, registration_callback, 0); jack_set_graph_order_callback(_client, graph_callback, 0); -// jack_set_xrun_callback(_client, xrun_callback, 0); jack_set_freewheel_callback (_client, freewheel_callback, 0); jack_set_thread_init_callback(_client, (JackThreadInitCallback) jack_thread_init, 0); jack_set_timebase_callback(_client, 0, timebase_callback, 0); @@ -516,12 +503,6 @@ Port JackAudio::registerOutPort(const QString& name, bool midi) const char* type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE; Port p(jack_port_register(_client, name.toLatin1().data(), type, JackPortIsOutput, 0)); // printf("JACK: registerOutPort<%s>: <%s> %p\n", type, name.toLatin1().data(), p.jackPort()); -#if 0 - if (midi) { - jack_nframes_t nframes = jack_get_buffer_size(_client); - jack_midi_reset_new_port(jack_port_get_buffer(p.jackPort(), nframes), nframes); - } -#endif if (!p.jackPort()) p.setZero(); return p; @@ -712,7 +693,6 @@ void JackAudio::setFreewheel(bool f) void JackAudio::startTransport() { -// printf("JACK: startTransport\n"); jack_transport_start(_client); } @@ -722,7 +702,6 @@ void JackAudio::startTransport() void JackAudio::stopTransport() { -// printf("JACK: stopTransport\n"); if (_client) jack_transport_stop(_client); } @@ -733,7 +712,6 @@ void JackAudio::stopTransport() void JackAudio::seekTransport(unsigned frame) { -// printf("JACK: seekTransport %d\n", frame); jack_transport_locate(_client, frame); } @@ -748,7 +726,6 @@ Port JackAudio::findPort(const QString& name) return Port(); } jack_port_t* port = jack_port_by_name(_client, name.toLatin1().data()); -// printf("Jack::findPort <%s>, %p\n", name.toLatin1().data(), port); return (port == 0) ? Port() : Port(port); } @@ -838,9 +815,9 @@ void JackAudio::putEvent(Port port, const MidiEvent& e) e.dump(); } void* pb = jack_port_get_buffer(port.jackPort(), segmentSize); - int ft = e.time() - lastFrameTime(); + int ft = e.time() - _frameCounter; if (ft < 0 || ft >= (int)segmentSize) { - printf("JackAudio::putEvent: time out of range %d\n", ft); + printf("JackAudio::putEvent: time out of range %d(seg=%d)\n", ft, segmentSize); if (ft < 0) ft = 0; if (ft > (int)segmentSize) @@ -853,12 +830,7 @@ void JackAudio::putEvent(Port port, const MidiEvent& e) case ME_CONTROLLER: case ME_PITCHBEND: { -#ifdef JACK107 unsigned char* p = jack_midi_event_reserve(pb, ft, 3); -#endif -#ifdef JACK103 - unsigned char* p = jack_midi_event_reserve(pb, ft, 3, segmentSize); -#endif if (p == 0) { fprintf(stderr, "JackMidi: buffer overflow, event lost\n"); return; @@ -872,12 +844,7 @@ void JackAudio::putEvent(Port port, const MidiEvent& e) case ME_PROGRAM: case ME_AFTERTOUCH: { -#ifdef JACK107 unsigned char* p = jack_midi_event_reserve(pb, ft, 2); -#endif -#ifdef JACK103 - unsigned char* p = jack_midi_event_reserve(pb, ft, 2, segmentSize); -#endif if (p == 0) { fprintf(stderr, "JackMidi: buffer overflow, event lost\n"); return; @@ -890,12 +857,7 @@ void JackAudio::putEvent(Port port, const MidiEvent& e) { const unsigned char* data = e.data(); int len = e.len(); -#ifdef JACK107 unsigned char* p = jack_midi_event_reserve(pb, ft, len+2); -#endif -#ifdef JACK103 - unsigned char* p = jack_midi_event_reserve(pb, ft, len+2, segmentSize); -#endif if (p == 0) { fprintf(stderr, "JackMidi: buffer overflow, event lost\n"); return; @@ -922,12 +884,7 @@ void JackAudio::putEvent(Port port, const MidiEvent& e) void JackAudio::startMidiCycle(Port port) { void* port_buf = jack_port_get_buffer(port.jackPort(), segmentSize); -#ifdef JACK107 jack_midi_clear_buffer(port_buf); -#endif -#ifdef JACK103 - jack_midi_clear_buffer(port_buf, segmentSize); -#endif } //--------------------------------------------------------- diff --git a/muse/muse/jackaudio.h b/muse/muse/jackaudio.h index 7a7d5474..1839d27e 100644 --- a/muse/muse/jackaudio.h +++ b/muse/muse/jackaudio.h @@ -33,6 +33,9 @@ class JackAudio : public AudioDriver { jack_position_t pos; char jackRegisteredName[8]; jack_transport_state_t transportState; + jack_nframes_t _frameCounter; + + static int processAudio(jack_nframes_t frames, void*); public: JackAudio(jack_client_t* cl, char * jack_id_string); @@ -79,9 +82,7 @@ class JackAudio : public AudioDriver { virtual void putEvent(Port, const MidiEvent&); virtual void startMidiCycle(Port); - virtual unsigned lastFrameTime() const { return jack_last_frame_time(_client); } - virtual unsigned frameTime() const { return jack_frame_time(_client); } - virtual unsigned curFrame() const { return pos.frame; } + virtual unsigned frameTime() const { return _frameCounter; } virtual void collectMidiEvents(MidiInPort*, Port); }; diff --git a/muse/muse/midi.h b/muse/muse/midi.h index 09d6a1e9..d6713c5a 100644 --- a/muse/muse/midi.h +++ b/muse/muse/midi.h @@ -22,20 +22,26 @@ #define __MIDI_H__ enum { - ME_NOTEOFF = 0x80, - ME_NOTEON = 0x90, - ME_POLYAFTER = 0xa0, - ME_CONTROLLER = 0xb0, - ME_PROGRAM = 0xc0, - ME_AFTERTOUCH = 0xd0, - ME_PITCHBEND = 0xe0, - ME_SYSEX = 0xf0, - ME_META = 0xff, - ME_SONGPOS = 0xf2, - ME_CLOCK = 0xf8, - ME_START = 0xfa, - ME_CONTINUE = 0xfb, - ME_STOP = 0xfc, + ME_NOTEOFF = 0x80, + ME_NOTEON = 0x90, + ME_POLYAFTER = 0xa0, + ME_CONTROLLER = 0xb0, + ME_PROGRAM = 0xc0, + ME_AFTERTOUCH = 0xd0, + ME_PITCHBEND = 0xe0, + ME_SYSEX = 0xf0, + ME_META = 0xff, + ME_MTC_QUARTER = 0xf1, + ME_SONGPOS = 0xf2, + ME_SONGSEL = 0xf3, + ME_TUNE_REQ = 0xf6, + ME_SYSEX_END = 0xf7, + ME_CLOCK = 0xf8, + ME_TICK = 0xf9, + ME_START = 0xfa, + ME_CONTINUE = 0xfb, + ME_STOP = 0xfc, + ME_SENSE = 0xfe, }; #define ME_TIMESIG 0x58 diff --git a/muse/muse/midiinport.cpp b/muse/muse/midiinport.cpp index 8953725d..afe53876 100644 --- a/muse/muse/midiinport.cpp +++ b/muse/muse/midiinport.cpp @@ -105,71 +105,52 @@ void MidiInPort::eventReceived(jack_midi_event_t* ev) // ^ ^ ^ // catch process play // - event.setTime(audioDriver->frameTime() + ev->time); - - switch(*(ev->buffer) & 0xf0) { - case 0x90: - event.setChannel(*(ev->buffer) & 0xf); - event.setType(ME_NOTEON); + const SeqTime* st = audio->seqTime(); + +// unsigned curFrame = st->startFrame() + segmentSize; + unsigned curFrame = st->lastFrameTime; + event.setTime(curFrame + ev->time); + + event.setChannel(*(ev->buffer) & 0xf); + int type = *(ev->buffer) & 0xf0; + int a = *(ev->buffer + 1) & 0x7f; + int b = *(ev->buffer + 2) & 0x7f; + event.setType(type); + switch(type) { + case ME_NOTEON: + case ME_NOTEOFF: + case ME_CONTROLLER: event.setA(*(ev->buffer + 1)); event.setB(*(ev->buffer + 2)); break; - case 0x80: - event.setChannel(*(ev->buffer) & 0xf); - event.setType(ME_NOTEOFF); + case ME_PROGRAM: + case ME_AFTERTOUCH: event.setA(*(ev->buffer + 1)); - event.setB(*(ev->buffer + 2)); - break; -#if 0 - case SND_SEQ_EVENT_KEYPRESS: - event.setChannel(ev->data.note.channel); - event.setType(ME_POLYAFTER); - event.setA(ev->data.note.note); - event.setB(ev->data.note.velocity); - break; - - case SND_SEQ_EVENT_SYSEX: - event.setTime(0); // mark as used - event.setType(ME_SYSEX); - event.setData((unsigned char*)(ev->data.ext.ptr)+1, - ev->data.ext.len-2); - break; - - case SND_SEQ_EVENT_NOTEOFF: - event.setChannel(ev->data.note.channel); - event.setType(ME_NOTEOFF); - event.setA(ev->data.note.note); - event.setB(ev->data.note.velocity); break; - case SND_SEQ_EVENT_CHANPRESS: - event.setChannel(ev->data.control.channel); - event.setType(ME_AFTERTOUCH); - event.setA(ev->data.control.value); + case ME_PITCHBEND: + event.setA(((b << 7) + a) - 8192); break; - case SND_SEQ_EVENT_PGMCHANGE: - event.setChannel(ev->data.control.channel); - event.setType(ME_PROGRAM); - event.setA(ev->data.control.value); - break; - - case SND_SEQ_EVENT_PITCHBEND: - event.setChannel(ev->data.control.channel); - event.setType(ME_CONTROLLER); - event.setA(CTRL_PITCH); - event.setB(ev->data.control.value); - break; - - case SND_SEQ_EVENT_CONTROLLER: - event.setChannel(ev->data.control.channel); - event.setType(ME_CONTROLLER); - event.setA(ev->data.control.param); - event.setB(ev->data.control.value); - break; -#endif - default: - return; // ignore + case ME_SYSEX: + { + int type = *(ev->buffer) & 0xff; + switch(type) { + case ME_SYSEX: + event.setTime(0); // mark as used + event.setType(ME_SYSEX); + event.setData((unsigned char*)(ev->buffer + 1), + ev->size - 2); + break; + case ME_CLOCK: + case ME_SENSE: + break; + default: + printf("unknown event 0x%02x\n", type); + return; + } + } + return; } if (midiInputTrace) { @@ -183,7 +164,7 @@ void MidiInPort::eventReceived(jack_midi_event_t* ev) MidiEventList il, ol; il.insert(event); - pipeline()->apply(audio->seqTime()->curTickPos, audio->seqTime()->nextTickPos, &il, &ol); + pipeline()->apply(st->curTickPos, st->nextTickPos, &il, &ol); // // update midi activity @@ -218,11 +199,6 @@ void MidiInPort::beforeProcess() { if (!jackPort(0).isZero()) audioDriver->collectMidiEvents(this, jackPort(0)); - -// Port _jackPort[MAX_CHANNELS]; - // collect jack midi events -// void eventReceived(snd_seq_event_t*); - tmpRecordCount = recordFifo.getSize(); } diff --git a/muse/muse/midioutport.cpp b/muse/muse/midioutport.cpp index e3acc736..06c247d1 100644 --- a/muse/muse/midioutport.cpp +++ b/muse/muse/midioutport.cpp @@ -149,7 +149,8 @@ void MidiOutPort::queueJackEvent(const MidiEvent& ev) unsigned t = ev.time(); if (a == CTRL_PITCH) { - JO(MidiEvent(t, chn, ME_PITCHBEND, b, 0)); + int v = b + 8192; + JO(MidiEvent(t, chn, ME_PITCHBEND, v & 0x7f, (v >> 7) & 0x7f)); } else if (a == CTRL_PROGRAM) { // don't output program changes for GM drum channel diff --git a/muse/muse/miditrack.cpp b/muse/muse/miditrack.cpp index a14a2f75..276eeccb 100644 --- a/muse/muse/miditrack.cpp +++ b/muse/muse/miditrack.cpp @@ -215,8 +215,8 @@ void MidiTrack::startRecording() void MidiTrack::recordBeat() { int updateFlags = 0; - unsigned cpos = song->cpos(); - unsigned ptick = recordPart->tick(); + unsigned cpos = song->cpos(); + unsigned ptick = recordPart->tick(); if (song->punchout()) { if (song->rPos() >= song->cPos()) { @@ -547,7 +547,7 @@ void MidiTrack::processMidi(SeqTime* t) // if (autoRead()) { for (iCtrl ic = controller()->begin(); ic != controller()->end(); ++ic) { - Ctrl* c = ic->second; + Ctrl* c = ic->second; iCtrlVal is = c->lowerBound(t->curTickPos); iCtrlVal ie = c->lowerBound(t->nextTickPos); for (iCtrlVal ic = is; ic != ie; ++ic) { @@ -601,6 +601,7 @@ void MidiTrack::processMidi(SeqTime* t) event.setB(velo); } } + event.setTime(eventTime + segmentSize); schedEvents.insert(event); } } -- cgit v1.2.3