13
0

preparations for clip data display (MIDI) while recording (GUI edition)

This commit is contained in:
Paul Davis 2024-10-10 22:18:17 -06:00
parent 7c944687c9
commit 35f16f1bb6
5 changed files with 103 additions and 5 deletions

View File

@ -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<ARDOUR::TriggerBox> 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<ARDOUR::MidiTrack> t, uint32_t slot_index, std::shared_ptr<ARDOUR::MidiRegion> r)
{

View File

@ -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<ARDOUR::MidiTrack>, uint32_t slot_index, std::shared_ptr<ARDOUR::MidiRegion>);
void set_box (std::shared_ptr<ARDOUR::TriggerBox>);
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;
};

View File

@ -4174,6 +4174,68 @@ MidiView::set_step_edit_cursor_width (Temporal::Beats beats)
}
}
void
MidiView::clip_data_recorded ()
{
std::shared_ptr<TriggerBox> tb = _midi_track->triggerbox();
assert (tb);
std::shared_ptr<MidiBuffer> buf = tb->get_gui_feed_buffer();
for (MidiBuffer::iterator i = buf->begin(); i != buf->end(); ++i) {
const Evoral::Event<MidiBuffer::TimeType>& 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<NoteType> note (new NoteType (ev.channel(), time_beats, std::numeric_limits<Temporal::Beats>::max() - time_beats, ev.note(), ev.velocity()));
assert (note->end_time() == std::numeric_limits<Temporal::Beats>::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.
*/

View File

@ -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); }

View File

@ -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<TriggerBox> 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<MidiRegion> mr = std::dynamic_pointer_cast<MidiRegion> (trigger->the_region());
if (mr) {
std::shared_ptr<MidiTrack> mt = std::dynamic_pointer_cast<MidiTrack> (entry->strip().stripable());
_midi_editor->set_region (mt, ref.slot(), mr);