fix up delivery of MTC & MMC; add zero=last_timestamp semantics to JACK midi port write call; setup parser execution for JACK MIDI ports

git-svn-id: svn://localhost/ardour2/branches/3.0@3159 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2008-03-19 21:15:28 +00:00
parent 4808f7fe8b
commit 022c45361e
5 changed files with 52 additions and 26 deletions

View file

@ -726,7 +726,7 @@ Session::send_full_time_code(nframes_t nframes)
cerr << "MTC: Sending full time code at " << outbound_mtc_smpte_frame << endl;
// Send message at offset 0, sent time is for the start of this cycle
if (!_mtc_port->midimsg (msg, sizeof (msg), 0)) {
if (_mtc_port->midimsg (msg, sizeof (msg), 0)) {
error << _("Session: could not send full MIDI time code") << endmsg;
return -1;
}
@ -808,9 +808,9 @@ Session::send_midi_time_code_for_cycle(nframes_t nframes)
nframes_t out_stamp = msg_time - _transport_frame;
assert(out_stamp < nframes);
if (!_mtc_port->midimsg (mtc_msg, 2, out_stamp)) {
if (_mtc_port->midimsg (mtc_msg, 2, out_stamp)) {
error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
<< endmsg;
<< endmsg;
return -1;
}
@ -846,11 +846,6 @@ Session::send_midi_time_code_for_cycle(nframes_t nframes)
OUTBOUND MMC STUFF
**********************************************************************/
/** Send an MMC command at the given absolute timestamp (@a where).
*
* This must be called in the process thread, and @a where must fall within
* this process cycle or horrible things will happen.
*/
void
Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
{
@ -859,13 +854,13 @@ Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
SMPTE::Time smpte;
if (_mmc_port == 0 || !session_send_mmc) {
//cerr << "Not delivering MMC " << _mmc_port << " - " << send_mmc << endl;
// cerr << "Not delivering MMC " << _mmc_port << " - " << session_send_mmc << endl;
return;
}
mmc_buffer[nbytes++] = cmd;
//cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
// cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
switch (cmd) {
case MachineControl::cmdLocate:
@ -909,13 +904,9 @@ Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
assert(where >= _transport_frame);
if (!_mmc_port->midimsg (mmc_buffer, sizeof (mmc_buffer), 0)) {
if (_mmc_port->midimsg (mmc_buffer, nbytes, 0)) {
error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
} /*else {
cerr << "Sending MMC\n";
}*/
}
}
}

View file

@ -336,7 +336,7 @@ Session::process_with_events (nframes_t nframes)
}
if (!_exporting) {
send_midi_time_code_for_cycle(nframes);
send_midi_time_code_for_cycle (nframes);
}
if (actively_recording()) {
@ -764,7 +764,7 @@ Session::process_without_events (nframes_t nframes)
}
if (!_exporting) {
send_midi_time_code_for_cycle(nframes);
send_midi_time_code_for_cycle (nframes);
}
if (actively_recording()) {

View file

@ -58,6 +58,7 @@ JACK_MidiPort::cycle_start (nframes_t nframes)
Port::cycle_start(nframes);
assert(_nframes_this_cycle == nframes);
_last_read_index = 0;
_last_write_timestamp = 0;
void *buffer = jack_port_get_buffer (_jack_output_port, nframes);
jack_midi_clear_buffer (buffer);
@ -67,6 +68,8 @@ JACK_MidiPort::cycle_start (nframes_t nframes)
int
JACK_MidiPort::write(byte * msg, size_t msglen, timestamp_t timestamp)
{
int ret = 0;
if (!is_process_thread()) {
Glib::Mutex::Lock lm (non_process_thread_fifo_lock);
@ -74,8 +77,6 @@ JACK_MidiPort::write(byte * msg, size_t msglen, timestamp_t timestamp)
non_process_thread_fifo.get_write_vector (&vec);
cerr << "Non-process thread writes " << msglen << " to " << name() << endl;
if (vec.len[0] + vec.len[1] < 1) {
error << "no space in FIFO for non-process thread MIDI write"
<< endmsg;
@ -89,19 +90,41 @@ JACK_MidiPort::write(byte * msg, size_t msglen, timestamp_t timestamp)
}
non_process_thread_fifo.increment_write_idx (1);
return msglen;
ret = msglen;
} else {
assert(_currently_in_cycle);
assert(timestamp < _nframes_this_cycle);
assert(_jack_output_port);
assert(timestamp < _nframes_this_cycle);
// FIXME: return value correct?
return jack_midi_event_write (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle),
timestamp, msg, msglen);
if (timestamp == 0) {
timestamp = _last_write_timestamp;
}
if (jack_midi_event_write (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle),
timestamp, msg, msglen) == 0) {
ret = msglen;
_last_write_timestamp = timestamp;
} else {
ret = 0;
cerr << "write of " << msglen << " failed, port holds "
<< jack_midi_get_event_count (jack_port_get_buffer (_jack_output_port, _nframes_this_cycle))
<< endl;
}
}
if (ret > 0 && output_parser) {
output_parser->raw_preparse (*output_parser, msg, ret);
for (int i = 0; i < ret; i++) {
output_parser->scanner (msg[i]);
}
output_parser->raw_postparse (*output_parser, msg, ret);
}
return ret;
}
void
@ -156,6 +179,15 @@ JACK_MidiPort::read(byte * buf, size_t bufsize)
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;

View file

@ -73,6 +73,7 @@ private:
jack_port_t* _jack_input_port;
jack_port_t* _jack_output_port;
nframes_t _last_read_index;
timestamp_t _last_write_timestamp;
void flush (void* jack_port_buffer);

View file

@ -143,6 +143,8 @@ Parser::trace_event (Parser &p, byte *msg, size_t len)
eventType type;
ostream *o;
cerr << "TRACE\n";
if ((o = trace_stream) == NULL) { /* can be asynchronously removed */
return;
}