X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_track.cc;h=a4c14e4f625fab397ca83e03543f626e5439ddb5;hb=1203d796de35cd7d6cdee4738e47f2a7c1d797c6;hp=7c1b3a9399cc99a0b0be44a54b20a3ddafef7a79;hpb=653ae4acd639fef149314fe6f8c7a0d862afae40;p=ardour.git diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 7c1b3a9399..a4c14e4f62 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; @@ -67,14 +67,15 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode) - : Track (sess, name, flag, mode, DataType::MIDI) - , _immediate_events(1024) // FIXME: size? +MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode) + : Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI) + , _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 () @@ -138,11 +139,13 @@ MidiTrack::set_diskstream (boost::shared_ptr ds) mds->reset_tracker (); _diskstream->set_track (this); +#ifdef XXX_OLD_DESTRUCTIVE_API_XXX if (Profile->get_trx()) { _diskstream->set_destructive (false); } else { _diskstream->set_destructive (_mode == Destructive); } +#endif _diskstream->set_record_enabled (false); _diskstream_data_recorded_connection.disconnect (); @@ -266,6 +269,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 +345,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) { @@ -396,16 +419,6 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame return dret; } - if (_mute_control->list() && _mute_control->automation_playback()) { - bool valid = false; - const float mute = _mute_control->list()->rt_safe_eval(transport_frame, valid); - if (mute >= 0.5 && !muted()) { - _mute_control->set_value_unchecked(1.0); // mute - } else if (mute < 0.5 && muted()) { - _mute_control->set_value_unchecked(0.0); // unmute - } - } - BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); fill_buffers_with_input (bufs, _input, nframes); @@ -414,7 +427,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame _capture_filter.filter (bufs); if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) { - _meter->run (bufs, start_frame, end_frame, nframes, true); + _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true); } @@ -454,12 +467,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); @@ -564,7 +572,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 @@ -572,7 +580,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()); } } } @@ -704,8 +712,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 @@ -716,6 +723,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 @@ -726,6 +734,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) { @@ -772,6 +786,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); @@ -920,7 +940,7 @@ MidiTrack::act_on_mute () return; } - if (muted() || _mute_master->muted_by_others_at(MuteMaster::AllPoints)) { + if (muted() || _mute_master->muted_by_others_soloing_at (MuteMaster::AllPoints)) { /* only send messages for channels we are using */ uint16_t mask = _playback_filter.get_channel_mask(); @@ -947,7 +967,7 @@ void MidiTrack::monitoring_changed (bool self, Controllable::GroupControlDisposition gcd) { Track::monitoring_changed (self, gcd); - + /* monitoring state changed, so flush out any on notes at the * port level. */