MIDI tracks: split immediate events into ardour- and user-generated
This now allows the already-apparently possible recording of user-input from the kbd in the MIDI track header to actually be successful
This commit is contained in:
parent
a2656d6612
commit
d44c9787b6
@ -75,6 +75,7 @@ public:
|
|||||||
|
|
||||||
void midi_panic(void);
|
void midi_panic(void);
|
||||||
bool write_immediate_event (Evoral::EventType event_type, size_t size, const uint8_t* buf);
|
bool write_immediate_event (Evoral::EventType event_type, size_t size, const uint8_t* buf);
|
||||||
|
bool write_user_immediate_event (Evoral::EventType event_type, size_t size, const uint8_t* buf);
|
||||||
|
|
||||||
std::shared_ptr<VelocityControl> velocity_control() const { return _velocity_control; }
|
std::shared_ptr<VelocityControl> velocity_control() const { return _velocity_control; }
|
||||||
|
|
||||||
@ -135,7 +136,9 @@ public:
|
|||||||
MonitorState get_input_monitoring_state (bool recording, bool talkback) const;
|
MonitorState get_input_monitoring_state (bool recording, bool talkback) const;
|
||||||
|
|
||||||
MidiBuffer const& immediate_event_buffer () const { return _immediate_event_buffer; }
|
MidiBuffer const& immediate_event_buffer () const { return _immediate_event_buffer; }
|
||||||
|
MidiBuffer const& user_immediate_event_buffer () const { return _user_immediate_event_buffer; }
|
||||||
MidiRingBuffer<samplepos_t>& immediate_events () { return _immediate_events; }
|
MidiRingBuffer<samplepos_t>& immediate_events () { return _immediate_events; }
|
||||||
|
MidiRingBuffer<samplepos_t>& user_immediate_events () { return _user_immediate_events; }
|
||||||
|
|
||||||
void set_input_active (bool);
|
void set_input_active (bool);
|
||||||
bool input_active () const;
|
bool input_active () const;
|
||||||
@ -160,7 +163,9 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
MidiRingBuffer<samplepos_t> _immediate_events;
|
MidiRingBuffer<samplepos_t> _immediate_events;
|
||||||
|
MidiRingBuffer<samplepos_t> _user_immediate_events;
|
||||||
MidiBuffer _immediate_event_buffer;
|
MidiBuffer _immediate_event_buffer;
|
||||||
|
MidiBuffer _user_immediate_event_buffer;
|
||||||
MidiRingBuffer<samplepos_t> _step_edit_ring_buffer;
|
MidiRingBuffer<samplepos_t> _step_edit_ring_buffer;
|
||||||
NoteMode _note_mode;
|
NoteMode _note_mode;
|
||||||
bool _step_editing;
|
bool _step_editing;
|
||||||
|
@ -572,8 +572,8 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||||||
/* AUDIO */
|
/* AUDIO */
|
||||||
|
|
||||||
const size_t n_buffers = bufs.count().n_audio();
|
const size_t n_buffers = bufs.count().n_audio();
|
||||||
|
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
|
|
||||||
for (auto const& chaninfo : *c) {
|
for (auto const& chaninfo : *c) {
|
||||||
AudioBuffer& buf (bufs.get_audio (n%n_buffers));
|
AudioBuffer& buf (bufs.get_audio (n%n_buffers));
|
||||||
++n;
|
++n;
|
||||||
@ -611,6 +611,8 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||||||
|
|
||||||
/* MIDI */
|
/* MIDI */
|
||||||
|
|
||||||
|
uint32_t cnt = 0;
|
||||||
|
|
||||||
if (_midi_buf) {
|
if (_midi_buf) {
|
||||||
|
|
||||||
// Pump entire port buffer into the ring buffer (TODO: split cycles?)
|
// Pump entire port buffer into the ring buffer (TODO: split cycles?)
|
||||||
@ -658,7 +660,10 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||||||
|
|
||||||
bool skip_event = false;
|
bool skip_event = false;
|
||||||
if (mt) {
|
if (mt) {
|
||||||
/* skip injected immediate/out-of-band events */
|
/* skip injected immediate/out-of-band
|
||||||
|
* events, but allow those from
|
||||||
|
* user_immediate_event_buffer
|
||||||
|
*/
|
||||||
MidiBuffer const& ieb (mt->immediate_event_buffer());
|
MidiBuffer const& ieb (mt->immediate_event_buffer());
|
||||||
for (MidiBuffer::const_iterator j = ieb.begin(); j != ieb.end(); ++j) {
|
for (MidiBuffer::const_iterator j = ieb.begin(); j != ieb.end(); ++j) {
|
||||||
if (*j == ev) {
|
if (*j == ev) {
|
||||||
@ -672,6 +677,7 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||||||
|
|
||||||
if (!filter || !filter->filter(ev.buffer(), ev.size())) {
|
if (!filter || !filter->filter(ev.buffer(), ev.size())) {
|
||||||
_midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
|
_midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
|
||||||
|
cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,6 +703,9 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnt) {
|
||||||
DataRecorded (_midi_write_source); /* EMIT SIGNAL */
|
DataRecorded (_midi_write_source); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,9 @@ using namespace PBD;
|
|||||||
MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
|
MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
|
||||||
: Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI)
|
: Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI)
|
||||||
, _immediate_events(6096) // FIXME: size?
|
, _immediate_events(6096) // FIXME: size?
|
||||||
|
, _user_immediate_events(2048) // FIXME: size?
|
||||||
, _immediate_event_buffer(6096)
|
, _immediate_event_buffer(6096)
|
||||||
|
, _user_immediate_event_buffer(2048)
|
||||||
, _step_edit_ring_buffer(64) // FIXME: size?
|
, _step_edit_ring_buffer(64) // FIXME: size?
|
||||||
, _note_mode (Sustained)
|
, _note_mode (Sustained)
|
||||||
, _step_editing (false)
|
, _step_editing (false)
|
||||||
@ -502,7 +504,7 @@ MidiTrack::snapshot_out_of_band_data (samplecnt_t nframes)
|
|||||||
{
|
{
|
||||||
_immediate_event_buffer.clear ();
|
_immediate_event_buffer.clear ();
|
||||||
if (0 == _immediate_events.read_space()) {
|
if (0 == _immediate_events.read_space()) {
|
||||||
return;
|
goto user;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (nframes > 0);
|
assert (nframes > 0);
|
||||||
@ -519,6 +521,28 @@ MidiTrack::snapshot_out_of_band_data (samplecnt_t nframes)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
_immediate_events.read (_immediate_event_buffer, 0, 1, nframes - 1, true);
|
_immediate_events.read (_immediate_event_buffer, 0, 1, nframes - 1, true);
|
||||||
|
|
||||||
|
user:
|
||||||
|
_user_immediate_event_buffer.clear ();
|
||||||
|
if (0 == _user_immediate_events.read_space()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (nframes > 0);
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("%1 has %2 of user immediate events to deliver\n", name(), _user_immediate_events.read_space()));
|
||||||
|
|
||||||
|
/* write as many of the user immediate events as we can, but give "true" as
|
||||||
|
* the last argument ("stop on overflow in destination") so that we'll
|
||||||
|
* ship the rest out next time.
|
||||||
|
*
|
||||||
|
* the (nframes-1) argument puts all these events at the last
|
||||||
|
* possible position of the output buffer, so that we do not
|
||||||
|
* violate monotonicity when writing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
_user_immediate_events.read (_user_immediate_event_buffer, 0, 1, nframes - 1, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -526,6 +550,7 @@ MidiTrack::write_out_of_band_data (BufferSet& bufs, samplecnt_t nframes) const
|
|||||||
{
|
{
|
||||||
MidiBuffer& buf (bufs.get_midi (0));
|
MidiBuffer& buf (bufs.get_midi (0));
|
||||||
buf.merge_from (_immediate_event_buffer, nframes);
|
buf.merge_from (_immediate_event_buffer, nframes);
|
||||||
|
buf.merge_from (_user_immediate_event_buffer, nframes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -650,6 +675,16 @@ MidiTrack::write_immediate_event(Evoral::EventType event_type, size_t size, cons
|
|||||||
return (_immediate_events.write (0, event_type, size, buf) == size);
|
return (_immediate_events.write (0, event_type, size, buf) == size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MidiTrack::write_user_immediate_event(Evoral::EventType event_type, size_t size, const uint8_t* buf)
|
||||||
|
{
|
||||||
|
if (!Evoral::midi_event_is_valid(buf, size)) {
|
||||||
|
cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (_user_immediate_events.write (0, event_type, size, buf) == size);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
|
MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
|
||||||
{
|
{
|
||||||
@ -952,6 +987,7 @@ MidiTrack::realtime_handle_transport_stopped ()
|
|||||||
{
|
{
|
||||||
Route::realtime_handle_transport_stopped ();
|
Route::realtime_handle_transport_stopped ();
|
||||||
_disk_reader->resolve_tracker (_immediate_events, 0);
|
_disk_reader->resolve_tracker (_immediate_events, 0);
|
||||||
|
_disk_reader->resolve_tracker (_user_immediate_events, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user