mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
basically, fix all kinds of odds and ends with MIDI playback, including missed notes and applying gain
git-svn-id: svn://localhost/ardour2/branches/3.0@7247 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
8f263c239a
commit
1e728e728a
13 changed files with 107 additions and 35 deletions
|
|
@ -3768,7 +3768,6 @@ NoteDrag::motion (GdkEvent*, bool)
|
||||||
cnote->note()->length(),
|
cnote->note()->length(),
|
||||||
cnote->note()->note() + drag_delta_note,
|
cnote->note()->note() + drag_delta_note,
|
||||||
cnote->note()->velocity()));
|
cnote->note()->velocity()));
|
||||||
bool overlaps = cnote->region_view().midi_region()->model()->overlaps (check_note, cnote->note());
|
|
||||||
|
|
||||||
region->move_selection (dx, dy);
|
region->move_selection (dx, dy);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,9 +167,8 @@ Amp::apply_gain (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t targ
|
||||||
Evoral::MIDIEvent<MidiBuffer::TimeType> ev = *m;
|
Evoral::MIDIEvent<MidiBuffer::TimeType> ev = *m;
|
||||||
|
|
||||||
if (ev.is_note_on()) {
|
if (ev.is_note_on()) {
|
||||||
gain_t scale = delta * (ev.time()/nframes);
|
gain_t scale = delta * (ev.time()/(double) nframes);
|
||||||
std::cerr << "scale by " << scale << " for " << ev.time() << " of " << nframes << std::endl;
|
ev.scale_velocity (initial+scale);
|
||||||
ev.scale_velocity (scale);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,8 +98,8 @@ AudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
AudioPort::raw_buffer_size(nframes_t nframes) const
|
AudioPort::raw_buffer_size (nframes_t nframes) const
|
||||||
{
|
{
|
||||||
return nframes * sizeof(float);
|
return nframes * sizeof (Sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,15 @@ AudioEngine::start ()
|
||||||
}
|
}
|
||||||
|
|
||||||
_raw_buffer_sizes[DataType::AUDIO] = blocksize * sizeof(float);
|
_raw_buffer_sizes[DataType::AUDIO] = blocksize * sizeof(float);
|
||||||
|
|
||||||
|
jack_port_t* midi_port = jack_port_register (_priv_jack, "m", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
|
||||||
|
if (!midi_port) {
|
||||||
|
error << _("Cannot create temporary MIDI port to determine MIDI buffer size") << endmsg;
|
||||||
|
} else {
|
||||||
|
_raw_buffer_sizes[DataType::MIDI] = jack_midi_max_event_size (jack_port_get_buffer(midi_port, blocksize));
|
||||||
|
cerr << "MIDI port buffers = " << _raw_buffer_sizes[DataType::MIDI] << endl;
|
||||||
|
jack_port_unregister (_priv_jack, midi_port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _running ? 0 : -1;
|
return _running ? 0 : -1;
|
||||||
|
|
@ -420,6 +429,7 @@ AudioEngine::process_thread ()
|
||||||
jack_nframes_t nframes = jack_cycle_wait (_jack);
|
jack_nframes_t nframes = jack_cycle_wait (_jack);
|
||||||
|
|
||||||
if (process_callback (nframes)) {
|
if (process_callback (nframes)) {
|
||||||
|
cerr << "--- process\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -583,16 +593,40 @@ AudioEngine::_bufsize_callback (nframes_t nframes, void *arg)
|
||||||
int
|
int
|
||||||
AudioEngine::jack_bufsize_callback (nframes_t nframes)
|
AudioEngine::jack_bufsize_callback (nframes_t nframes)
|
||||||
{
|
{
|
||||||
|
bool need_midi_size = true;
|
||||||
|
bool need_audio_size = true;
|
||||||
|
|
||||||
_buffer_size = nframes;
|
_buffer_size = nframes;
|
||||||
_raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof(float);
|
|
||||||
cout << "FIXME: Assuming maximum MIDI buffer size " << nframes * 4 << "bytes" << endl;
|
|
||||||
_raw_buffer_sizes[DataType::MIDI] = nframes * 4;
|
|
||||||
_usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
|
_usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
|
||||||
last_monitor_check = 0;
|
last_monitor_check = 0;
|
||||||
|
|
||||||
boost::shared_ptr<Ports> p = ports.reader();
|
boost::shared_ptr<Ports> p = ports.reader();
|
||||||
|
|
||||||
|
/* crude guesses, see below where we try to get the right answers.
|
||||||
|
|
||||||
|
Note that our guess for MIDI deliberatey tries to overestimate
|
||||||
|
by a little. It would be nicer if we could get the actual
|
||||||
|
size from a port, but we have to use this estimate in the
|
||||||
|
event that there are no MIDI ports currently. If there are
|
||||||
|
the value will be adjusted below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
_raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
|
||||||
|
_raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
|
||||||
|
|
||||||
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
|
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
|
||||||
|
|
||||||
|
if (need_audio_size && (*i)->type() == DataType::AUDIO) {
|
||||||
|
_raw_buffer_sizes[DataType::AUDIO] = (*i)->raw_buffer_size (nframes);
|
||||||
|
need_audio_size = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (need_midi_size && (*i)->type() == DataType::MIDI) {
|
||||||
|
_raw_buffer_sizes[DataType::MIDI] = (*i)->raw_buffer_size (nframes);
|
||||||
|
need_midi_size = false;
|
||||||
|
}
|
||||||
|
|
||||||
(*i)->reset();
|
(*i)->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -220,7 +220,7 @@ Graph::rechain (boost::shared_ptr<RouteList> routelist)
|
||||||
|
|
||||||
pthread_mutex_lock (&_swap_mutex);
|
pthread_mutex_lock (&_swap_mutex);
|
||||||
int chain = _setup_chain;
|
int chain = _setup_chain;
|
||||||
printf ("============== setup %d\n", chain);
|
DEBUG_TRACE (DEBUG::Graph, string_compose ("============== setup %1\n", chain));
|
||||||
// set all refcounts to 0;
|
// set all refcounts to 0;
|
||||||
|
|
||||||
_init_finished_refcount[chain] = 0;
|
_init_finished_refcount[chain] = 0;
|
||||||
|
|
@ -393,21 +393,21 @@ Graph::dump (int chain)
|
||||||
|
|
||||||
chain = _pending_chain;
|
chain = _pending_chain;
|
||||||
|
|
||||||
printf ("--------------------------------------------Graph dump:\n" );
|
DEBUG_TRACE (DEBUG::Graph, "--------------------------------------------Graph dump:\n");
|
||||||
for (ni=_nodes_rt[chain].begin(); ni!=_nodes_rt[chain].end(); ni++) {
|
for (ni=_nodes_rt[chain].begin(); ni!=_nodes_rt[chain].end(); ni++) {
|
||||||
boost::shared_ptr<Route> rp = boost::dynamic_pointer_cast<Route>( *ni);
|
boost::shared_ptr<Route> rp = boost::dynamic_pointer_cast<Route>( *ni);
|
||||||
printf ("GraphNode: %s refcount: %d\n", rp->name().c_str(), (*ni)->_init_refcount[chain] );
|
DEBUG_TRACE (DEBUG::Graph, string_compose ("GraphNode: %1 refcount: %2\n", rp->name().c_str(), (*ni)->_init_refcount[chain]));
|
||||||
for (ai=(*ni)->_activation_set[chain].begin(); ai!=(*ni)->_activation_set[chain].end(); ai++) {
|
for (ai=(*ni)->_activation_set[chain].begin(); ai!=(*ni)->_activation_set[chain].end(); ai++) {
|
||||||
printf (" triggers: %s\n", boost::dynamic_pointer_cast<Route>(*ai)->name().c_str() );
|
DEBUG_TRACE (DEBUG::Graph, string_compose (" triggers: %1\n", boost::dynamic_pointer_cast<Route>(*ai)->name().c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("------------- trigger list:\n" );
|
DEBUG_TRACE (DEBUG::Graph, "------------- trigger list:\n");
|
||||||
for (ni=_init_trigger_list[chain].begin(); ni!=_init_trigger_list[chain].end(); ni++) {
|
for (ni=_init_trigger_list[chain].begin(); ni!=_init_trigger_list[chain].end(); ni++) {
|
||||||
printf ("GraphNode: %s refcount: %d\n", boost::dynamic_pointer_cast<Route>(*ni)->name().c_str(), (*ni)->_init_refcount[chain] );
|
DEBUG_TRACE (DEBUG::Graph, string_compose ("GraphNode: %1 refcount: %2\n", boost::dynamic_pointer_cast<Route>(*ni)->name().c_str(), (*ni)->_init_refcount[chain]));
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("final activation refcount: %d\n", _init_finished_refcount[chain] );
|
DEBUG_TRACE (DEBUG::Graph, string_compose ("final activation refcount: %1\n", _init_finished_refcount[chain]));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "pbd/malign.h"
|
#include "pbd/malign.h"
|
||||||
|
#include "pbd/compose.h"
|
||||||
|
#include "pbd/debug.h"
|
||||||
|
|
||||||
|
#include "ardour/debug.h"
|
||||||
#include "ardour/midi_buffer.h"
|
#include "ardour/midi_buffer.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
|
using namespace PBD;
|
||||||
|
|
||||||
// FIXME: mirroring for MIDI buffers?
|
// FIXME: mirroring for MIDI buffers?
|
||||||
MidiBuffer::MidiBuffer(size_t capacity)
|
MidiBuffer::MidiBuffer(size_t capacity)
|
||||||
|
|
@ -93,7 +99,10 @@ MidiBuffer::read_from (const Buffer& src, nframes_t nframes, nframes_t dst_offse
|
||||||
const Evoral::MIDIEvent<TimeType> ev(*i, false);
|
const Evoral::MIDIEvent<TimeType> ev(*i, false);
|
||||||
if (ev.time() >= src_offset && ev.time() < (nframes+src_offset)) {
|
if (ev.time() >= src_offset && ev.time() < (nframes+src_offset)) {
|
||||||
push_back (ev);
|
push_back (ev);
|
||||||
}
|
} else {
|
||||||
|
cerr << "MIDI event @ " << ev.time() << " skipped, not within range " << src_offset << " .. "
|
||||||
|
<< (nframes + src_offset) << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_silent = src.silent();
|
_silent = src.silent();
|
||||||
|
|
@ -147,8 +156,22 @@ bool
|
||||||
MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
|
MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
|
||||||
{
|
{
|
||||||
const size_t stamp_size = sizeof(TimeType);
|
const size_t stamp_size = sizeof(TimeType);
|
||||||
/*cerr << "MidiBuffer: pushing event @ " << ev.time()
|
|
||||||
<< " size = " << ev.size() << endl;*/
|
#ifndef NDEBUG
|
||||||
|
DEBUG_STR_DECL(a);
|
||||||
|
DEBUG_STR_APPEND(a, string_compose ("midibuffer %1 push event @ %2 sz %3 ", this, time, size));
|
||||||
|
for (size_t i=0; i < size; ++i) {
|
||||||
|
DEBUG_STR_APPEND(a,hex);
|
||||||
|
DEBUG_STR_APPEND(a,"0x");
|
||||||
|
DEBUG_STR_APPEND(a,(int)data[i]);
|
||||||
|
DEBUG_STR_APPEND(a,' ');
|
||||||
|
}
|
||||||
|
DEBUG_STR_APPEND(a,'\n');
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// cerr << "MidiBuffer: pushing event @ " << time
|
||||||
|
// << " size = " << size << endl;
|
||||||
|
|
||||||
if (_size + stamp_size + size >= _capacity) {
|
if (_size + stamp_size + size >= _capacity) {
|
||||||
cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
|
cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
|
||||||
|
|
@ -302,10 +325,12 @@ MidiBuffer::merge_in_place(const MidiBuffer &other)
|
||||||
++them;
|
++them;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (us != end())
|
if (us != end())
|
||||||
cerr << "us @ " << (*us).time() << endl;
|
cerr << "us @ " << (*us).time() << endl;
|
||||||
if (them != other.end())
|
if (them != other.end())
|
||||||
cerr << "them @ " << (*them).time() << endl;
|
cerr << "them @ " << (*them).time() << endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sz) {
|
if (sz) {
|
||||||
assert(src >= 0);
|
assert(src >= 0);
|
||||||
|
|
@ -342,7 +367,7 @@ MidiBuffer::merge_in_place(const MidiBuffer &other)
|
||||||
size_t test_final_count = 0;
|
size_t test_final_count = 0;
|
||||||
test_time = 0;
|
test_time = 0;
|
||||||
for (iterator i = begin(); i != end(); ++i) {
|
for (iterator i = begin(); i != end(); ++i) {
|
||||||
cerr << "CHECK " << test_final_count << " / " << test_us_count + test_them_count << endl;
|
// cerr << "CHECK " << test_final_count << " / " << test_us_count + test_them_count << endl;
|
||||||
assert(Evoral::midi_event_is_valid((*i).buffer(), (*i).size()));
|
assert(Evoral::midi_event_is_valid((*i).buffer(), (*i).size()));
|
||||||
assert((*i).time() >= test_time);
|
assert((*i).time() >= test_time);
|
||||||
test_time = (*i).time();
|
test_time = (*i).time();
|
||||||
|
|
|
||||||
|
|
@ -163,11 +163,11 @@ MidiPlaylist::read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_t d
|
||||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, "\tBEFORE: new tracker\n");
|
DEBUG_TRACE (DEBUG::MidiPlaylistIO, "\tBEFORE: new tracker\n");
|
||||||
} else {
|
} else {
|
||||||
tracker = t->second;
|
tracker = t->second;
|
||||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\tBEFORE: tracker says there are %1 on notes", tracker->on()));
|
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\tBEFORE: tracker says there are %1 on notes\n", tracker->on()));
|
||||||
}
|
}
|
||||||
|
|
||||||
mr->read_at (dst, start, dur, chan_n, _note_mode, tracker);
|
mr->read_at (dst, start, dur, chan_n, _note_mode, tracker);
|
||||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\tAFTER: tracker says there are %1 on notes", tracker->on()));
|
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("\tAFTER: tracker says there are %1 on notes\n", tracker->on()));
|
||||||
|
|
||||||
if (new_tracker) {
|
if (new_tracker) {
|
||||||
pair<Region*,MidiStateTracker*> newpair;
|
pair<Region*,MidiStateTracker*> newpair;
|
||||||
|
|
|
||||||
|
|
@ -137,8 +137,14 @@ MidiPort::flush_buffers (nframes_t nframes, nframes64_t time, nframes_t offset)
|
||||||
assert(ev.time() < (nframes+offset+_port_offset));
|
assert(ev.time() < (nframes+offset+_port_offset));
|
||||||
|
|
||||||
if (ev.time() >= offset + _port_offset) {
|
if (ev.time() >= offset + _port_offset) {
|
||||||
jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size());
|
if (jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size()) != 0) {
|
||||||
}
|
cerr << "write failed, drop flushed note off on the floor, time " << ev.time() << " > " << offset << " + " << _port_offset
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cerr << "drop flushed note off on the floor, time " << ev.time() << " > " << offset << " + " << _port_offset
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
|
||||||
|
|
||||||
this->full_peek(sizeof(T), (uint8_t*)&ev_time);
|
this->full_peek(sizeof(T), (uint8_t*)&ev_time);
|
||||||
|
|
||||||
if (ev_time > end) {
|
if (ev_time >= end) {
|
||||||
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 past end @ %2\n", ev_time, end));
|
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 past end @ %2\n", ev_time, end));
|
||||||
break;
|
break;
|
||||||
} else if (ev_time < start) {
|
} else if (ev_time < start) {
|
||||||
|
|
@ -70,7 +70,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
|
||||||
if (ev_type == LoopEventType) {
|
if (ev_type == LoopEventType) {
|
||||||
/*ev_time -= start;
|
/*ev_time -= start;
|
||||||
ev_time += offset;*/
|
ev_time += offset;*/
|
||||||
// cerr << "MRB loop boundary @ " << ev_time << endl;
|
cerr << "MRB loop boundary @ " << ev_time << endl;
|
||||||
|
|
||||||
// Return without reading data or writing to buffer (loop events have no data)
|
// Return without reading data or writing to buffer (loop events have no data)
|
||||||
// FIXME: This is not correct, loses events after the loop this cycle
|
// FIXME: This is not correct, loses events after the loop this cycle
|
||||||
|
|
@ -98,7 +98,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
|
||||||
// write the timestamp to address (write_loc - 1)
|
// write the timestamp to address (write_loc - 1)
|
||||||
uint8_t* write_loc = dst.reserve(ev_time, ev_size);
|
uint8_t* write_loc = dst.reserve(ev_time, ev_size);
|
||||||
if (write_loc == NULL) {
|
if (write_loc == NULL) {
|
||||||
// cerr << "MRB: Unable to reserve space in buffer, event skipped";
|
cerr << "MRB: Unable to reserve space in buffer, event skipped";
|
||||||
this->skip (ev_size); // Advance read pointer to next event
|
this->skip (ev_size); // Advance read pointer to next event
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -107,15 +107,16 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
|
||||||
success = read_contents (ev_size, write_loc);
|
success = read_contents (ev_size, write_loc);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, "wrote MidiEvent to Buffer: ");
|
DEBUG_STR_DECL(a);
|
||||||
|
DEBUG_STR_APPEND(a, string_compose ("wrote MidiEvent to Buffer (time=%1, start=%2 offset=%3)", ev_time, start, offset));
|
||||||
for (size_t i=0; i < ev_size; ++i) {
|
for (size_t i=0; i < ev_size; ++i) {
|
||||||
DEBUG_STR_DECL(a);
|
|
||||||
DEBUG_STR_APPEND(a,hex);
|
DEBUG_STR_APPEND(a,hex);
|
||||||
DEBUG_STR_APPEND(a,"0x");
|
DEBUG_STR_APPEND(a,"0x");
|
||||||
DEBUG_STR_APPEND(a,(int)write_loc[i]);
|
DEBUG_STR_APPEND(a,(int)write_loc[i]);
|
||||||
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, DEBUG_STR(a).str());
|
DEBUG_STR_APPEND(a,' ');
|
||||||
}
|
}
|
||||||
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, "\n");
|
DEBUG_STR_APPEND(a,'\n');
|
||||||
|
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, DEBUG_STR(a).str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "ardour/amp.h"
|
#include "ardour/amp.h"
|
||||||
#include "ardour/buffer_set.h"
|
#include "ardour/buffer_set.h"
|
||||||
|
#include "ardour/debug.h"
|
||||||
#include "ardour/delivery.h"
|
#include "ardour/delivery.h"
|
||||||
#include "ardour/io_processor.h"
|
#include "ardour/io_processor.h"
|
||||||
#include "ardour/meter.h"
|
#include "ardour/meter.h"
|
||||||
|
|
@ -412,7 +413,11 @@ MidiTrack::write_out_of_band_data (BufferSet& bufs, sframes_t /*start*/, sframes
|
||||||
{
|
{
|
||||||
// Append immediate events
|
// Append immediate events
|
||||||
MidiBuffer& buf (bufs.get_midi (0));
|
MidiBuffer& buf (bufs.get_midi (0));
|
||||||
_immediate_events.read (buf, 0, 0, nframes - 1); // all stamps = 0
|
if (_immediate_events.read_space()) {
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of immediate events to deliver\n",
|
||||||
|
name(), _immediate_events.read_space()));
|
||||||
|
}
|
||||||
|
_immediate_events.read (buf, 0, 1, nframes-1); // all stamps = 0
|
||||||
|
|
||||||
// MIDI thru: send incoming data "through" output
|
// MIDI thru: send incoming data "through" output
|
||||||
if (_midi_thru && _session.transport_speed() != 0.0f && _input->n_ports().n_midi()) {
|
if (_midi_thru && _session.transport_speed() != 0.0f && _input->n_ports().n_midi()) {
|
||||||
|
|
@ -474,6 +479,7 @@ MidiTrack::set_note_mode (NoteMode m)
|
||||||
void
|
void
|
||||||
MidiTrack::midi_panic()
|
MidiTrack::midi_panic()
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 delivers panic data\n", name()));
|
||||||
for (uint8_t channel = 0; channel <= 0xF; channel++) {
|
for (uint8_t channel = 0; channel <= 0xF; channel++) {
|
||||||
uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
|
uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 };
|
||||||
write_immediate_event(3, ev);
|
write_immediate_event(3, ev);
|
||||||
|
|
|
||||||
|
|
@ -316,3 +316,4 @@ Port::physically_connected () const
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include <glibmm/thread.h>
|
#include <glibmm/thread.h>
|
||||||
|
|
||||||
|
#include <jack/weakjack.h>
|
||||||
#include <jack/jack.h>
|
#include <jack/jack.h>
|
||||||
#include <jack/midiport.h>
|
#include <jack/midiport.h>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue