X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmidi_streamview.cc;h=b3d976ae2e907a7a2c47dc4d785bf42135684bcc;hb=4e4cb140a0713cabec624f13e86eaf9b375ab6c5;hp=5f939ab58306a5a3c15db4521c9ffe5f52790cab;hpb=d752986314eb37151983393c1d62efefe503e47c;p=ardour.git diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc index 5f939ab583..b3d976ae2e 100644 --- a/gtk2_ardour/midi_streamview.cc +++ b/gtk2_ardour/midi_streamview.cc @@ -18,6 +18,7 @@ #include #include +#include #include @@ -28,8 +29,8 @@ #include #include #include -//#include -#include +#include +#include #include "midi_streamview.h" #include "region_view.h" @@ -44,7 +45,9 @@ #include "gui_thread.h" #include "utils.h" #include "color.h" +#include "simplerect.h" +using namespace std; using namespace ARDOUR; using namespace PBD; using namespace Editing; @@ -53,12 +56,12 @@ MidiStreamView::MidiStreamView (MidiTimeAxisView& tv) : StreamView (tv) { if (tv.is_track()) - stream_base_color = color_map[cMidiTrackBase]; + stream_base_color = ARDOUR_UI::config()->canvasvar_MidiTrackBase.get(); else - stream_base_color = color_map[cMidiBusBase]; + stream_base_color = ARDOUR_UI::config()->canvasvar_MidiBusBase.get(); canvas_rect->property_fill_color_rgba() = stream_base_color; - canvas_rect->property_outline_color_rgba() = color_map[cAudioTrackOutline]; + canvas_rect->property_outline_color_rgba() = RGBA_BLACK; //use_rec_regions = tv.editor.show_waveforms_recording (); use_rec_regions = true; @@ -69,34 +72,32 @@ MidiStreamView::~MidiStreamView () } -void -MidiStreamView::add_region_view_internal (Region *r, bool wait_for_waves) +RegionView* +MidiStreamView::add_region_view_internal (boost::shared_ptr r, bool wait_for_waves) { - ENSURE_GUI_THREAD (bind (mem_fun (*this, &MidiStreamView::add_region_view), r)); - - MidiRegion* region = dynamic_cast (r); + boost::shared_ptr region = boost::dynamic_pointer_cast (r); if (region == 0) { - return; + return NULL; } MidiRegionView *region_view; list::iterator i; for (i = region_views.begin(); i != region_views.end(); ++i) { - if (&(*i)->region() == r) { + if ((*i)->region() == r) { /* great. we already have a MidiRegionView for this Region. use it again. */ (*i)->set_valid (true); - return; + return NULL; } } // can't we all just get along? assert(_trackview.midi_track()->mode() != Destructive); - region_view = new MidiRegionView (canvas_group, _trackview, *region, + region_view = new MidiRegionView (canvas_group, _trackview, region, _samples_per_unit, region_color); region_view->init (region_color, wait_for_waves); @@ -107,11 +108,18 @@ MidiStreamView::add_region_view_internal (Region *r, bool wait_for_waves) // FIXME //region_view->set_waveform_visible(_trackview.editor.show_waveforms()); - /* catch regionview going away */ + /* display events */ + region_view->begin_write(); + for (size_t i=0; i < region->midi_source(0)->model()->n_events(); ++i) + region_view->add_event(region->midi_source(0)->model()->event_at(i)); + region_view->end_write(); - region->GoingAway.connect (mem_fun (*this, &MidiStreamView::remove_region_view)); + /* catch regionview going away */ + region->GoingAway.connect (bind (mem_fun (*this, &MidiStreamView::remove_region_view), region)); RegionViewAdded (region_view); + + return region_view; } // FIXME: code duplication with AudioStreamVIew @@ -142,7 +150,9 @@ MidiStreamView::redisplay_diskstream () /* now fix layering */ - playlist_modified (); + for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) { + region_layered (*i); + } } @@ -153,8 +163,6 @@ MidiStreamView::setup_rec_box () if (_trackview.session().transport_rolling()) { - cerr << "\tSHOW: rolling\n"; - if (!rec_active && _trackview.session().record_status() == Session::Recording && _trackview.get_diskstream()->record_enabled()) { @@ -164,37 +172,43 @@ MidiStreamView::setup_rec_box () /* add a new region, but don't bother if they set use_rec_regions mid-record */ MidiRegion::SourceList sources; + + for (list::iterator prc = rec_data_ready_connections.begin(); prc != rec_data_ready_connections.end(); ++prc) { + (*prc).disconnect(); + } + rec_data_ready_connections.clear(); // FIXME - MidiDiskstream* mds = dynamic_cast(_trackview.get_diskstream()); + boost::shared_ptr mds = boost::dynamic_pointer_cast(_trackview.get_diskstream()); assert(mds); - sources.push_back((Source*)mds->write_source()); + sources.push_back(mds->write_source()); - // FIXME - rec_data_ready_connections.push_back (mds->write_source()->ViewDataRangeReady.connect (bind (mem_fun (*this, &MidiStreamView::rec_data_range_ready), mds->write_source()))); + rec_data_ready_connections.push_back (mds->write_source()->ViewDataRangeReady.connect (bind (mem_fun (*this, &MidiStreamView::rec_data_range_ready), boost::weak_ptr(mds->write_source())))); // handle multi jack_nframes_t start = 0; if (rec_regions.size() > 0) { - start = rec_regions.back()->start() + _trackview.get_diskstream()->get_captured_frames(rec_regions.size()-1); + start = rec_regions.back().first->start() + _trackview.get_diskstream()->get_captured_frames(rec_regions.size()-1); } - MidiRegion * region = new MidiRegion(sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false); + boost::shared_ptr region (boost::dynamic_pointer_cast + (RegionFactory::create (sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false))); + assert(region); region->set_position (_trackview.session().transport_frame(), this); - rec_regions.push_back (region); - /* catch it if it goes away */ - region->GoingAway.connect (mem_fun (*this, &MidiStreamView::remove_rec_region)); + rec_regions.push_back (make_pair(region, (RegionView*)0)); + + // rec regions are destroyed in setup_rec_box /* we add the region later */ } /* start a new rec box */ - MidiTrack* mt = _trackview.midi_track(); /* we know what it is already */ - MidiDiskstream& ds = mt->midi_diskstream(); - jack_nframes_t frame_pos = ds.current_capture_start (); + boost::shared_ptr mt = _trackview.midi_track(); /* we know what it is already */ + boost::shared_ptr ds = mt->midi_diskstream(); + jack_nframes_t frame_pos = ds->current_capture_start (); gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos); gdouble xend; uint32_t fill_color; @@ -202,15 +216,16 @@ MidiStreamView::setup_rec_box () assert(_trackview.midi_track()->mode() == Normal); xend = xstart; - fill_color = color_map[cRecordingRectFill]; + fill_color = ARDOUR_UI::config()->canvasvar_RecordingRect.get(); ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group); rec_rect->property_x1() = xstart; rec_rect->property_y1() = 1.0; rec_rect->property_x2() = xend; rec_rect->property_y2() = (double) _trackview.height - 1; - rec_rect->property_outline_color_rgba() = color_map[cRecordingRectOutline]; + rec_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_RecordingRect.get(); rec_rect->property_fill_color_rgba() = fill_color; + rec_rect->lower_to_bottom(); RecBoxInfo recbox; recbox.rectangle = rec_rect; @@ -224,16 +239,10 @@ MidiStreamView::setup_rec_box () rec_updating = true; rec_active = true; - // Show, damn you! - rec_rect->show(); - rec_rect->raise_to_top(); - } else if (rec_active && (_trackview.session().record_status() != Session::Recording || !_trackview.get_diskstream()->record_enabled())) { - cerr << "NO SHOW 1\n"; - screen_update_connection.disconnect(); rec_active = false; rec_updating = false; @@ -242,7 +251,7 @@ MidiStreamView::setup_rec_box () } else { - cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl; + // cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl; if (!rec_rects.empty() || !rec_regions.empty()) { @@ -256,18 +265,16 @@ MidiStreamView::setup_rec_box () rec_updating = false; rec_active = false; - last_rec_data_frame = 0; /* remove temp regions */ - for (list::iterator iter=rec_regions.begin(); iter != rec_regions.end(); ) - { - list::iterator tmp; - + + for (list,RegionView*> >::iterator iter = rec_regions.begin(); iter != rec_regions.end();) { + list,RegionView*> >::iterator tmp; + tmp = iter; ++tmp; - /* this will trigger the remove_region_view */ - delete *iter; + (*iter).first->drop_references (); iter = tmp; } @@ -275,7 +282,6 @@ MidiStreamView::setup_rec_box () rec_regions.clear(); // cerr << "\tclear " << rec_rects.size() << " rec rects\n"; - /* transport stopped, clear boxes */ for (vector::iterator iter=rec_rects.begin(); iter != rec_rects.end(); ++iter) { @@ -290,16 +296,17 @@ MidiStreamView::setup_rec_box () } void -MidiStreamView::update_rec_regions () +MidiStreamView::update_rec_regions (boost::shared_ptr data, nframes_t start, nframes_t dur) { - if (use_rec_regions) { + ENSURE_GUI_THREAD (bind (mem_fun (*this, &MidiStreamView::update_rec_regions), data, start, dur)); + if (use_rec_regions) { uint32_t n = 0; - for (list::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) { + for (list,RegionView*> >::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) { - list::iterator tmp; + list,RegionView*> >::iterator tmp; tmp = iter; ++tmp; @@ -310,17 +317,21 @@ MidiStreamView::update_rec_regions () continue; } - // FIXME - MidiRegion * region = dynamic_cast(*iter); - assert(region); + boost::shared_ptr region = boost::dynamic_pointer_cast(iter->first); + if (!region) { + continue; + } - jack_nframes_t origlen = region->length(); + nframes_t origlen = region->length(); + + //cerr << "MIDI URR: " << start << " * " << dur + // << " (origlen " << origlen << ")" << endl; - if (region == rec_regions.back() && rec_active) { + if (region == rec_regions.back().first && rec_active) { - if (last_rec_data_frame > region->start()) { + if (start >= region->start()) { - jack_nframes_t nlen = last_rec_data_frame - region->start(); + nframes_t nlen = start + dur - region->start(); if (nlen != region->length()) { @@ -331,23 +342,33 @@ MidiStreamView::update_rec_regions () if (origlen == 1) { /* our special initial length */ - add_region_view_internal (region, false); + iter->second = add_region_view_internal (region, false); + ((MidiRegionView*)iter->second)->begin_write(); } /* also update rect */ ArdourCanvas::SimpleRect * rect = rec_rects[n].rectangle; gdouble xend = _trackview.editor.frame_to_pixel (region->position() + region->length()); rect->property_x2() = xend; + + /* draw events */ + MidiRegionView* mrv = (MidiRegionView*)iter->second; + for (size_t i = 0; i < data->size(); ++i) { + const MidiEvent& ev = (*data.get())[i]; + mrv->add_event(ev); + mrv->extend_active_notes(); + } + } } } else { - jack_nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n); + nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n); if (nlen != region->length()) { - if (region->source(0).length() >= region->start() + nlen) { + if (region->source(0)->length() >= region->start() + nlen) { region->freeze (); region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this); @@ -356,7 +377,7 @@ MidiStreamView::update_rec_regions () if (origlen == 1) { /* our special initial length */ - add_region_view_internal (region, false); + iter->second = add_region_view_internal (region, false); } /* also hide rect */ @@ -373,46 +394,32 @@ MidiStreamView::update_rec_regions () } void -MidiStreamView::rec_data_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * src) +MidiStreamView::rec_data_range_ready (boost::shared_ptr data, jack_nframes_t start, jack_nframes_t dur, boost::weak_ptr weak_src) { // this is called from the butler thread for now - // yeah we need a "peak" building thread or something. whatever. :) - ENSURE_GUI_THREAD(bind (mem_fun (*this, &MidiStreamView::rec_data_range_ready), start, cnt, src)); + ENSURE_GUI_THREAD(bind (mem_fun (*this, &MidiStreamView::rec_data_range_ready), data, start, dur, weak_src)); - //cerr << "REC DATA: " << start << " --- " << cnt << endl; - - if (rec_data_ready_map.size() == 0 || start+cnt > last_rec_data_frame) { - last_rec_data_frame = start + cnt; - } - - rec_data_ready_map[src] = true; - - if (rec_data_ready_map.size() == _trackview.get_diskstream()->n_channels().get(DataType::MIDI)) { - this->update_rec_regions (); - rec_data_ready_map.clear(); - } + boost::shared_ptr src (boost::dynamic_pointer_cast(weak_src.lock())); + + //cerr << src.get() << " MIDI READY: " << start << " * " << dur + // << " -- " << data->size() << " events!" << endl; + + this->update_rec_regions (data, start, dur); } void -MidiStreamView::color_handler (ColorID id, uint32_t val) +MidiStreamView::color_handler () { - switch (id) { - case cMidiTrackBase: - if (_trackview.is_midi_track()) { - canvas_rect->property_fill_color_rgba() = val; - } - break; - case cMidiBusBase: - if (!_trackview.is_midi_track()) { - canvas_rect->property_fill_color_rgba() = val; - } - break; - case cMidiTrackOutline: - canvas_rect->property_outline_color_rgba() = val; - break; - default: - break; + //case cMidiTrackBase: + if (_trackview.is_midi_track()) { + canvas_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiTrackBase.get(); + } + + //case cMidiBusBase: + if (!_trackview.is_midi_track()) { + canvas_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiBusBase.get();; } } +