X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_track.cc;h=c5433347a0630738547be6afbc20ab7a8f48b6eb;hb=b52bf1a42c71ae943eaff2bca4c309618c173ab3;hp=e9efb2fc17d992f688534e8149715594ef51fd21;hpb=e9a8ccc7e2826d8fe91eff34ee8a0683a7f7aac6;p=ardour.git diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index e9efb2fc17..c5433347a0 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -54,7 +54,7 @@ #include "ardour/session_playlists.h" #include "ardour/utils.h" -#include "i18n.h" +#include "pbd/i18n.h" namespace ARDOUR { class InterThreadInfo; @@ -69,12 +69,13 @@ using namespace PBD; MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode) : Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI) - , _immediate_events(1024) // FIXME: size? + , _immediate_events(6096) // FIXME: size? , _step_edit_ring_buffer(64) // FIXME: size? , _note_mode(Sustained) , _step_editing (false) , _input_active (true) { + _session.SessionLoaded.connect_same_thread (*this, boost::bind (&MidiTrack::restore_controls, this)); } MidiTrack::~MidiTrack () @@ -266,6 +267,14 @@ MidiTrack::state(bool full_state) root.add_property ("step-editing", (_step_editing ? "yes" : "no")); root.add_property ("input-active", (_input_active ? "yes" : "no")); + for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) { + if (boost::dynamic_pointer_cast(c->second)) { + boost::shared_ptr ac = boost::dynamic_pointer_cast (c->second); + assert (ac); + root.add_child_nocopy (ac->get_state ()); + } + } + return root; } @@ -334,12 +343,24 @@ MidiTrack::set_state_part_two () return; } +void +MidiTrack::restore_controls () +{ + // TODO order events (CC before PGM to set banks) + for (Controls::const_iterator c = _controls.begin(); c != _controls.end(); ++c) { + boost::shared_ptr mctrl = boost::dynamic_pointer_cast(c->second); + if (mctrl) { + mctrl->restore_value(); + } + } +} + void MidiTrack::update_controls(const BufferSet& bufs) { const MidiBuffer& buf = bufs.get_midi(0); for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) { - const Evoral::MIDIEvent& ev = *e; + const Evoral::Event& ev = *e; const Evoral::Parameter param = midi_parameter(ev.buffer(), ev.size()); const boost::shared_ptr control = this->control(param); if (control) { @@ -444,12 +465,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!diskstream->record_enabled() && !_session.transport_stopped())); - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - boost::shared_ptr d = boost::dynamic_pointer_cast (*i); - if (d) { - d->flush_buffers (nframes); - } - } + flush_processor_buffers_locked (nframes); need_butler = diskstream->commit (playback_distance); @@ -554,7 +570,7 @@ MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes) for (MidiBuffer::const_iterator e = mb->begin(); e != mb->end(); ++e) { - const Evoral::MIDIEvent ev(*e, false); + const Evoral::Event ev(*e, false); /* note on, since for step edit, note length is determined elsewhere @@ -562,7 +578,7 @@ MidiTrack::push_midi_input_to_step_edit_ringbuffer (framecnt_t nframes) if (ev.is_note_on()) { /* we don't care about the time for this purpose */ - _step_edit_ring_buffer.write (0, ev.type(), ev.size(), ev.buffer()); + _step_edit_ring_buffer.write (0, ev.event_type(), ev.size(), ev.buffer()); } } } @@ -694,8 +710,7 @@ MidiTrack::write_immediate_event(size_t size, const uint8_t* buf) cerr << "WARNING: Ignoring illegal immediate MIDI event" << endl; return false; } - const uint32_t type = midi_parameter_type(buf[0]); - return (_immediate_events.write (0, type, size, buf) == size); + return (_immediate_events.write (0, Evoral::MIDI_EVENT, size, buf) == size); } void @@ -706,6 +721,7 @@ MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState st case MidiPgmChangeAutomation: case MidiPitchBenderAutomation: case MidiChannelPressureAutomation: + case MidiNotePressureAutomation: case MidiSystemExclusiveAutomation: /* The track control for MIDI parameters is for immediate events to act as a control surface, write/touch for them is not currently @@ -716,6 +732,12 @@ MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState st } } +void +MidiTrack::MidiControl::restore_value () +{ + actually_set_value (get_value(), Controllable::NoGroup); +} + void MidiTrack::MidiControl::actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override) { @@ -762,6 +784,12 @@ MidiTrack::MidiControl::actually_set_value (double val, PBD::Controllable::Group ev[1] = int(val); break; + case MidiNotePressureAutomation: + ev[0] += MIDI_CMD_NOTE_PRESSURE; + ev[1] = parameter.id(); + ev[2] = int(val); + break; + case MidiPitchBenderAutomation: ev[0] += MIDI_CMD_BENDER; ev[1] = 0x7F & int(val);