diff --git a/gtk2_ardour/midi_cue_editor.cc b/gtk2_ardour/midi_cue_editor.cc index 7031991760..cd8d145154 100644 --- a/gtk2_ardour/midi_cue_editor.cc +++ b/gtk2_ardour/midi_cue_editor.cc @@ -17,6 +17,7 @@ */ #include "ardour/midi_region.h" +#include "ardour/midi_track.h" #include "ardour/smf_source.h" #include "canvas/box.h" @@ -34,6 +35,7 @@ #include "ardour_ui.h" #include "editor_cursors.h" #include "editor_drag.h" +#include "gui_thread.h" #include "keyboard.h" #include "midi_cue_background.h" #include "midi_cue_editor.h" @@ -431,6 +433,24 @@ MidiCueEditor::toolbox () return _toolbox; } +void +MidiCueEditor::data_captured () +{ + if (view) { + view->clip_data_recorded(); + } +} + +void +MidiCueEditor::set_box (std::shared_ptr b) +{ + capture_connection.disconnect (); + if (b) { + std::cerr << "Bix set to " << b->order() << std::endl; + b->Captured.connect (capture_connection, invalidator (*this), boost::bind (&MidiCueEditor::data_captured, this), gui_context()); + } +} + void MidiCueEditor::set_region (std::shared_ptr t, uint32_t slot_index, std::shared_ptr r) { diff --git a/gtk2_ardour/midi_cue_editor.h b/gtk2_ardour/midi_cue_editor.h index b09b9d3c88..847abd125f 100644 --- a/gtk2_ardour/midi_cue_editor.h +++ b/gtk2_ardour/midi_cue_editor.h @@ -73,6 +73,7 @@ class MidiCueEditor : public CueEditor int32_t get_grid_music_divisions (Editing::GridType gt, uint32_t event_state) const { return 1; } void set_region (std::shared_ptr, uint32_t slot_index, std::shared_ptr); + void set_box (std::shared_ptr); ArdourCanvas::ScrollGroup* get_hscroll_group () const { return h_scroll_group; } ArdourCanvas::ScrollGroup* get_cursor_scroll_group () const { return cursor_scroll_group; } @@ -203,6 +204,9 @@ class MidiCueEditor : public CueEditor void visual_changer (const VisualChange&); void bindings_changed (); + + void data_captured (); + PBD::ScopedConnection capture_connection; }; diff --git a/gtk2_ardour/midi_view.cc b/gtk2_ardour/midi_view.cc index d37ee1bad1..59cf7936e1 100644 --- a/gtk2_ardour/midi_view.cc +++ b/gtk2_ardour/midi_view.cc @@ -4174,6 +4174,68 @@ MidiView::set_step_edit_cursor_width (Temporal::Beats beats) } } +void +MidiView::clip_data_recorded () +{ + std::shared_ptr tb = _midi_track->triggerbox(); + assert (tb); + + std::shared_ptr buf = tb->get_gui_feed_buffer(); + + for (MidiBuffer::iterator i = buf->begin(); i != buf->end(); ++i) { + const Evoral::Event& ev = *i; + + if (ev.is_channel_event()) { + if (get_channel_mode() == FilterChannels) { + if (((uint16_t(1) << ev.channel()) & get_selected_channels()) == 0) { + continue; + } + } + } + + /* ev.time() is in MidiBuffer::TimeType i.e. samples + + we want to convert to beats relative to source start. + */ + + Temporal::Beats const time_beats = timepos_t (ev.time()).beats(); + + if (ev.type() == MIDI_CMD_NOTE_ON) { + + std::shared_ptr note (new NoteType (ev.channel(), time_beats, std::numeric_limits::max() - time_beats, ev.note(), ev.velocity())); + + assert (note->end_time() == std::numeric_limits::max()); + + NoteBase* nb = add_note (note, true); + nb->item()->set_fill_color (UIConfiguration::instance().color ("recording note")); + nb->item()->set_outline_color (UIConfiguration::instance().color ("recording note")); + + /* fix up our note range */ + if (ev.note() < _midi_context.lowest_note()) { + set_note_range (ev.note(), _midi_context.highest_note()); + } else if (ev.note() > _midi_context.highest_note()) { + set_note_range (_midi_context.lowest_note(), ev.note()); + } + + } else if (ev.type() == MIDI_CMD_NOTE_OFF) { + + // XXX WAS resolve_note (ev.note (), time_beats); + uint8_t note = ev.note (); + Temporal::Beats end_time = time_beats; + + if (_active_notes && _active_notes[note]) { + /* Set note length so update_note() works. Note this is a local note + for recording, not from a model, so we can safely mess with it. */ + _active_notes[note]->note()->set_length (end_time - _active_notes[note]->note()->time()); + + _active_notes[note]->set_x1 (_editing_context.sample_to_pixel (timepos_t (ev.time ()).samples())); + _active_notes[note]->set_outline_all (); + _active_notes[note] = 0; + } + } + } +} + /** Called when a diskstream on our track has received some data. Update the view, if applicable. * @param w Source that the data will end up in. */ diff --git a/gtk2_ardour/midi_view.h b/gtk2_ardour/midi_view.h index 689a4beb9d..5e8abbf65b 100644 --- a/gtk2_ardour/midi_view.h +++ b/gtk2_ardour/midi_view.h @@ -339,6 +339,8 @@ class MidiView : public virtual sigc::trackable, public LineMerger EditingContext& editing_context() const { return _editing_context; } MidiViewBackground& midi_context() const { return _midi_context; } + void clip_data_recorded (); + virtual void select_self (bool add) {} virtual void unselect_self () {} void select_self () { select_self (false); } diff --git a/gtk2_ardour/trigger_page.cc b/gtk2_ardour/trigger_page.cc index 6890c49775..167df2be2c 100644 --- a/gtk2_ardour/trigger_page.cc +++ b/gtk2_ardour/trigger_page.cc @@ -396,23 +396,33 @@ TriggerPage::selection_changed () _parameter_box.hide (); + std::cerr << "here, st = " << selection.triggers.size() << std::endl; + if (!selection.triggers.empty ()) { TriggerSelection ts = selection.triggers; TriggerEntry* entry = *ts.begin (); TriggerReference ref = entry->trigger_reference (); TriggerPtr trigger = entry->trigger (); + std::shared_ptr box = ref.box(); _slot_prop_box.set_slot (ref); _slot_prop_box.show (); - if (trigger->the_region ()) { - if (trigger->the_region ()->data_type () == DataType::AUDIO) { + + if (box->data_type () == DataType::AUDIO) { + if (trigger->the_region()) { _audio_trig_box.set_trigger (ref); _audio_trig_box.show (); - } else { - _midi_trig_box.set_trigger (ref); - _midi_trig_box.show (); + } + } else { + _midi_trig_box.set_trigger (ref); + _midi_trig_box.show (); + + _midi_editor->set_box (ref.box()); + + if (trigger->the_region()) { std::shared_ptr mr = std::dynamic_pointer_cast (trigger->the_region()); + if (mr) { std::shared_ptr mt = std::dynamic_pointer_cast (entry->strip().stripable()); _midi_editor->set_region (mt, ref.slot(), mr);