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);
|
||||
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; }
|
||||
|
||||
@ -135,7 +136,9 @@ public:
|
||||
MonitorState get_input_monitoring_state (bool recording, bool talkback) const;
|
||||
|
||||
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>& user_immediate_events () { return _user_immediate_events; }
|
||||
|
||||
void set_input_active (bool);
|
||||
bool input_active () const;
|
||||
@ -160,7 +163,9 @@ protected:
|
||||
|
||||
private:
|
||||
MidiRingBuffer<samplepos_t> _immediate_events;
|
||||
MidiRingBuffer<samplepos_t> _user_immediate_events;
|
||||
MidiBuffer _immediate_event_buffer;
|
||||
MidiBuffer _user_immediate_event_buffer;
|
||||
MidiRingBuffer<samplepos_t> _step_edit_ring_buffer;
|
||||
NoteMode _note_mode;
|
||||
bool _step_editing;
|
||||
|
@ -572,8 +572,8 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
||||
/* AUDIO */
|
||||
|
||||
const size_t n_buffers = bufs.count().n_audio();
|
||||
|
||||
uint32_t n = 0;
|
||||
|
||||
for (auto const& chaninfo : *c) {
|
||||
AudioBuffer& buf (bufs.get_audio (n%n_buffers));
|
||||
++n;
|
||||
@ -611,6 +611,8 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
||||
|
||||
/* MIDI */
|
||||
|
||||
uint32_t cnt = 0;
|
||||
|
||||
if (_midi_buf) {
|
||||
|
||||
// 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;
|
||||
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());
|
||||
for (MidiBuffer::const_iterator j = ieb.begin(); j != ieb.end(); ++j) {
|
||||
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())) {
|
||||
_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 */
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,9 @@ using namespace PBD;
|
||||
MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
|
||||
: Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI)
|
||||
, _immediate_events(6096) // FIXME: size?
|
||||
, _user_immediate_events(2048) // FIXME: size?
|
||||
, _immediate_event_buffer(6096)
|
||||
, _user_immediate_event_buffer(2048)
|
||||
, _step_edit_ring_buffer(64) // FIXME: size?
|
||||
, _note_mode (Sustained)
|
||||
, _step_editing (false)
|
||||
@ -502,7 +504,7 @@ MidiTrack::snapshot_out_of_band_data (samplecnt_t nframes)
|
||||
{
|
||||
_immediate_event_buffer.clear ();
|
||||
if (0 == _immediate_events.read_space()) {
|
||||
return;
|
||||
goto user;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
@ -526,6 +550,7 @@ MidiTrack::write_out_of_band_data (BufferSet& bufs, samplecnt_t nframes) const
|
||||
{
|
||||
MidiBuffer& buf (bufs.get_midi (0));
|
||||
buf.merge_from (_immediate_event_buffer, nframes);
|
||||
buf.merge_from (_user_immediate_event_buffer, nframes);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState state)
|
||||
{
|
||||
@ -952,6 +987,7 @@ MidiTrack::realtime_handle_transport_stopped ()
|
||||
{
|
||||
Route::realtime_handle_transport_stopped ();
|
||||
_disk_reader->resolve_tracker (_immediate_events, 0);
|
||||
_disk_reader->resolve_tracker (_user_immediate_events, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user