mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
generalize hans' midi_clock_timestamp to be a general timestamp for incoming MIDI data (from JACK); make JACK_MidiPort::read() abort, because it should never ever be called; make JACK_MidiPort::~JackMIDIPort() unregister ports when it is destroyed; pass along the timestamp to MTC qtr and full signals
git-svn-id: svn://localhost/ardour2/branches/3.0@6254 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
ce2d9cb4aa
commit
b825b86862
4 changed files with 36 additions and 52 deletions
|
|
@ -20,6 +20,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "pbd/error.h"
|
#include "pbd/error.h"
|
||||||
|
|
||||||
|
|
@ -49,7 +50,15 @@ JACK_MidiPort::JACK_MidiPort(const XMLNode& node, jack_client_t* jack_client)
|
||||||
|
|
||||||
JACK_MidiPort::~JACK_MidiPort()
|
JACK_MidiPort::~JACK_MidiPort()
|
||||||
{
|
{
|
||||||
// FIXME: remove port
|
if (_jack_input_port) {
|
||||||
|
jack_port_unregister (_jack_client, _jack_input_port);
|
||||||
|
_jack_input_port = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_jack_output_port) {
|
||||||
|
jack_port_unregister (_jack_client, _jack_input_port);
|
||||||
|
_jack_input_port = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -80,8 +89,7 @@ JACK_MidiPort::cycle_start (nframes_t nframes)
|
||||||
|
|
||||||
if (input_parser) {
|
if (input_parser) {
|
||||||
for (size_t i = 0; i < ev.size; i++) {
|
for (size_t i = 0; i < ev.size; i++) {
|
||||||
// the midi events here are used for MIDI clock only
|
input_parser->set_timestamp (ev.time + jack_last_frame_time(_jack_client));
|
||||||
input_parser->set_midi_clock_timestamp(ev.time + jack_last_frame_time(_jack_client));
|
|
||||||
input_parser->scanner (ev.buffer[i]);
|
input_parser->scanner (ev.buffer[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -203,35 +211,8 @@ JACK_MidiPort::flush (void* jack_port_buffer)
|
||||||
int
|
int
|
||||||
JACK_MidiPort::read(byte * buf, size_t bufsize)
|
JACK_MidiPort::read(byte * buf, size_t bufsize)
|
||||||
{
|
{
|
||||||
assert(_currently_in_cycle);
|
cerr << "This program is improperly written. JACK_MidiPort::read() should never be called\n";
|
||||||
assert(_jack_input_port);
|
abort ();
|
||||||
|
|
||||||
jack_midi_event_t ev;
|
|
||||||
|
|
||||||
cerr << "JACK_MidiPort::read called" << endl;
|
|
||||||
|
|
||||||
int err = jack_midi_event_get (&ev,
|
|
||||||
jack_port_get_buffer(_jack_input_port, _nframes_this_cycle),
|
|
||||||
_last_read_index++);
|
|
||||||
|
|
||||||
// XXX this doesn't handle ev.size > max
|
|
||||||
|
|
||||||
if (!err) {
|
|
||||||
size_t limit = min (bufsize, ev.size);
|
|
||||||
memcpy(buf, ev.buffer, limit);
|
|
||||||
|
|
||||||
if (input_parser) {
|
|
||||||
input_parser->raw_preparse (*input_parser, buf, limit);
|
|
||||||
for (size_t i = 0; i < limit; i++) {
|
|
||||||
input_parser->scanner (buf[i]);
|
|
||||||
}
|
|
||||||
input_parser->raw_postparse (*input_parser, buf, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
return limit;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,15 @@ class Parser : public sigc::trackable {
|
||||||
public:
|
public:
|
||||||
Parser (Port &p);
|
Parser (Port &p);
|
||||||
~Parser ();
|
~Parser ();
|
||||||
|
|
||||||
|
/* sets the time that will be reported for any MTC or MIDI Clock
|
||||||
|
message the next time ::scanner() parses such a message. It should
|
||||||
|
therefore be set before every byte passed into ::scanner().
|
||||||
|
*/
|
||||||
|
|
||||||
|
nframes_t get_timestamp() const { return _timestamp; }
|
||||||
|
void set_timestamp (const nframes_t timestamp) { _timestamp = timestamp; }
|
||||||
|
|
||||||
/* signals that anyone can connect to */
|
/* signals that anyone can connect to */
|
||||||
|
|
||||||
OneByteSignal bank_change;
|
OneByteSignal bank_change;
|
||||||
|
|
@ -64,8 +72,8 @@ class Parser : public sigc::trackable {
|
||||||
sigc::signal<void, Parser &> channel_active_preparse[16];
|
sigc::signal<void, Parser &> channel_active_preparse[16];
|
||||||
sigc::signal<void, Parser &> channel_active_postparse[16];
|
sigc::signal<void, Parser &> channel_active_postparse[16];
|
||||||
|
|
||||||
OneByteSignal mtc_quarter_frame;
|
OneByteSignal mtc_quarter_frame; /* see below for more useful signals */
|
||||||
|
Signal mtc;
|
||||||
Signal raw_preparse;
|
Signal raw_preparse;
|
||||||
Signal raw_postparse;
|
Signal raw_postparse;
|
||||||
Signal any;
|
Signal any;
|
||||||
|
|
@ -74,9 +82,6 @@ class Parser : public sigc::trackable {
|
||||||
Signal position;
|
Signal position;
|
||||||
Signal song;
|
Signal song;
|
||||||
|
|
||||||
Signal mtc;
|
|
||||||
sigc::signal<void,Parser&,int> mtc_qtr;
|
|
||||||
|
|
||||||
sigc::signal<void, Parser &> all_notes_off;
|
sigc::signal<void, Parser &> all_notes_off;
|
||||||
sigc::signal<void, Parser &> tune;
|
sigc::signal<void, Parser &> tune;
|
||||||
sigc::signal<void, Parser &, nframes_t> timing;
|
sigc::signal<void, Parser &, nframes_t> timing;
|
||||||
|
|
@ -122,12 +127,10 @@ class Parser : public sigc::trackable {
|
||||||
const byte *mtc_current() const { return _mtc_time; }
|
const byte *mtc_current() const { return _mtc_time; }
|
||||||
bool mtc_locked() const { return _mtc_locked; }
|
bool mtc_locked() const { return _mtc_locked; }
|
||||||
|
|
||||||
nframes_t get_midi_clock_timestamp() const { return _midi_clock_timestamp; }
|
sigc::signal<void,Parser&,int,nframes_t> mtc_qtr;
|
||||||
void set_midi_clock_timestamp(const nframes_t timestamp) { _midi_clock_timestamp = timestamp; }
|
sigc::signal<void,const byte*,bool,nframes_t> mtc_time;
|
||||||
|
sigc::signal<void,MTC_Status> mtc_status;
|
||||||
sigc::signal<void,MTC_Status> mtc_status;
|
sigc::signal<bool> mtc_skipped;
|
||||||
sigc::signal<bool> mtc_skipped;
|
|
||||||
sigc::signal<void,const byte*,bool> mtc_time;
|
|
||||||
|
|
||||||
void set_mtc_forwarding (bool yn) {
|
void set_mtc_forwarding (bool yn) {
|
||||||
_mtc_forward = yn;
|
_mtc_forward = yn;
|
||||||
|
|
@ -172,7 +175,7 @@ class Parser : public sigc::trackable {
|
||||||
bool _mtc_locked;
|
bool _mtc_locked;
|
||||||
byte last_qtr_frame;
|
byte last_qtr_frame;
|
||||||
|
|
||||||
nframes_t _midi_clock_timestamp;
|
nframes_t _timestamp;
|
||||||
|
|
||||||
ParseState pre_variable_state;
|
ParseState pre_variable_state;
|
||||||
MIDI::eventType pre_variable_msgtype;
|
MIDI::eventType pre_variable_msgtype;
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ Parser::possible_mtc (byte *sysex_buf, size_t msglen)
|
||||||
/* emit signals */
|
/* emit signals */
|
||||||
|
|
||||||
mtc (*this, &sysex_buf[1], msglen - 1);
|
mtc (*this, &sysex_buf[1], msglen - 1);
|
||||||
mtc_time (fake_mtc_time, true);
|
mtc_time (fake_mtc_time, true, _timestamp);
|
||||||
mtc_status (MTC_Stopped);
|
mtc_status (MTC_Stopped);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -276,7 +276,7 @@ Parser::process_mtc_quarter_frame (byte *msg)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtc_qtr (*this, which_quarter_frame); /* EMIT_SIGNAL */
|
mtc_qtr (*this, which_quarter_frame, _timestamp); /* EMIT_SIGNAL */
|
||||||
|
|
||||||
// mtc (*this, &msg[1], msglen - 1);
|
// mtc (*this, &msg[1], msglen - 1);
|
||||||
|
|
||||||
|
|
@ -296,7 +296,7 @@ Parser::process_mtc_quarter_frame (byte *msg)
|
||||||
_mtc_locked = true;
|
_mtc_locked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtc_time (_mtc_time, false);
|
mtc_time (_mtc_time, false, _timestamp);
|
||||||
}
|
}
|
||||||
expected_mtc_quarter_frame_code = 0;
|
expected_mtc_quarter_frame_code = 0;
|
||||||
|
|
||||||
|
|
@ -319,7 +319,7 @@ Parser::process_mtc_quarter_frame (byte *msg)
|
||||||
if (!_mtc_locked) {
|
if (!_mtc_locked) {
|
||||||
_mtc_locked = true;
|
_mtc_locked = true;
|
||||||
}
|
}
|
||||||
mtc_time (_mtc_time, false);
|
mtc_time (_mtc_time, false, _timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_mtc_quarter_frame_code = 7;
|
expected_mtc_quarter_frame_code = 7;
|
||||||
|
|
|
||||||
|
|
@ -538,16 +538,16 @@ Parser::realtime_msg(unsigned char inbyte)
|
||||||
|
|
||||||
switch (inbyte) {
|
switch (inbyte) {
|
||||||
case 0xf8:
|
case 0xf8:
|
||||||
timing (*this, _midi_clock_timestamp);
|
timing (*this, _timestamp);
|
||||||
break;
|
break;
|
||||||
case 0xfa:
|
case 0xfa:
|
||||||
start (*this, _midi_clock_timestamp);
|
start (*this, _timestamp);
|
||||||
break;
|
break;
|
||||||
case 0xfb:
|
case 0xfb:
|
||||||
contineu (*this, _midi_clock_timestamp);
|
contineu (*this, _timestamp);
|
||||||
break;
|
break;
|
||||||
case 0xfc:
|
case 0xfc:
|
||||||
stop (*this, _midi_clock_timestamp);
|
stop (*this, _timestamp);
|
||||||
break;
|
break;
|
||||||
case 0xfe:
|
case 0xfe:
|
||||||
/* !!! active sense message in realtime_msg: should not reach here
|
/* !!! active sense message in realtime_msg: should not reach here
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue