diff options
53 files changed, 935 insertions, 635 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 8fb9a0717b..9035666bbb 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -168,6 +168,7 @@ region_gain_line.cc region_selection.cc region_view.cc audio_region_view.cc +midi_region_view.cc tape_region_view.cc route_params_ui.cc route_redirect_selection.cc diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 0e94259194..34718dfb1c 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -248,7 +248,7 @@ ARDOUR_UI::set_engine (AudioEngine& e) if (AudioSource::start_peak_thread ()) { throw failed_constructor(); } - + /* start the time-of-day-clock */ update_wall_clock (); diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index 2e82d48ff3..523395c503 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -56,7 +56,7 @@ AudioStreamView::AudioStreamView (AudioTimeAxisView& tv) { crossfades_visible = true; - if (tv.is_audio_track()) + if (tv.is_track()) stream_base_color = color_map[cAudioTrackBase]; else stream_base_color = color_map[cAudioBusBase]; @@ -67,7 +67,6 @@ AudioStreamView::AudioStreamView (AudioTimeAxisView& tv) _amplitude_above_axis = 1.0; use_rec_regions = tv.editor.show_waveforms_recording (); - last_rec_peak_frame = 0; } AudioStreamView::~AudioStreamView () @@ -393,10 +392,10 @@ AudioStreamView::setup_rec_box () AudioRegion::SourceList sources; - for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) { + for (list<sigc::connection>::iterator prc = rec_data_ready_connections.begin(); prc != rec_data_ready_connections.end(); ++prc) { (*prc).disconnect(); } - peak_ready_connections.clear(); + rec_data_ready_connections.clear(); // FIXME AudioDiskstream* ads = dynamic_cast<AudioDiskstream*>(_trackview.get_diskstream()); @@ -406,7 +405,7 @@ AudioStreamView::setup_rec_box () AudioSource *src = (AudioSource *) ads->write_source (n); if (src) { sources.push_back (src); - peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), src))); + rec_data_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), src))); } } @@ -492,14 +491,14 @@ AudioStreamView::setup_rec_box () /* disconnect rapid update */ screen_update_connection.disconnect(); - for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) { + for (list<sigc::connection>::iterator prc = rec_data_ready_connections.begin(); prc != rec_data_ready_connections.end(); ++prc) { (*prc).disconnect(); } - peak_ready_connections.clear(); + rec_data_ready_connections.clear(); rec_updating = false; rec_active = false; - last_rec_peak_frame = 0; + last_rec_data_frame = 0; /* remove temp regions */ for (list<Region*>::iterator iter=rec_regions.begin(); iter != rec_regions.end(); ) @@ -547,15 +546,15 @@ AudioStreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, ENSURE_GUI_THREAD(bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), start, cnt, src)); - if (rec_peak_ready_map.size() == 0 || start+cnt > last_rec_peak_frame) { - last_rec_peak_frame = start + cnt; + if (rec_data_ready_map.size() == 0 || start+cnt > last_rec_data_frame) { + last_rec_data_frame = start + cnt; } - rec_peak_ready_map[src] = true; + rec_data_ready_map[src] = true; - if (rec_peak_ready_map.size() == _trackview.get_diskstream()->n_channels().get(DataType::AUDIO)) { + if (rec_data_ready_map.size() == _trackview.get_diskstream()->n_channels().get(DataType::AUDIO)) { this->update_rec_regions (); - rec_peak_ready_map.clear(); + rec_data_ready_map.clear(); } } @@ -587,9 +586,9 @@ AudioStreamView::update_rec_regions () if (region == rec_regions.back() && rec_active) { - if (last_rec_peak_frame > region->start()) { + if (last_rec_data_frame > region->start()) { - jack_nframes_t nlen = last_rec_peak_frame - region->start(); + jack_nframes_t nlen = last_rec_data_frame - region->start(); if (nlen != region->length()) { diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h index 05ce8125f6..979240bd50 100644 --- a/gtk2_ardour/audio_streamview.h +++ b/gtk2_ardour/audio_streamview.h @@ -94,17 +94,11 @@ class AudioStreamView : public StreamView void color_handler (ColorID id, uint32_t val); - double _amplitude_above_axis; typedef list<CrossfadeView*> CrossfadeViewList; CrossfadeViewList crossfade_views; bool crossfades_visible; - - list<sigc::connection> peak_ready_connections; - jack_nframes_t last_rec_peak_frame; - map<ARDOUR::Source*, bool> rec_peak_ready_map; - }; #endif /* __ardour_audio_streamview_h__ */ diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index 893bcc21c0..7f6bc50222 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -117,7 +117,7 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::sh _route->panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans)); - if (is_audio_track()) { + if (is_track()) { controls_ebox.set_name ("AudioTrackControlsBaseUnselected"); controls_base_selected_name = "AudioTrackControlsBaseSelected"; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 513251085c..b991982855 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1178,8 +1178,8 @@ Editor::connect_to_session (Session *t) session_connections.push_back (session->TransportStateChange.connect (mem_fun(*this, &Editor::map_transport_state))); session_connections.push_back (session->PositionChanged.connect (mem_fun(*this, &Editor::map_position_change))); session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route))); - session_connections.push_back (session->AudioRegionAdded.connect (mem_fun(*this, &Editor::handle_new_audio_region))); - session_connections.push_back (session->AudioRegionRemoved.connect (mem_fun(*this, &Editor::handle_audio_region_removed))); + session_connections.push_back (session->RegionAdded.connect (mem_fun(*this, &Editor::handle_new_region))); + session_connections.push_back (session->RegionRemoved.connect (mem_fun(*this, &Editor::handle_region_removed))); session_connections.push_back (session->DurationChanged.connect (mem_fun(*this, &Editor::handle_new_duration))); session_connections.push_back (session->edit_group_added.connect (mem_fun(*this, &Editor::add_edit_group))); session_connections.push_back (session->edit_group_removed.connect (mem_fun(*this, &Editor::edit_groups_changed))); @@ -1327,10 +1327,10 @@ Editor::connect_to_session (Session *t) for (i = rows.begin(); i != rows.end(); ++i) { TimeAxisView *tv = (*i)[route_display_columns.tv]; - AudioTimeAxisView *atv; + RouteTimeAxisView *rtv; - if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) { - if (atv->route()->master()) { + if ((rtv = dynamic_cast<RouteTimeAxisView*>(tv)) != 0) { + if (rtv->route()->master()) { route_list_display.get_selection()->unselect (i); } } diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index b3735cf42a..3f2a278f09 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -832,14 +832,14 @@ class Editor : public PublicEditor int ensure_cursor (jack_nframes_t* pos); - void handle_new_audio_region (ARDOUR::AudioRegion *); - void handle_audio_region_removed (ARDOUR::AudioRegion *); - void add_audio_region_to_region_display (ARDOUR::AudioRegion *); + void handle_new_region (ARDOUR::Region *); + void handle_region_removed (ARDOUR::Region *); + void add_region_to_region_display (ARDOUR::Region *); void region_hidden (ARDOUR::Region*); void redisplay_regions (); - void insert_into_tmp_audio_regionlist(ARDOUR::AudioRegion *); + void insert_into_tmp_regionlist(ARDOUR::Region *); - list<ARDOUR::AudioRegion *> tmp_audio_region_list; + list<ARDOUR::Region *> tmp_region_list; void cut_copy (Editing::CutCopyOp); void cut_copy_points (Editing::CutCopyOp); diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 754706ad9f..de256ce0e6 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -176,8 +176,9 @@ Editor::import_sndfile (Glib::ustring path, ImportMode mode, AudioTrack* track, /* import thread finished - see if we should build a new track */ if (!import_status.new_regions.empty()) { - AudioRegion& region (*import_status.new_regions.front()); - finish_bringing_in_audio (region, region.n_channels(), region.n_channels(), track, pos, mode); + AudioRegion* const aregion = dynamic_cast<AudioRegion*>(import_status.new_regions.front()); + assert(aregion); + finish_bringing_in_audio (*aregion, aregion->n_channels(), aregion->n_channels(), track, pos, mode); } track_canvas.get_window()->set_cursor (*current_canvas_cursor); diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index e8ba2b8a60..2f3aab1eb6 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -426,7 +426,7 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context, guint info, guint time) { TimeAxisView* tvp; - AudioTimeAxisView* tv; + RouteTimeAxisView* tv; double cy; vector<ustring> paths; string spath; @@ -462,7 +462,7 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context, jack_nframes_t pos = 0; do_embed (paths, false, ImportAsTrack, 0, pos, false); - } else if ((tv = dynamic_cast<AudioTimeAxisView*>(tvp)) != 0) { + } else if ((tv = dynamic_cast<RouteTimeAxisView*>(tvp)) != 0) { /* check that its an audio track, not a bus */ @@ -486,9 +486,9 @@ Editor::drop_regions (const RefPtr<Gdk::DragContext>& context, for (uint32_t i = 0; i < sr->cnt; ++i) { Region* r = reinterpret_cast<Region*> (sr->ptr[i]); - AudioRegion* ar; - if ((ar = dynamic_cast<AudioRegion*>(r)) != 0) { + AudioRegion* ar = dynamic_cast<AudioRegion*>(r); + if (ar) { insert_region_list_drag (*ar, x, y); } } diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index a05dcba9e3..f459f24341 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -2682,7 +2682,7 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event) TimeAxisView* tvp = clicked_trackview; RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } @@ -2711,11 +2711,11 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event) start_grab(event); TimeAxisView* tv = &clicked_regionview->get_time_axis_view(); - RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(tv); + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(tv); double speed = 1.0; - if (atv && atv->is_audio_track()) { - speed = atv->get_diskstream()->speed(); + if (rtv && rtv->is_track()) { + speed = rtv->get_diskstream()->speed(); } drag_info.last_trackview = &clicked_regionview->get_time_axis_view(); @@ -2746,7 +2746,7 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) TimeAxisView* tvp = clicked_trackview; RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } @@ -2796,7 +2796,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) rv = (*i); Playlist* to_playlist = rv->region().playlist(); - RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view()); + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view()); insert_result = affected_playlists.insert (to_playlist); if (insert_result.second) { @@ -2805,7 +2805,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) latest_regionview = 0; - sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + sigc::connection c = rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); /* create a new region with the same name. */ @@ -2821,7 +2821,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) newregion->set_locked (false); - to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region().position() * atv->get_diskstream()->speed())); + to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region().position() * rtv->get_diskstream()->speed())); c.disconnect (); @@ -2847,15 +2847,15 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) /* Which trackview is this ? */ TimeAxisView* tvp = trackview_by_y_position (drag_info.current_pointer_y); - AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp); + RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); /* The region motion is only processed if the pointer is over an audio track. */ - if (!tv || !tv->is_audio_track()) { + if (!tv || !tv->is_track()) { /* To make sure we hide the verbose canvas cursor when the mouse is - not held over and audiotrack. + not held over a track. */ hide_verbose_canvas_cursor (); return; @@ -2883,30 +2883,30 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { TimeAxisView *tracklist_timeview; tracklist_timeview = (*i); - AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tracklist_timeview); + RouteTimeAxisView* rtv2 = dynamic_cast<RouteTimeAxisView*>(tracklist_timeview); list<TimeAxisView*> children_list; /* zeroes are audio tracks. ones are other types. */ - if (!atv2->hidden()) { + if (!rtv2->hidden()) { - if (visible_y_high < atv2->order) { - visible_y_high = atv2->order; + if (visible_y_high < rtv2->order) { + visible_y_high = rtv2->order; } - if (visible_y_low > atv2->order) { - visible_y_low = atv2->order; + if (visible_y_low > rtv2->order) { + visible_y_low = rtv2->order; } - if (!atv2->is_audio_track()) { - tracks = tracks |= (0x01 << atv2->order); + if (!rtv2->is_track()) { + tracks = tracks |= (0x01 << rtv2->order); } - height_list[atv2->order] = (*i)->height; + height_list[rtv2->order] = (*i)->height; children = 1; - if ((children_list = atv2->get_child_list()).size() > 0) { + if ((children_list = rtv2->get_child_list()).size() > 0) { for (list<TimeAxisView*>::iterator j = children_list.begin(); j != children_list.end(); ++j) { - tracks = tracks |= (0x01 << (atv2->order + children)); - height_list[atv2->order + children] = (*j)->height; + tracks = tracks |= (0x01 << (rtv2->order + children)); + height_list[rtv2->order + children] = (*j)->height; numtracks++; children++; } @@ -2941,27 +2941,27 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); rv2->get_canvas_group()->i2w (ix1, iy1); TimeAxisView* tvp2 = trackview_by_y_position (iy1); - RouteTimeAxisView* atv2 = dynamic_cast<RouteTimeAxisView*>(tvp2); + RouteTimeAxisView* rtv2 = dynamic_cast<RouteTimeAxisView*>(tvp2); - if (atv2->order != original_pointer_order) { + if (rtv2->order != original_pointer_order) { /* this isn't the pointer track */ if (canvas_pointer_y_span > 0) { /* moving up the canvas */ - if ((atv2->order - canvas_pointer_y_span) >= visible_y_low) { + if ((rtv2->order - canvas_pointer_y_span) >= visible_y_low) { int32_t visible_tracks = 0; while (visible_tracks < canvas_pointer_y_span ) { visible_tracks++; - while (height_list[atv2->order - (visible_tracks - n)] == 0) { + while (height_list[rtv2->order - (visible_tracks - n)] == 0) { /* we're passing through a hidden track */ n--; } } - if (tracks[atv2->order - (canvas_pointer_y_span - n)] != 0x00) { + if (tracks[rtv2->order - (canvas_pointer_y_span - n)] != 0x00) { clamp_y_axis = true; } @@ -2973,7 +2973,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) /*moving down the canvas*/ - if ((atv2->order - (canvas_pointer_y_span - n)) <= visible_y_high) { // we will overflow + if ((rtv2->order - (canvas_pointer_y_span - n)) <= visible_y_high) { // we will overflow int32_t visible_tracks = 0; @@ -2981,11 +2981,11 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) while (visible_tracks > canvas_pointer_y_span ) { visible_tracks--; - while (height_list[atv2->order - (visible_tracks - n)] == 0) { + while (height_list[rtv2->order - (visible_tracks - n)] == 0) { n++; } } - if ( tracks[atv2->order - ( canvas_pointer_y_span - n)] != 0x00) { + if ( tracks[rtv2->order - ( canvas_pointer_y_span - n)] != 0x00) { clamp_y_axis = true; } @@ -2998,9 +2998,9 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } else { /* this is the pointer's track */ - if ((atv2->order - pointer_y_span) > visible_y_high) { // we will overflow + if ((rtv2->order - pointer_y_span) > visible_y_high) { // we will overflow clamp_y_axis = true; - } else if ((atv2->order - pointer_y_span) < visible_y_low) { // we will underflow + } else if ((rtv2->order - pointer_y_span) < visible_y_low) { // we will underflow clamp_y_axis = true; } } @@ -3136,14 +3136,14 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); rv->get_canvas_group()->i2w (ix1, iy1); TimeAxisView* tvp2 = trackview_by_y_position (iy1); - AudioTimeAxisView* canvas_atv = dynamic_cast<AudioTimeAxisView*>(tvp2); - AudioTimeAxisView* temp_atv; + RouteTimeAxisView* canvas_rtv = dynamic_cast<RouteTimeAxisView*>(tvp2); + RouteTimeAxisView* temp_rtv; if ((pointer_y_span != 0) && !clamp_y_axis) { y_delta = 0; int32_t x = 0; for (j = height_list.begin(); j!= height_list.end(); j++) { - if (x == canvas_atv->order) { + if (x == canvas_rtv->order) { /* we found the track the region is on */ if (x != original_pointer_order) { /*this isn't from the same track we're dragging from */ @@ -3181,14 +3181,14 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) /* find out where we'll be when we move and set height accordingly */ tvp2 = trackview_by_y_position (iy1 + y_delta); - temp_atv = dynamic_cast<AudioTimeAxisView*>(tvp2); - rv->set_height (temp_atv->height); + temp_rtv = dynamic_cast<RouteTimeAxisView*>(tvp2); + rv->set_height (temp_rtv->height); /* if you un-comment the following, the region colours will follow the track colours whilst dragging, personally, i think this can confuse things, but never mind. */ - //const GdkColor& col (temp_atv->view->get_region_color()); + //const GdkColor& col (temp_rtv->view->get_region_color()); //rv->set_color (const_cast<GdkColor&>(col)); break; } @@ -3229,9 +3229,9 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) the motion is done. */ - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&rv->get_time_axis_view()); - if (atv && atv->is_audio_track()) { - AudioPlaylist* pl = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist()); + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view()); + if (rtv && rtv->is_track()) { + Playlist* pl = dynamic_cast<Playlist*>(rtv->get_diskstream()->playlist()); if (pl) { /* only freeze and capture state once */ @@ -3300,7 +3300,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event /* adjust for track speed */ speed = 1.0; - atv = dynamic_cast<AudioTimeAxisView*> (drag_info.last_trackview); + atv = dynamic_cast<RouteTimeAxisView*> (drag_info.last_trackview); if (atv && atv->get_diskstream()) { speed = atv->get_diskstream()->speed(); } @@ -3348,7 +3348,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event (*i)->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); (*i)->get_canvas_group()->i2w (ix1, iy1); TimeAxisView* tvp2 = trackview_by_y_position (iy1); - AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2); + RouteTimeAxisView* atv2 = dynamic_cast<RouteTimeAxisView*>(tvp2); from_playlist = (*i)->region().playlist(); to_playlist = atv2->playlist(); @@ -3383,7 +3383,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event (*i)->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); (*i)->get_canvas_group()->i2w (ix1, iy1); TimeAxisView* tvp2 = trackview_by_y_position (iy1); - AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2); + RouteTimeAxisView* atv2 = dynamic_cast<RouteTimeAxisView*>(tvp2); from_playlist = (*i)->region().playlist(); to_playlist = atv2->playlist(); @@ -3418,7 +3418,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event if (regionview_x_movement) { double ownspeed = 1.0; - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&(rv->get_time_axis_view())); + RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*> (&(rv->get_time_axis_view())); if (atv && atv->get_diskstream()) { ownspeed = atv->get_diskstream()->speed(); @@ -3467,9 +3467,9 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event) if (Keyboard::modifier_state_contains (event->state, Keyboard::Control)) { TimeAxisView* tv = &rv.get_time_axis_view(); - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(tv); + RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(tv); double speed = 1.0; - if (atv && atv->is_audio_track()) { + if (atv && atv->is_track()) { speed = atv->get_diskstream()->speed(); } @@ -3904,9 +3904,9 @@ Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event) { double speed = 1.0; TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp); + RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } @@ -3967,7 +3967,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); pair<set<Playlist*>::iterator,bool> insert_result; - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } @@ -4093,7 +4093,7 @@ Editor::single_contents_trim (RegionView& rv, jack_nframes_t frame_delta, bool l TimeAxisView* tvp = clicked_trackview; RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } @@ -4131,9 +4131,9 @@ Editor::single_start_trim (RegionView& rv, jack_nframes_t frame_delta, bool left double speed = 1.0; TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp); + RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } @@ -4165,9 +4165,9 @@ Editor::single_end_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_d double speed = 1.0; TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp); + RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } @@ -4824,7 +4824,7 @@ Editor::mouse_brush_insert_region (RegionView* rv, jack_nframes_t pos) RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&arv->get_time_axis_view()); - if (atv == 0 || !atv->is_audio_track()) { + if (atv == 0 || !atv->is_track()) { return; } diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 9b69026a01..30e19c484c 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2275,6 +2275,8 @@ Editor::new_region_from_selection () void Editor::separate_region_from_selection () { + // FIXME: TYPE + bool doing_undo = false; if (selection->time.empty()) { @@ -2321,6 +2323,8 @@ Editor::separate_region_from_selection () void Editor::separate_regions_using_location (Location& loc) { + // FIXME: TYPE + bool doing_undo = false; if (loc.is_mark()) { @@ -2391,15 +2395,12 @@ Editor::crop_region_to_selection () for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - AudioTimeAxisView* atv; + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*i); - if ((atv = dynamic_cast<AudioTimeAxisView*> ((*i))) != 0) { + if (rtv && rtv->is_track()) { - if (atv->is_audio_track()) { - - if ((playlist = atv->playlist()) != 0) { - playlists.push_back (playlist); - } + if ((playlist = rtv->playlist()) != 0) { + playlists.push_back (playlist); } } } @@ -2460,8 +2461,7 @@ Editor::region_fill_track () // FIXME AudioRegion* const ar = dynamic_cast<AudioRegion*>(®ion); - if (!ar) - continue; + assert(ar); Playlist* pl = region.playlist(); @@ -2475,7 +2475,7 @@ Editor::region_fill_track () return; } - XMLNode &before = pl->get_state(); + XMLNode &before = pl->get_state(); pl->add_region (*(new AudioRegion (*ar)), ar->last_frame(), times); session->add_command (new MementoCommand<Playlist>(*pl, before, pl->get_state())); } @@ -2486,7 +2486,7 @@ Editor::region_fill_track () void Editor::region_fill_selection () { - if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) { + if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) { return; } @@ -2613,7 +2613,7 @@ Editor::align_relative (RegionPoint what) } struct RegionSortByTime { - bool operator() (const AudioRegionView* a, const AudioRegionView* b) { + bool operator() (const RegionView* a, const RegionView* b) { return a->region().position() < b->region().position(); } }; @@ -2781,11 +2781,11 @@ Editor::trim_region_from_edit_cursor () void Editor::unfreeze_route () { - if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) { + if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_track()) { return; } - clicked_audio_trackview->audio_track()->unfreeze (); + clicked_audio_trackview->track()->unfreeze (); } void* @@ -2812,7 +2812,7 @@ Editor::freeze_progress_timeout (void *arg) void Editor::freeze_route () { - if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) { + if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_track()) { return; } diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc index 5cf099433b..7df91cfa4f 100644 --- a/gtk2_ardour/editor_region_list.cc +++ b/gtk2_ardour/editor_region_list.cc @@ -48,22 +48,22 @@ using namespace Glib; using namespace Editing; void -Editor::handle_audio_region_removed (AudioRegion* region) +Editor::handle_region_removed (Region* region) { - ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_audio_region_removed), region)); + ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_region_removed), region)); redisplay_regions (); } void -Editor::handle_new_audio_region (AudioRegion *region) +Editor::handle_new_region (Region *region) { - ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_audio_region), region)); + ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_region), region)); /* don't copy region - the one we are being notified about belongs to the session, and so it will never be edited. */ - add_audio_region_to_region_display (region); + add_region_to_region_display (region); } void @@ -75,7 +75,7 @@ Editor::region_hidden (Region* r) } void -Editor::add_audio_region_to_region_display (AudioRegion *region) +Editor::add_region_to_region_display (Region *region) { string str; TreeModel::Row row; @@ -206,14 +206,14 @@ Editor::region_list_selection_changed() } void -Editor::insert_into_tmp_audio_regionlist(AudioRegion* region) +Editor::insert_into_tmp_regionlist(Region* region) { /* keep all whole files at the beginning */ if (region->whole_file()) { - tmp_audio_region_list.push_front (region); + tmp_region_list.push_front (region); } else { - tmp_audio_region_list.push_back (region); + tmp_region_list.push_back (region); } } @@ -229,11 +229,11 @@ Editor::redisplay_regions () sorting. */ - tmp_audio_region_list.clear(); - session->foreach_audio_region (this, &Editor::insert_into_tmp_audio_regionlist); + tmp_region_list.clear(); + session->foreach_region (this, &Editor::insert_into_tmp_regionlist); - for (list<AudioRegion*>::iterator r = tmp_audio_region_list.begin(); r != tmp_audio_region_list.end(); ++r) { - add_audio_region_to_region_display (*r); + for (list<Region*>::iterator r = tmp_region_list.begin(); r != tmp_region_list.end(); ++r) { + add_region_to_region_display (*r); } region_list_display.set_model (region_list_model); diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index 9f7fe7cf09..2e4e092ebd 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -134,10 +134,10 @@ Editor::hide_measures () ArdourCanvas::SimpleLine * Editor::get_time_line () { - ArdourCanvas::SimpleLine *line; + ArdourCanvas::SimpleLine *line; if (free_measure_lines.empty()) { - line = new ArdourCanvas::SimpleLine (*time_line_group); + line = new ArdourCanvas::SimpleLine (*time_line_group); used_measure_lines.push_back (line); } else { line = free_measure_lines.front(); @@ -194,6 +194,7 @@ Editor::draw_measures () double x1, x2, y1, y2; track_canvas.get_scroll_region (x1, y1, x2, y2); + y2 = 1000000000.0f; for (i = all_bbt_points->begin(); i != all_bbt_points->end(); ++i) { diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index d716a5605a..2e102b4f70 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -68,7 +68,8 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd) // FIXME: Some redundancy here with RegionView::init. Need to figure out // where order is important and where it isn't... - RegionView::init(basic_color, wfd); + // FIXME + RegionView::init(basic_color, /*wfd*/false); compute_colors (basic_color); @@ -108,6 +109,7 @@ MidiRegionView::show_region_editor () GhostRegion* MidiRegionView::add_ghost (AutomationTimeAxisView& atv) { + throw; // FIXME return NULL; } diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc index 60372e640f..5f939ab583 100644 --- a/gtk2_ardour/midi_streamview.cc +++ b/gtk2_ardour/midi_streamview.cc @@ -29,11 +29,11 @@ #include <ardour/midi_diskstream.h> #include <ardour/midi_track.h> //#include <ardour/playlist_templates.h> -#include <ardour/source.h> +#include <ardour/midi_source.h> #include "midi_streamview.h" #include "region_view.h" -//#include "midi_regionview.h" +#include "midi_region_view.h" #include "midi_time_axis.h" #include "canvas-simplerect.h" #include "region_selection.h" @@ -52,55 +52,26 @@ using namespace Editing; MidiStreamView::MidiStreamView (MidiTimeAxisView& tv) : StreamView (tv) { - region_color = _trackview.color(); - - if (tv.is_midi_track()) + if (tv.is_track()) stream_base_color = color_map[cMidiTrackBase]; else stream_base_color = color_map[cMidiBusBase]; - - /* set_position() will position the group */ - - canvas_group = new ArdourCanvas::Group(*_trackview.canvas_display); - - canvas_rect = new ArdourCanvas::SimpleRect (*canvas_group); - canvas_rect->property_x1() = 0.0; - canvas_rect->property_y1() = 0.0; - canvas_rect->property_x2() = 1000000.0; - canvas_rect->property_y2() = (double) tv.height; - canvas_rect->property_outline_color_rgba() = color_map[cMidiTrackOutline]; - canvas_rect->property_outline_what() = (guint32) (0x1|0x2|0x8); // outline ends and bottom + canvas_rect->property_fill_color_rgba() = stream_base_color; + canvas_rect->property_outline_color_rgba() = color_map[cAudioTrackOutline]; - canvas_rect->signal_event().connect (bind (mem_fun (_trackview.editor, &PublicEditor::canvas_stream_view_event), canvas_rect, &_trackview)); - - _samples_per_unit = _trackview.editor.get_current_zoom(); - - if (_trackview.is_midi_track()) { - _trackview.midi_track()->DiskstreamChanged.connect (mem_fun (*this, &MidiStreamView::diskstream_changed)); - _trackview.session().TransportStateChange.connect (mem_fun (*this, &MidiStreamView::transport_changed)); - _trackview.get_diskstream()->RecordEnableChanged.connect (mem_fun (*this, &MidiStreamView::rec_enable_changed)); - _trackview.session().RecordStateChanged.connect (mem_fun (*this, &MidiStreamView::sess_rec_enable_changed)); - } - - rec_updating = false; - rec_active = false; - use_rec_regions = tv.editor.show_waveforms_recording (); - - ColorChanged.connect (mem_fun (*this, &MidiStreamView::color_handler)); + //use_rec_regions = tv.editor.show_waveforms_recording (); + use_rec_regions = true; } MidiStreamView::~MidiStreamView () { - undisplay_diskstream (); - delete canvas_group; } void MidiStreamView::add_region_view_internal (Region *r, bool wait_for_waves) { -#if 0 ENSURE_GUI_THREAD (bind (mem_fun (*this, &MidiStreamView::add_region_view), r)); MidiRegion* region = dynamic_cast<MidiRegion*> (r); @@ -122,30 +93,25 @@ MidiStreamView::add_region_view_internal (Region *r, bool wait_for_waves) } } - /* FIXME - switch (_trackview.midi_track()->mode()) { - case Normal: - region_view = new MidiRegionView (canvas_group, _trackview, *region, - _samples_per_unit, region_color); - break; - case Destructive: - region_view = new TapeMidiRegionView (canvas_group, _trackview, *region, - _samples_per_unit, region_color); - break; - } - */ + // can't we all just get along? + assert(_trackview.midi_track()->mode() != Destructive); + region_view = new MidiRegionView (canvas_group, _trackview, *region, - _samples_per_unit, region_color); + _samples_per_unit, region_color); region_view->init (region_color, wait_for_waves); region_views.push_front (region_view); + /* follow global waveform setting */ + + // FIXME + //region_view->set_waveform_visible(_trackview.editor.show_waveforms()); + /* catch regionview going away */ region->GoingAway.connect (mem_fun (*this, &MidiStreamView::remove_region_view)); RegionViewAdded (region_view); -#endif } // FIXME: code duplication with AudioStreamVIew @@ -183,26 +149,30 @@ MidiStreamView::redisplay_diskstream () void MidiStreamView::setup_rec_box () { -#if 0 // cerr << _trackview.name() << " streamview SRB\n"; if (_trackview.session().transport_rolling()) { - // cerr << "\trolling\n"; + cerr << "\tSHOW: rolling\n"; if (!rec_active && _trackview.session().record_status() == Session::Recording && _trackview.get_diskstream()->record_enabled()) { - if (_trackview.midi_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) { + if (use_rec_regions && rec_regions.size() == rec_rects.size()) { /* add a new region, but don't bother if they set use_rec_regions mid-record */ MidiRegion::SourceList sources; // FIXME - MidiDiskstream* ads = dynamic_cast<MidiDiskstream*>(_trackview.get_diskstream()); - assert(ads); + MidiDiskstream* mds = dynamic_cast<MidiDiskstream*>(_trackview.get_diskstream()); + assert(mds); + + sources.push_back((Source*)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()))); // handle multi @@ -222,30 +192,17 @@ MidiStreamView::setup_rec_box () /* start a new rec box */ - MidiTrack* at; - - at = _trackview.midi_track(); /* we know what it is already */ - MidiDiskstream& ds = at->midi_diskstream(); + 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 (); gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos); gdouble xend; uint32_t fill_color; - switch (_trackview.midi_track()->mode()) { - case Normal: - xend = xstart; - fill_color = color_map[cRecordingRectFill]; - break; - - case Destructive: - xend = xstart + 2; - fill_color = color_map[cRecordingRectFill]; - /* make the recording rect translucent to allow - the user to see the peak data coming in, etc. - */ - fill_color = UINT_RGBA_CHANGE_A (fill_color, 120); - break; - } + assert(_trackview.midi_track()->mode() == Normal); + + xend = xstart; + fill_color = color_map[cRecordingRectFill]; ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group); rec_rect->property_x1() = xstart; @@ -267,10 +224,16 @@ 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; @@ -279,21 +242,21 @@ 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()) { /* disconnect rapid update */ screen_update_connection.disconnect(); - for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) { + for (list<sigc::connection>::iterator prc = rec_data_ready_connections.begin(); prc != rec_data_ready_connections.end(); ++prc) { (*prc).disconnect(); } - peak_ready_connections.clear(); + rec_data_ready_connections.clear(); rec_updating = false; rec_active = false; - last_rec_peak_frame = 0; + last_rec_data_frame = 0; /* remove temp regions */ for (list<Region*>::iterator iter=rec_regions.begin(); iter != rec_regions.end(); ) @@ -324,15 +287,14 @@ MidiStreamView::setup_rec_box () } } -#endif } void MidiStreamView::update_rec_regions () { -#if 0 if (use_rec_regions) { + uint32_t n = 0; for (list<Region*>::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) { @@ -356,9 +318,9 @@ MidiStreamView::update_rec_regions () if (region == rec_regions.back() && rec_active) { - if (last_rec_peak_frame > region->start()) { + if (last_rec_data_frame > region->start()) { - jack_nframes_t nlen = last_rec_peak_frame - region->start(); + jack_nframes_t nlen = last_rec_data_frame - region->start(); if (nlen != region->length()) { @@ -408,7 +370,28 @@ MidiStreamView::update_rec_regions () iter = tmp; } } -#endif +} + +void +MidiStreamView::rec_data_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * 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)); + + //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(); + } } void diff --git a/gtk2_ardour/midi_streamview.h b/gtk2_ardour/midi_streamview.h index 0b13f9fd7f..107a804db8 100644 --- a/gtk2_ardour/midi_streamview.h +++ b/gtk2_ardour/midi_streamview.h @@ -62,7 +62,7 @@ class MidiStreamView : public StreamView private: void setup_rec_box (); - void rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, ARDOUR::Source* src); + void rec_data_range_ready (jack_nframes_t start, jack_nframes_t cnt, ARDOUR::Source* src); void update_rec_regions (); void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves); diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index 041eebff10..9300986960 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -98,26 +98,27 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, boost::shar /* map current state of the route */ - //redirects_changed (0); + redirects_changed (0); ensure_xml_node (); set_state (*xml_node); - //_route.redirects_changed.connect (mem_fun(*this, &MidiTimeAxisView::redirects_changed)); + _route->redirects_changed.connect (mem_fun(*this, &MidiTimeAxisView::redirects_changed)); - if (is_midi_track()) { + if (is_track()) { controls_ebox.set_name ("MidiTrackControlsBaseUnselected"); controls_base_selected_name = "MidiTrackControlsBaseSelected"; controls_base_unselected_name = "MidiTrackControlsBaseUnselected"; /* ask for notifications of any new RegionViews */ - //view->MidiRegionViewAdded.connect (mem_fun(*this, &MidiTimeAxisView::region_view_added)); - //view->attach (); + _view->RegionViewAdded.connect (mem_fun(*this, &MidiTimeAxisView::region_view_added)); + _view->attach (); } else { /* bus */ + throw; // what the? controls_ebox.set_name ("MidiBusControlsBaseUnselected"); controls_base_selected_name = "MidiBusControlsBaseSelected"; controls_base_unselected_name = "MidiBusControlsBaseUnselected"; @@ -174,75 +175,6 @@ MidiTimeAxisView::set_state (const XMLNode& node) } } -void -MidiTimeAxisView::build_display_menu () -{ - using namespace Menu_Helpers; - - /* get the size menu ready */ - - build_size_menu (); - - /* prepare it */ - - TimeAxisView::build_display_menu (); - - /* now fill it with our stuff */ - - MenuList& items = display_menu->items(); - display_menu->set_name ("ArdourContextMenu"); - - items.push_back (MenuElem (_("Height"), *size_menu)); - items.push_back (MenuElem (_("Color"), mem_fun(*this, &MidiTimeAxisView::select_track_color))); - - - items.push_back (SeparatorElem()); - - build_remote_control_menu (); - items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu)); - - automation_action_menu = manage (new Menu); - MenuList& automation_items = automation_action_menu->items(); - automation_action_menu->set_name ("ArdourContextMenu"); - - automation_items.push_back (SeparatorElem()); - - automation_items.push_back (MenuElem (_("Plugins"), subplugin_menu)); - - if (is_midi_track()) { - - Menu* alignment_menu = manage (new Menu); - MenuList& alignment_items = alignment_menu->items(); - alignment_menu->set_name ("ArdourContextMenu"); - - RadioMenuItem::Group align_group; - - alignment_items.push_back (RadioMenuElem (align_group, _("Align with existing material"), bind (mem_fun(*this, &MidiTimeAxisView::set_align_style), ExistingMaterial))); - align_existing_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back()); - if (get_diskstream()->alignment_style() == ExistingMaterial) { - align_existing_item->set_active(); - } - alignment_items.push_back (RadioMenuElem (align_group, _("Align with capture time"), bind (mem_fun(*this, &MidiTimeAxisView::set_align_style), CaptureTime))); - align_capture_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back()); - if (get_diskstream()->alignment_style() == CaptureTime) { - align_capture_item->set_active(); - } - - items.push_back (MenuElem (_("Alignment"), *alignment_menu)); - - get_diskstream()->AlignmentStyleChanged.connect (mem_fun(*this, &MidiTimeAxisView::align_style_changed)); - } - - items.push_back (SeparatorElem()); - items.push_back (CheckMenuElem (_("Active"), mem_fun(*this, &RouteUI::toggle_route_active))); - route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back()); - route_active_menu_item->set_active (_route->active()); - - items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route))); - -} - // FIXME: duplicated in audio_time_axis.cc /*static string legalize_for_xml_node (string str) @@ -267,7 +199,7 @@ MidiTimeAxisView::route_active_changed () { RouteUI::route_active_changed (); - if (is_midi_track()) { + if (is_track()) { if (_route->active()) { controls_ebox.set_name ("MidiTrackControlsBaseUnselected"); controls_base_selected_name = "MidiTrackControlsBaseSelected"; @@ -278,6 +210,9 @@ MidiTimeAxisView::route_active_changed () controls_base_unselected_name = "MidiTrackControlsBaseInactiveUnselected"; } } else { + + throw; // wha? + if (_route->active()) { controls_ebox.set_name ("BusControlsBaseUnselected"); controls_base_selected_name = "BusControlsBaseSelected"; diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h index be01e16d26..df1c964fee 100644 --- a/gtk2_ardour/midi_time_axis.h +++ b/gtk2_ardour/midi_time_axis.h @@ -74,14 +74,10 @@ class MidiTimeAxisView : public RouteTimeAxisView XMLNode* get_child_xml_node (const string & childname); private: - void region_view_added (RegionView*) {} - void route_active_changed (); //void redirects_changed (void *); FIXME? - void build_display_menu (); - void add_redirect_to_subplugin_menu (ARDOUR::Redirect *); Gtk::Menu subplugin_menu; diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index e90355fd0a..6b3c2a820c 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -300,10 +300,10 @@ RouteUI::rec_enable_press(GdkEventButton* ev) } else { - reversibly_apply_audio_track_boolean ("rec-enable change", &AudioTrack::set_record_enable, !audio_track()->record_enabled(), this); + reversibly_apply_track_boolean ("rec-enable change", &Track::set_record_enable, !track()->record_enabled(), this); ignore_toggle = true; - rec_enable_button->set_active(audio_track()->record_enabled()); + rec_enable_button->set_active(track()->record_enabled()); ignore_toggle = false; } @@ -593,6 +593,17 @@ RouteUI::reversibly_apply_audio_track_boolean (string name, void (AudioTrack::*f } void +RouteUI::reversibly_apply_track_boolean (string name, void (Track::*func)(bool, void *), bool yn, void *arg) +{ + _session.begin_reversible_command (name); + XMLNode &before = track()->get_state(); + bind (mem_fun (*track(), func), yn, arg)(); + XMLNode &after = track()->get_state(); + _session.add_command (new MementoCommand<Track>(*track(), before, after)); + _session.commit_reversible_command (); +} + +void RouteUI::set_mix_group_mute(boost::shared_ptr<Route> route, bool yn) { RouteGroup* mix_group; diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h index 643c39b960..156063a8e5 100644 --- a/gtk2_ardour/route_ui.h +++ b/gtk2_ardour/route_ui.h @@ -156,6 +156,7 @@ class RouteUI : public virtual AxisView void reversibly_apply_route_boolean (string name, void (ARDOUR::Route::*func)(bool, void*), bool, void *); void reversibly_apply_audio_track_boolean (string name, void (ARDOUR::AudioTrack::*func)(bool, void*), bool, void *); + void reversibly_apply_track_boolean (string name, void (ARDOUR::Track::*func)(bool, void*), bool, void *); }; #endif /* __ardour_route_ui__ */ diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index d1d163d7a2..82f941f9bd 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -56,6 +56,7 @@ StreamView::StreamView (RouteTimeAxisView& tv) , use_rec_regions(tv.editor.show_waveforms_recording()) , region_color(_trackview.color()) , stream_base_color(0xFFFFFFFF) + , last_rec_data_frame(0) { /* set_position() will position the group */ diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h index 5a0e10974f..bee51e8835 100644 --- a/gtk2_ardour/streamview.h +++ b/gtk2_ardour/streamview.h @@ -144,6 +144,10 @@ protected: vector<sigc::connection> playlist_connections; sigc::connection playlist_change_connection; + + list<sigc::connection> rec_data_ready_connections; + jack_nframes_t last_rec_data_frame; + map<ARDOUR::Source*, bool> rec_data_ready_map; }; #endif /* __ardour_streamview_h__ */ diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index 4af857c1d6..c3c2f9bb9a 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -70,8 +70,6 @@ class AudioSource : public Source int read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_unit) const; int build_peaks (); bool peaks_ready (sigc::slot<void>, sigc::connection&) const; - - static sigc::signal<void,AudioSource*> AudioSourceCreated; mutable sigc::signal<void> PeaksReady; mutable sigc::signal<void,jack_nframes_t,jack_nframes_t> PeakRangeReady; diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index c4e85c00ce..fa1126901d 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -238,8 +238,8 @@ class Diskstream : public Stateful, public sigc::trackable virtual void get_input_sources () = 0; virtual void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record) = 0; virtual void set_align_style_from_io() {} - virtual void setup_destructive_playlist () = 0; - virtual void use_destructive_playlist () = 0; + virtual void setup_destructive_playlist () {} + virtual void use_destructive_playlist () {} static jack_nframes_t disk_io_chunk_frames; vector<CaptureInfo*> capture_info; diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h index a048cf4021..8085e6509a 100644 --- a/libs/ardour/ardour/midi_diskstream.h +++ b/libs/ardour/ardour/midi_diskstream.h @@ -83,6 +83,10 @@ class MidiDiskstream : public Diskstream void monitor_input (bool); + MidiSource* write_source() { return (MidiSource*)_write_source; } + + void set_destructive (bool yn); // doom! + protected: friend class Session; @@ -138,8 +142,6 @@ class MidiDiskstream : public Diskstream void get_input_sources (); void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record); void set_align_style_from_io(); - void setup_destructive_playlist (); - void use_destructive_playlist (); void engage_record_enable (); void disengage_record_enable (); diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h index 1c00289003..d4fec52609 100644 --- a/libs/ardour/ardour/midi_source.h +++ b/libs/ardour/ardour/midi_source.h @@ -59,8 +59,10 @@ class MidiSource : public Source static sigc::signal<void,MidiSource*> MidiSourceCreated; - mutable sigc::signal<void> PeaksReady; - mutable sigc::signal<void,jack_nframes_t,jack_nframes_t> PeakRangeReady; + // The MIDI equivalent to "peaks" + static int start_view_data_thread (); + static void stop_view_data_thread (); + mutable sigc::signal<void,jack_nframes_t,jack_nframes_t> ViewDataRangeReady; XMLNode& get_state (); int set_state (const XMLNode&); diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 9274cfbcf6..654eb98e30 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -53,8 +53,6 @@ public: jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick, bool meter); - void set_record_enable (bool yn, void *src); - MidiDiskstream& midi_diskstream() const; int use_diskstream (string name); @@ -75,8 +73,6 @@ public: int set_state(const XMLNode& node); - bool record_enabled() const; - protected: XMLNode& state (bool full); diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index b389258860..59fd0f8bc5 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -39,6 +39,7 @@ #include <ardour/crossfade_compare.h> #include <ardour/location.h> #include <ardour/state_manager.h> +#include <ardour/data_type.h> namespace ARDOUR { @@ -49,8 +50,8 @@ class Playlist : public Stateful, public StateManager { public: typedef list<Region*> RegionList; - Playlist (Session&, const XMLNode&, bool hidden = false); - Playlist (Session&, string name, bool hidden = false); + Playlist (Session&, const XMLNode&, DataType type, bool hidden = false); + Playlist (Session&, string name, DataType type, bool hidden = false); Playlist (const Playlist&, string name, bool hidden = false); Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false); @@ -65,6 +66,8 @@ class Playlist : public Stateful, public StateManager { const string& name() const { return _name; } void set_name (const string& str); + const DataType& data_type() const { return _type; } + bool frozen() const { return _frozen; } void set_frozen (bool yn); @@ -171,6 +174,7 @@ class Playlist : public Stateful, public StateManager { RegionList regions; string _name; Session& _session; + DataType _type; mutable gint block_notifications; mutable gint ignore_state_changes; mutable Glib::Mutex region_lock; @@ -275,7 +279,7 @@ class Playlist : public Stateful, public StateManager { void timestamp_layer_op (Region&); - PBD::ID _id; + PBD::ID _id; }; } /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index c0ff8be607..80504ce044 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -27,6 +27,7 @@ #include <ardour/ardour.h> #include <ardour/state_manager.h> +#include <ardour/data_type.h> class XMLNode; @@ -94,9 +95,9 @@ class Region : public Stateful, public StateManager static Change HiddenChanged; Region (Source& src, jack_nframes_t start, jack_nframes_t length, - const string& name, layer_t = 0, Flag flags = DefaultFlags); + const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags); Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, - const string& name, layer_t = 0, Flag flags = DefaultFlags); + const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags); Region (const Region&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags); Region (const Region&); @@ -111,6 +112,8 @@ class Region : public Stateful, public StateManager string name() const { return _name; } void set_name (string str); + const DataType& data_type() const { return _type; } + jack_nframes_t position () const { return _position; } jack_nframes_t start () const { return _start; } jack_nframes_t length() const { return _length; } @@ -251,7 +254,8 @@ class Region : public Stateful, public StateManager PBD::ID _id; - string _name; + string _name; + DataType _type; Flag _flags; jack_nframes_t _start; jack_nframes_t _length; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index a9b8cbf290..2737d86a3f 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -632,8 +632,8 @@ class Session : public sigc::trackable, public Stateful /* region info */ - sigc::signal<void,AudioRegion *> AudioRegionAdded; - sigc::signal<void,AudioRegion *> AudioRegionRemoved; + sigc::signal<void,Region *> RegionAdded; + sigc::signal<void,Region *> RegionRemoved; int region_name (string& result, string base = string(""), bool newlevel = false) const; string new_region_name (string); @@ -642,9 +642,11 @@ class Session : public sigc::trackable, public Stateful Region* find_whole_file_parent (Region& child); void find_equivalent_playlist_regions (Region&, std::vector<Region*>& result); - AudioRegion *XMLRegionFactory (const XMLNode&, bool full); + Region* XMLRegionFactory (const XMLNode&, bool full); + AudioRegion* XMLAudioRegionFactory (const XMLNode&, bool full); + MidiRegion* XMLMidiRegionFactory (const XMLNode&, bool full); - template<class T> void foreach_audio_region (T *obj, void (T::*func)(AudioRegion *)); + template<class T> void foreach_region (T *obj, void (T::*func)(Region *)); /* source management */ @@ -658,7 +660,7 @@ class Session : public sigc::trackable, public Stateful string pathname; /* result */ - std::vector<AudioRegion*> new_regions; + std::vector<Region*> new_regions; }; @@ -672,7 +674,7 @@ class Session : public sigc::trackable, public Stateful int start_audio_export (ARDOUR::AudioExportSpecification&); int stop_audio_export (ARDOUR::AudioExportSpecification&); - void add_audio_source (AudioSource *); + void add_source (Source *); void remove_source (Source *); int cleanup_audio_file_source (AudioFileSource&); @@ -1551,8 +1553,8 @@ class Session : public sigc::trackable, public Stateful /* REGION MANAGEMENT */ mutable Glib::Mutex region_lock; - typedef map<PBD::ID,AudioRegion *> AudioRegionList; - AudioRegionList audio_regions; + typedef map<PBD::ID,Region *> RegionList; + RegionList regions; void region_renamed (Region *); void region_changed (Change, Region *); @@ -1563,10 +1565,10 @@ class Session : public sigc::trackable, public Stateful /* SOURCES */ - mutable Glib::Mutex audio_source_lock; - typedef std::map<PBD::ID,AudioSource *> AudioSourceList; + mutable Glib::Mutex source_lock; + typedef std::map<PBD::ID,Source *> SourceList; - AudioSourceList audio_sources; + SourceList sources; int load_sources (const XMLNode& node); XMLNode& get_sources_as_xml (); diff --git a/libs/ardour/ardour/session_region.h b/libs/ardour/ardour/session_region.h index 4f0fb92e3b..fae950baa6 100644 --- a/libs/ardour/ardour/session_region.h +++ b/libs/ardour/ardour/session_region.h @@ -6,10 +6,10 @@ namespace ARDOUR { -template<class T> void Session::foreach_audio_region (T *obj, void (T::*func)(AudioRegion *)) +template<class T> void Session::foreach_region (T *obj, void (T::*func)(Region *)) { Glib::Mutex::Lock lm (region_lock); - for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); i++) { + for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) { (obj->*func) (i->second); } } diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h index 83bc47d7d3..abb52456e3 100644 --- a/libs/ardour/ardour/smf_source.h +++ b/libs/ardour/ardour/smf_source.h @@ -48,6 +48,16 @@ class SMFSource : public MidiSource { virtual ~SMFSource (); + /* this block of methods do nothing for regular file sources, but are significant + for files used in destructive recording. + */ + // FIXME and thus are useless for MIDI.. but make MidiDiskstream compile easier! :) + + virtual jack_nframes_t last_capture_start_frame() const { return 0; } + virtual void mark_capture_start (jack_nframes_t) {} + virtual void mark_capture_end () {} + virtual void clear_capture_marks() {} + int set_name (string newname, bool destructive); string path() const { return _path; } diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index dc1e93f8f2..a8d0fed20b 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -28,13 +28,14 @@ #include <pbd/stateful.h> #include <ardour/ardour.h> +#include <ardour/data_type.h> namespace ARDOUR { class Source : public Stateful, public sigc::trackable { public: - Source (std::string name); + Source (std::string name, DataType type); Source (const XMLNode&); virtual ~Source (); @@ -60,12 +61,14 @@ class Source : public Stateful, public sigc::trackable XMLNode& get_state (); int set_state (const XMLNode&); + static sigc::signal<void,Source*> SourceCreated; sigc::signal<void,Source *> GoingAway; protected: void update_length (jack_nframes_t pos, jack_nframes_t cnt); string _name; + DataType _type; uint32_t _use_cnt; time_t _timestamp; jack_nframes_t _length; diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index 4fc7cf4326..15a0a28aab 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -48,7 +48,7 @@ class Track : public Route void toggle_monitor_input (); - virtual bool can_record(); + bool can_record(); Diskstream& diskstream() const { return *_diskstream; } diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 6973ebd877..784a14bb2b 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -280,7 +280,8 @@ AudioDiskstream::get_input_sources () chan.source = 0; } else { - chan.source = _session.engine().get_port_by_name (connections[0]); + chan.source = dynamic_cast<AudioPort*>( + _session.engine().get_port_by_name (connections[0]) ); } if (connections) { diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index 328c9b25f5..b621e587e9 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -44,8 +44,11 @@ AudioPlaylist::State::~State () } AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden) - : Playlist (session, node, hidden) + : Playlist (session, node, DataType::AUDIO, hidden) { + const XMLProperty* prop = node.property("type"); + assert(!prop || DataType(prop->value()) == DataType::AUDIO); + in_set_state = true; set_state (node); in_set_state = false; @@ -58,7 +61,7 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden } AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden) - : Playlist (session, name, hidden) + : Playlist (session, name, DataType::AUDIO, hidden) { save_state (_("initial state")); diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 6b810c04ec..052049cda7 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -66,7 +66,7 @@ AudioRegionState::AudioRegionState (string why) /** Basic AudioRegion constructor (one channel) */ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, bool announce) - : Region (src, start, length, PBD::basename_nosuffix(src.name()), 0, Region::Flag(Region::DefaultFlags|Region::External)) + : Region (src, start, length, PBD::basename_nosuffix(src.name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External)) , _fade_in (0.0, 2.0, 1.0, false) , _fade_out (0.0, 2.0, 1.0, false) , _envelope (0.0, 2.0, 1.0, false) @@ -87,7 +87,7 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t /* Basic AudioRegion constructor (one channel) */ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce) - : Region (src, start, length, name, layer, flags) + : Region (src, start, length, name, DataType::AUDIO, layer, flags) , _fade_in (0.0, 2.0, 1.0, false) , _fade_out (0.0, 2.0, 1.0, false) , _envelope (0.0, 2.0, 1.0, false) @@ -107,7 +107,7 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t /* Basic AudioRegion constructor (many channels) */ AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce) - : Region (srcs, start, length, name, layer, flags) + : Region (srcs, start, length, name, DataType::AUDIO, layer, flags) , _fade_in (0.0, 2.0, 1.0, false) , _fade_out (0.0, 2.0, 1.0, false) , _envelope (0.0, 2.0, 1.0, false) @@ -204,6 +204,8 @@ AudioRegion::AudioRegion (AudioSource& src, const XMLNode& node) _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); + assert(_type == DataType::AUDIO); + CheckNewRegion (this); /* EMIT SIGNAL */ } @@ -224,6 +226,8 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node) _envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); + assert(_type == DataType::AUDIO); + CheckNewRegion (this); /* EMIT SIGNAL */ } diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index bf97ef848a..9620565ae2 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -40,7 +40,6 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -sigc::signal<void,AudioSource *> AudioSource::AudioSourceCreated; pthread_t AudioSource::peak_thread; bool AudioSource::have_peak_thread = false; vector<AudioSource*> AudioSource::pending_peak_sources; @@ -51,7 +50,7 @@ bool AudioSource::_build_missing_peakfiles = false; bool AudioSource::_build_peakfiles = false; AudioSource::AudioSource (string name) - : Source (name) + : Source (name, DataType::AUDIO) { if (pending_peak_sources_lock == 0) { pending_peak_sources_lock = new Glib::Mutex; diff --git a/libs/ardour/buffer.cc b/libs/ardour/buffer.cc index 85b9317f78..fa4669cef6 100644 --- a/libs/ardour/buffer.cc +++ b/libs/ardour/buffer.cc @@ -101,8 +101,8 @@ MidiBuffer::read_from(const Buffer& src, jack_nframes_t nframes, jack_nframes_t } assert(_size == msrc.size()); - if (_size > 0) - std::cerr << "MidiBuffer wrote " << _size << " events.\n"; + //if (_size > 0) + // std::cerr << "MidiBuffer wrote " << _size << " events.\n"; } diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc index f0fcac14e2..d2a9a8c8e6 100644 --- a/libs/ardour/coreaudiosource.cc +++ b/libs/ardour/coreaudiosource.cc @@ -32,7 +32,7 @@ CoreAudioSource::CoreAudioSource (const XMLNode& node) { init (_name); - AudioSourceCreated (this); /* EMIT SIGNAL */ + SourceCreated (this); /* EMIT SIGNAL */ } CoreAudioSource::CoreAudioSource (const string& idstr, Flag flags) @@ -40,7 +40,7 @@ CoreAudioSource::CoreAudioSource (const string& idstr, Flag flags) { init (idstr); - AudioSourceCreated (this); /* EMIT SIGNAL */ + SourceCreated (this); /* EMIT SIGNAL */ } void diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index c68eb16aae..6d98388941 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -262,7 +262,7 @@ Session::import_audiofile (import_status& status) } if (status.cancel) { - for (vector<AudioRegion *>::iterator i = status.new_regions.begin(); i != status.new_regions.end(); ++i) { + for (vector<Region *>::iterator i = status.new_regions.begin(); i != status.new_regions.end(); ++i) { delete *i; } diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 948afd149b..2c88d5daa8 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -35,6 +35,7 @@ #include <pbd/basename.h> #include <glibmm/thread.h> #include <pbd/xml++.h> +#include <pbd/memento_command.h> #include <ardour/ardour.h> #include <ardour/audioengine.h> @@ -77,6 +78,7 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F in_set_state = false; + assert(!destructive()); DiskstreamCreated (this); /* EMIT SIGNAL */ } @@ -129,6 +131,8 @@ MidiDiskstream::init (Diskstream::Flag f) _capture_transition_buf = new RingBufferNPT<CaptureTransition> (128); _n_channels = ChanCount(DataType::MIDI, 1); + + assert(recordable()); } MidiDiskstream::~MidiDiskstream () @@ -181,20 +185,18 @@ MidiDiskstream::non_realtime_input_change () void MidiDiskstream::get_input_sources () { -#if 0 - if (_io->n_inputs() == 0) { - cerr << "MidiDiskstream NO INPUTS?\n"; + uint32_t ni = _io->n_inputs().get(DataType::MIDI); + + if (ni == 0) { return; - } else { - cerr << "INPUTS!\n"; } - // FIXME this is weird and really different from AudioDiskstream - - assert(_io->n_inputs() == 1); - assert(_io->midi_input(0)); + // This is all we do for now at least + assert(ni == 1); + _source_port = _io->midi_input(0); + /* I don't get it.... const char **connections = _io->input(0)->get_connections (); if (connections == 0 || connections[0] == 0) { @@ -207,20 +209,12 @@ MidiDiskstream::get_input_sources () } else { _source_port = dynamic_cast<MidiPort*>( - _session.engine().get_port_by_name (connections[0])); - assert(_source_port); - } - - if (_source_port) { - cerr << "SOURCE PORT!\n"; - } else { - cerr << "NO SOURCE PORT?!\n"; + _session.engine().get_port_by_name (connections[0]) ); } if (connections) { free (connections); - } -#endif + }*/ } int @@ -299,46 +293,13 @@ MidiDiskstream::use_copy_playlist () } } +/** Overloaded from parent to die horribly + */ void -MidiDiskstream::setup_destructive_playlist () +MidiDiskstream::set_destructive (bool yn) { - Region::SourceList srcs; - - srcs.push_back (_write_source); - /* a single full-sized region */ - - cerr << "Setup MIDI DS using " << srcs.front()->natural_position () << endl; - - MidiRegion* region = new MidiRegion (srcs, 0, max_frames, _name); - _playlist->add_region (*region, srcs.front()->natural_position()); -} - -void -MidiDiskstream::use_destructive_playlist () -{ - /* use the sources associated with the single full-extent region */ - - Playlist::RegionList* rl = _playlist->regions_at (0); - - if (rl->empty()) { - reset_write_sources (false, true); - return; - } - - MidiRegion* region = dynamic_cast<MidiRegion*> (rl->front()); - - if (region == 0) { - throw failed_constructor(); - } - - delete rl; - - assert(region->n_channels() == 1); - _write_source = dynamic_cast<SMFSource*>(®ion->source (0)); - assert(_write_source); - _write_source->set_allow_remove_if_empty (false); - - /* the source list will never be reset for a destructive track */ + assert( ! destructive()); + assert( ! yn); } void @@ -587,8 +548,8 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, cerr << "DISKSTREAM GOT EVENT " << i << "!!\n"; } - if (_source_port->size() == 0) - cerr << "No events :/ (1)\n"; + //if (_source_port->size() == 0) + // cerr << "No events :/ (1)\n"; } else { @@ -607,8 +568,8 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, for (size_t i=0; i < _source_port->size(); ++i) { cerr << "DISKSTREAM GOT EVENT " << i << "!!\n"; } - if (_source_port->size() == 0) - cerr << "No events :/ (2)\n"; + //if (_source_port->size() == 0) + // cerr << "No events :/ (2)\n"; RawMidi* buf = NULL; // FIXME FIXME FIXME (make it compile) assert(false); jack_nframes_t first = _capture_vector.len[0]; @@ -630,6 +591,10 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, if (rec_nframes) { + // FIXME: filthy hack to fool the GUI into thinking we're doing something + if (_write_source) + _write_source->ViewDataRangeReady (transport_frame, rec_nframes); /* EMIT SIGNAL */ + /* data will be written to disk */ if (rec_nframes == nframes && rec_offset == 0) { @@ -687,9 +652,9 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t total = _playback_vector.len[0] + _playback_vector.len[1]; if (necessary_samples > total) { - cerr << "DiskUnderrun\n"; + //cerr << "DiskUnderrun\n"; //DiskUnderrun (); // FIXME - goto out; + //goto out; } else { @@ -758,12 +723,46 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, } return ret; + + _processed = true; + + return 0; } bool MidiDiskstream::commit (jack_nframes_t nframes) { - return 0; + bool need_butler = false; + + if (_actual_speed < 0.0) { + playback_sample -= playback_distance; + } else { + playback_sample += playback_distance; + } + + _playback_buf->increment_read_ptr (playback_distance); + + if (adjust_capture_position) { + _capture_buf->increment_write_ptr (adjust_capture_position); + } + + if (adjust_capture_position != 0) { + capture_captured += adjust_capture_position; + adjust_capture_position = 0; + } + + if (_slaved) { + need_butler = _playback_buf->write_space() >= _playback_buf->bufsize() / 2; + } else { + need_butler = _playback_buf->write_space() >= disk_io_chunk_frames + || _capture_buf->read_space() >= disk_io_chunk_frames; + } + + state_lock.unlock(); + + _processed = false; + + return need_butler; } void @@ -786,6 +785,7 @@ MidiDiskstream::overwrite_existing_buffers () int MidiDiskstream::seek (jack_nframes_t frame, bool complete_refill) { + Glib::Mutex::Lock lm (state_lock); return 0; } @@ -810,12 +810,13 @@ MidiDiskstream::read (RawMidi* buf, jack_nframes_t& start, jack_nframes_t cnt, b int MidiDiskstream::do_refill_with_alloc () { - return 0; + return do_refill(); } int MidiDiskstream::do_refill () { + // yeah, the data's ready. promise. return 0; } @@ -832,17 +833,198 @@ MidiDiskstream::do_refill () int MidiDiskstream::do_flush (Session::RunContext context, bool force_flush) { + /* hey, so did you write that data? */ + + // oh yeah, you bet. wrote it good. honest. + return 0; } void MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture) { + uint32_t buffer_position; + bool more_work = true; + int err = 0; + MidiRegion* region = 0; + jack_nframes_t total_capture; + MidiRegion::SourceList srcs; + MidiRegion::SourceList::iterator src; + vector<CaptureInfo*>::iterator ci; + bool mark_write_completed = false; + + finish_capture (true); + + /* butler is already stopped, but there may be work to do + to flush remaining data to disk. + */ + + while (more_work && !err) { + switch (do_flush (Session::TransportContext, true)) { + case 0: + more_work = false; + break; + case 1: + break; + case -1: + error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg; + err++; + } + } + + /* XXX is there anything we can do if err != 0 ? */ + Glib::Mutex::Lock lm (capture_info_lock); + + if (capture_info.empty()) { + return; + } + + if (abort_capture) { + + list<Source*>* deletion_list = new list<Source*>; + + if (_write_source) { + _write_source->mark_for_remove (); + _write_source->release (); + + deletion_list->push_back (_write_source); + + _write_source = 0; + } + + /* new source set up in "out" below */ + + if (!deletion_list->empty()) { + DeleteSources (deletion_list); + } else { + delete deletion_list; + } + + } else { + + assert(_write_source); + + for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) { + total_capture += (*ci)->frames; + } + + /* figure out the name for this take */ + + SMFSource* s = _write_source; + + if (s) { + + srcs.push_back (s); + + cerr << "MidiDiskstream: updating source after capture\n"; + s->update_header (capture_info.front()->start, when, twhen); + + s->set_captured_for (_name); + + } + + /* Register a new region with the Session that + describes the entire source. Do this first + so that any sub-regions will obviously be + children of this one (later!) + */ + try { + assert(_write_source); + region = new MidiRegion (srcs, _write_source->last_capture_start_frame(), total_capture, + region_name_from_path (_write_source->name()), + 0, Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)); + + region->special_set_position (capture_info.front()->start); + } + + + catch (failed_constructor& err) { + error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg; + /* XXX what now? */ + } + + _last_capture_regions.push_back (region); + + // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n"; + + XMLNode &before = _playlist->get_state(); + _playlist->freeze (); + + for (buffer_position = _write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) { + + string region_name; + _session.region_name (region_name, _write_source->name(), false); + + // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n"; + + try { + region = new MidiRegion (srcs, buffer_position, (*ci)->frames, region_name); + } + + catch (failed_constructor& err) { + error << _("MidiDiskstream: could not create region for captured audio!") << endmsg; + continue; /* XXX is this OK? */ + } + + _last_capture_regions.push_back (region); + + // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl; + + i_am_the_modifier++; + _playlist->add_region (*region, (*ci)->start); + i_am_the_modifier--; + + buffer_position += (*ci)->frames; + } + + _playlist->thaw (); + XMLNode &after = _playlist->get_state(); + _session.add_command (new MementoCommand<Playlist>(*_playlist, before, after)); + + mark_write_completed = true; + + reset_write_sources (mark_write_completed); + + } + + for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) { + delete *ci; + } + + capture_info.clear (); + capture_start_frame = 0; } void MidiDiskstream::finish_capture (bool rec_monitors_input) { + was_recording = false; + + if (capture_captured == 0) { + return; + } + + // Why must we destroy? + assert(!destructive()); + + CaptureInfo* ci = new CaptureInfo; + + ci->start = capture_start_frame; + ci->frames = capture_captured; + + /* XXX theoretical race condition here. Need atomic exchange ? + However, the circumstances when this is called right + now (either on record-disable or transport_stopped) + mean that no actual race exists. I think ... + We now have a capture_info_lock, but it is only to be used + to synchronize in the transport_stop and the capture info + accessors, so that invalidation will not occur (both non-realtime). + */ + + // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl; + + capture_info.push_back (ci); + capture_captured = 0; } void @@ -852,12 +1034,8 @@ MidiDiskstream::set_record_enabled (bool yn) return; } - /* can't rec-enable in destructive mode if transport is before start */ - - if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) { - return; - } - + assert(!destructive()); + if (yn && _source_port == 0) { /* pick up connections not initiated *from* the IO object @@ -1014,11 +1192,7 @@ MidiDiskstream::set_state (const XMLNode& node) _playlist->set_orig_diskstream_id (_id); } - if (!destructive() && capture_pending_node) { - /* destructive streams have one and only one source per channel, - and so they never end up in pending capture in any useful - sense. - */ + if (capture_pending_node) { use_pending_capture_data (*capture_pending_node); } @@ -1083,10 +1257,7 @@ MidiDiskstream::use_new_write_source (uint32_t n) } _write_source->use (); - - /* do not remove destructive files even if they are empty */ - - _write_source->set_allow_remove_if_empty (!destructive()); + _write_source->set_allow_remove_if_empty (true); return 0; } @@ -1098,29 +1269,11 @@ MidiDiskstream::reset_write_sources (bool mark_write_complete, bool force) return; } - if (!destructive()) { - - if (_write_source && mark_write_complete) { - _write_source->mark_streaming_write_completed (); - } - use_new_write_source (); - - } else { - if (_write_source == 0) { - use_new_write_source (); - } - } - - if (destructive()) { - - /* we now have all our write sources set up, so create the - playlist's single region. - */ - - if (_playlist->empty()) { - setup_destructive_playlist (); - } + if (_write_source && mark_write_complete) { + _write_source->mark_streaming_write_completed (); } + use_new_write_source (); + assert(_write_source); } int diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc index db28c06f17..443c5b57bf 100644 --- a/libs/ardour/midi_playlist.cc +++ b/libs/ardour/midi_playlist.cc @@ -43,8 +43,11 @@ MidiPlaylist::State::~State () {} MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden) - : Playlist (session, node, hidden) + : Playlist (session, node, DataType::MIDI, hidden) { + const XMLProperty* prop = node.property("type"); + assert(prop && DataType(prop->value()) == DataType::MIDI); + in_set_state = true; set_state (node); in_set_state = false; @@ -57,7 +60,7 @@ MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden) } MidiPlaylist::MidiPlaylist (Session& session, string name, bool hidden) - : Playlist (session, name, hidden) + : Playlist (session, name, DataType::MIDI, hidden) { save_state (_("initial state")); @@ -70,6 +73,7 @@ MidiPlaylist::MidiPlaylist (Session& session, string name, bool hidden) MidiPlaylist::MidiPlaylist (const MidiPlaylist& other, string name, bool hidden) : Playlist (other, name, hidden) { + throw; // nope save_state (_("initial state")); /* @@ -246,6 +250,7 @@ MidiPlaylist::refresh_dependents (Region& r) void MidiPlaylist::finalize_split_region (Region *o, Region *l, Region *r) { + throw; // I don't wanna /* MidiRegion *orig = dynamic_cast<MidiRegion*>(o); MidiRegion *left = dynamic_cast<MidiRegion*>(l); @@ -333,20 +338,18 @@ MidiPlaylist::check_dependents (Region& r, bool norefresh) int MidiPlaylist::set_state (const XMLNode& node) { - /* - XMLNode *child; - XMLNodeList nlist; - XMLNodeConstIterator niter; - if (!in_set_state) { Playlist::set_state (node); } - nlist = node.children(); + // Actually Charles, I don't much care for children + + /* + XMLNodeList nlist = node.children(); - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { + for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) { - child = *niter; + XMLNode* const child = *niter; }*/ diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index 0902337030..5b8a49049e 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -48,7 +48,7 @@ using namespace ARDOUR; /** Basic MidiRegion constructor (one channel) */ MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t length, bool announce) - : Region (src, start, length, PBD::basename_nosuffix(src.name()), 0, Region::Flag(Region::DefaultFlags|Region::External)) + : Region (src, start, length, PBD::basename_nosuffix(src.name()), DataType::MIDI, 0, Region::Flag(Region::DefaultFlags|Region::External)) { save_state ("initial state"); @@ -59,7 +59,7 @@ MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t le /* Basic MidiRegion constructor (one channel) */ MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce) - : Region (src, start, length, name, layer, flags) + : Region (src, start, length, name, DataType::MIDI, layer, flags) { save_state ("initial state"); @@ -70,7 +70,7 @@ MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t le /* Basic MidiRegion constructor (many channels) */ MidiRegion::MidiRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce) - : Region (srcs, start, length, name, layer, flags) + : Region (srcs, start, length, name, DataType::MIDI, layer, flags) { save_state ("initial state"); @@ -108,6 +108,8 @@ MidiRegion::MidiRegion (MidiSource& src, const XMLNode& node) save_state ("initial state"); + assert(_type == DataType::MIDI); + CheckNewRegion (this); /* EMIT SIGNAL */ } @@ -120,6 +122,8 @@ MidiRegion::MidiRegion (SourceList& srcs, const XMLNode& node) save_state ("initial state"); + assert(_type == DataType::MIDI); + CheckNewRegion (this); /* EMIT SIGNAL */ } @@ -332,6 +336,8 @@ MidiRegion::separate_by_channel (Session& session, vector<MidiRegion*>& v) const v.push_back (new MidiRegion (srcs, _start, _length, new_name, _layer, _flags)); } #endif + + // Actually, I would prefer not if that's alright return -1; } diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index 4cda0f6ebd..6728231de6 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -42,7 +42,7 @@ using namespace PBD; sigc::signal<void,MidiSource *> MidiSource::MidiSourceCreated; MidiSource::MidiSource (string name) - : Source (name) + : Source (name, DataType::MIDI) { _read_data_count = 0; _write_data_count = 0; diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index cdbd441cd6..470759f3ac 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -129,44 +129,6 @@ MidiTrack::use_diskstream (const PBD::ID& id) return set_diskstream (*dstream); } -bool -MidiTrack::record_enabled () const -{ - return _diskstream->record_enabled (); -} - -void -MidiTrack::set_record_enable (bool yn, void *src) -{ - if (_freeze_record.state == Frozen) { - return; - } -#if 0 - if (_mix_group && src != _mix_group && _mix_group->is_active()) { - _mix_group->apply (&MidiTrack::set_record_enable, yn, _mix_group); - return; - } - - /* keep track of the meter point as it was before we rec-enabled */ - - if (!diskstream->record_enabled()) { - _saved_meter_point = _meter_point; - } - - diskstream->set_record_enabled (yn, src); - - if (diskstream->record_enabled()) { - set_meter_point (MeterInput, this); - } else { - set_meter_point (_saved_meter_point, this); - } - - if (_session.get_midi_feedback()) { - _midi_rec_enable_control.send_feedback (record_enabled()); - } -#endif -} - MidiDiskstream& MidiTrack::midi_diskstream() const { @@ -482,7 +444,109 @@ int MidiTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input) { - passthru (start_frame, end_frame, nframes, offset, declick, false); + //passthru (start_frame, end_frame, nframes, offset, declick, false); + int dret; + RawMidi* b; // FIXME: this won't work, duh + //Sample* tmpb; + jack_nframes_t transport_frame; + MidiDiskstream& diskstream = midi_diskstream(); + + { + Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK); + if (lm.locked()) { + // automation snapshot can also be called from the non-rt context + // and it uses the redirect list, so we take the lock out here + automation_snapshot (start_frame); + } + } + + if (n_outputs().get_total() == 0 && _redirects.empty()) { + return 0; + } + + if (!_active) { + silence (nframes, offset); + return 0; + } + + transport_frame = _session.transport_frame(); + + if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) { + /* need to do this so that the diskstream sets its + playback distance to zero, thus causing diskstream::commit + to do nothing. + */ + return diskstream.process (transport_frame, 0, 0, can_record, rec_monitors_input); + } + + _silent = false; + //apply_gain_automation = false; + + if ((dret = diskstream.process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) { + + silence (nframes, offset); + + return dret; + } + + /* special condition applies */ + + if (_meter_point == MeterInput) { + just_meter_input (start_frame, end_frame, nframes, offset); + } + + if (diskstream.record_enabled() && !can_record && !_session.get_auto_input()) { + + /* not actually recording, but we want to hear the input material anyway, + at least potentially (depending on monitoring options) + */ + + passthru (start_frame, end_frame, nframes, offset, 0, true); + + } else if ((b = diskstream.playback_buffer()) != 0) { + /* + XXX is it true that the earlier test on n_outputs() + means that we can avoid checking it again here? i think + so, because changing the i/o configuration of an IO + requires holding the AudioEngine lock, which we hold + while in the process() tree. + */ + + + /* copy the diskstream data to all output buffers */ + + //const size_t limit = n_process_buffers().get(DataType::AUDIO); + BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers()); + + //uint32_t n; + //uint32_t i; +#if 0 + for (i = 0, n = 1; i < limit; ++i, ++n) { + memcpy (bufs.get_audio(i).data(nframes), b, sizeof (Sample) * nframes); + if (n < diskstream.n_channels().get(DataType::AUDIO)) { + tmpb = diskstream.playback_buffer(n); + if (tmpb!=0) { + b = tmpb; + } + } + } + + /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */ + + if (!diskstream.record_enabled() && _session.transport_rolling()) { + Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK); + + if (am.locked() && gain_automation_playback()) { + apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes); + } + } +#endif + process_output_buffers (bufs, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !_session.get_do_not_record_plugins()), declick, (_meter_point != MeterInput)); + + } else { + /* problem with the diskstream; just be quiet for a bit */ + silence (nframes, offset); + } return 0; } @@ -571,6 +635,7 @@ MidiTrack::set_latency_delay (jack_nframes_t longest_session_latency) void MidiTrack::bounce (InterThreadInfo& itt) { + throw; //vector<MidiSource*> srcs; //_session.write_one_midi_track (*this, 0, _session.current_end_frame(), false, srcs, itt); } @@ -579,6 +644,7 @@ MidiTrack::bounce (InterThreadInfo& itt) void MidiTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt) { + throw; //vector<MidiSource*> srcs; //_session.write_one_midi_track (*this, start, end, false, srcs, itt); } diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 6d5e8f7847..61aa5c587a 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -72,17 +72,22 @@ struct RegionSortByLastLayerOp { } }; -Playlist::Playlist (Session& sess, string nom, bool hide) +Playlist::Playlist (Session& sess, string nom, DataType type, bool hide) : _session (sess) + , _type(type) { init (hide); _name = nom; } -Playlist::Playlist (Session& sess, const XMLNode& node, bool hide) +Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide) : _session (sess) + , _type(type) { + const XMLProperty* prop = node.property("type"); + assert(!prop || DataType(prop->value()) == _type); + init (hide); _name = "unnamed"; /* reset by set_state */ @@ -92,7 +97,7 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide) } Playlist::Playlist (const Playlist& other, string namestr, bool hide) - : _name (namestr), _session (other._session), _orig_diskstream_id(other._orig_diskstream_id) + : _name (namestr), _session (other._session), _type(other._type), _orig_diskstream_id(other._orig_diskstream_id) { init (hide); @@ -125,7 +130,7 @@ Playlist::Playlist (const Playlist& other, string namestr, bool hide) } Playlist::Playlist (const Playlist& other, jack_nframes_t start, jack_nframes_t cnt, string str, bool hide) - : _name (str), _session (other._session), _orig_diskstream_id(other._orig_diskstream_id) + : _name (str), _session (other._session), _type(other._type), _orig_diskstream_id(other._orig_diskstream_id) { RegionLock rlock2 (&((Playlist&)other)); @@ -247,12 +252,14 @@ Playlist::init (bool hide) Playlist::Playlist (const Playlist& pl) : _session (pl._session) + , _type(pl.data_type()) { fatal << _("playlist const copy constructor called") << endmsg; } Playlist::Playlist (Playlist& pl) : _session (pl._session) + , _type(pl.data_type()) { fatal << _("playlist non-const copy constructor called") << endmsg; } @@ -1426,6 +1433,7 @@ Playlist::state (bool full_state) char buf[64]; node->add_property (X_("name"), _name); + node->add_property (X_("type"), _type.to_string()); _orig_diskstream_id.print (buf); node->add_property (X_("orig_diskstream_id"), buf); diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 03a4d1d2a3..3481ee3eea 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -51,8 +51,9 @@ Change Region::HiddenChanged = ARDOUR::new_change (); sigc::signal<void,Region *> Region::CheckNewRegion; /** Basic Region constructor (single source) */ -Region::Region (Source& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags) +Region::Region (Source& src, jack_nframes_t start, jack_nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) : _name(name) + , _type(type) , _flags(flags) , _start(start) , _length(length) @@ -76,8 +77,9 @@ Region::Region (Source& src, jack_nframes_t start, jack_nframes_t length, const } /** Basic Region constructor (many sources) */ -Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags) +Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) : _name(name) + , _type(type) , _flags(flags) , _start(start) , _length(length) @@ -114,6 +116,7 @@ Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, c /** Create a new Region from part of an existing one */ Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags) : _name(name) + , _type(other.data_type()) , _flags(Flag(flags & ~(Locked|WholeFile|Hidden))) , _start(other._start + offset) , _length(length) @@ -153,6 +156,7 @@ Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t lengt /** Pure copy constructor */ Region::Region (const Region &other) : _name(other._name) + , _type(other.data_type()) , _flags(Flag(other._flags & ~Locked)) , _start(other._start) , _length(other._length) @@ -196,6 +200,7 @@ Region::Region (const Region &other) Region::Region (SourceList& srcs, const XMLNode& node) : _name(X_("error: XML did not reset this")) + , _type(DataType::NIL) // to be loaded from XML , _flags(Flag(0)) , _start(0) , _length(0) @@ -230,12 +235,14 @@ Region::Region (SourceList& srcs, const XMLNode& node) if (set_state (node)) { throw failed_constructor(); } - + + assert(_type != DataType::NIL); assert(_sources.size() > 0); } Region::Region (Source& src, const XMLNode& node) : _name(X_("error: XML did not reset this")) + , _type(DataType::NIL) , _flags(Flag(0)) , _start(0) , _length(0) @@ -257,6 +264,7 @@ Region::Region (Source& src, const XMLNode& node) throw failed_constructor(); } + assert(_type != DataType::NIL); assert(_sources.size() > 0); } @@ -957,6 +965,7 @@ Region::state (bool full_state) _id.print (buf); node->add_property ("id", buf); node->add_property ("name", _name); + node->add_property ("type", _type.to_string()); snprintf (buf, sizeof (buf), "%u", _start); node->add_property ("start", buf); snprintf (buf, sizeof (buf), "%u", _length); @@ -1004,6 +1013,12 @@ Region::set_state (const XMLNode& node) } _name = prop->value(); + + if ((prop = node.property ("type")) == 0) { + _type = DataType::AUDIO; + } else { + _type = DataType(prop->value()); + } if ((prop = node.property ("start")) != 0) { _start = (jack_nframes_t) atoi (prop->value().c_str()); diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 9cfaf18cb0..33165574a8 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -431,10 +431,10 @@ Session::~Session () } #ifdef TRACK_DESTRUCTION - cerr << "delete audio regions\n"; + cerr << "delete regions\n"; #endif /* TRACK_DESTRUCTION */ - for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) { - AudioRegionList::iterator tmp; + for (RegionList::iterator i = regions.begin(); i != regions.end(); ) { + RegionList::iterator tmp; tmp =i; ++tmp; @@ -461,8 +461,8 @@ Session::~Session () #ifdef TRACK_DESTRUCTION cerr << "delete audio sources\n"; #endif /* TRACK_DESTRUCTION */ - for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) { - AudioSourceList::iterator tmp; + for (SourceList::iterator i = sources.begin(); i != sources.end(); ) { + SourceList::iterator tmp; tmp = i; ++tmp; @@ -2137,11 +2137,11 @@ Session::remove_route (shared_ptr<Route> route) /* writer goes out of scope, forces route list update */ } - AudioTrack* at; - AudioDiskstream* ds = 0; + Track* t; + Diskstream* ds = 0; - if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) { - ds = &at->audio_diskstream(); + if ((t = dynamic_cast<Track*>(route.get())) != 0) { + ds = &t->diskstream(); } if (ds) { @@ -2183,7 +2183,7 @@ Session::route_solo_changed (void* src, shared_ptr<Route> route) bool is_track; - is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0); + is_track = (dynamic_cast<Track*>(route.get()) != 0); shared_ptr<RouteList> r = routes.reader (); @@ -2195,7 +2195,7 @@ Session::route_solo_changed (void* src, shared_ptr<Route> route) /* don't mess with busses */ - if (dynamic_cast<AudioTrack*>((*i).get()) == 0) { + if (dynamic_cast<Track*>((*i).get()) == 0) { continue; } @@ -2203,7 +2203,7 @@ Session::route_solo_changed (void* src, shared_ptr<Route> route) /* don't mess with tracks */ - if (dynamic_cast<AudioTrack*>((*i).get()) != 0) { + if (dynamic_cast<Track*>((*i).get()) != 0) { continue; } } @@ -2239,7 +2239,7 @@ Session::route_solo_changed (void* src, shared_ptr<Route> route) for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->soloed()) { something_soloed = true; - if (dynamic_cast<AudioTrack*>((*i).get())) { + if (dynamic_cast<Track*>((*i).get())) { if (is_track) { same_thing_soloed = true; break; @@ -2296,7 +2296,7 @@ Session::update_route_solo_state () for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->soloed()) { mute = true; - if (dynamic_cast<AudioTrack*>((*i).get())) { + if (dynamic_cast<Track*>((*i).get())) { is_track = true; } break; @@ -2341,7 +2341,7 @@ Session::modify_solo_mute (bool is_track, bool mute) /* only alter track solo mute */ - if (dynamic_cast<AudioTrack*>((*i).get())) { + if (dynamic_cast<Track*>((*i).get())) { if ((*i)->soloed()) { (*i)->set_solo_mute (!mute); } else { @@ -2353,7 +2353,7 @@ Session::modify_solo_mute (bool is_track, bool mute) /* only alter bus solo mute */ - if (!dynamic_cast<AudioTrack*>((*i).get())) { + if (!dynamic_cast<Track*>((*i).get())) { if ((*i)->soloed()) { @@ -2506,7 +2506,7 @@ Session::new_region_name (string old) while (number < (UINT_MAX-1)) { - AudioRegionList::const_iterator i; + RegionList::const_iterator i; string sbuf; number++; @@ -2514,13 +2514,13 @@ Session::new_region_name (string old) snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number); sbuf = buf; - for (i = audio_regions.begin(); i != audio_regions.end(); ++i) { + for (i = regions.begin(); i != regions.end(); ++i) { if (i->second->name() == sbuf) { break; } } - if (i == audio_regions.end()) { + if (i == regions.end()) { break; } } @@ -2543,7 +2543,7 @@ Session::region_name (string& result, string base, bool newlevel) const Glib::Mutex::Lock lm (region_lock); - snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1); + snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1); result = "region."; @@ -2579,7 +2579,7 @@ Session::region_name (string& result, string base, bool newlevel) const name_taken = false; - for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) { + for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { if (i->second->name() == result) { name_taken = true; break; @@ -2603,62 +2603,48 @@ Session::region_name (string& result, string base, bool newlevel) const void Session::add_region (Region* region) { - AudioRegion* ar = 0; - AudioRegion* oar = 0; bool added = false; { Glib::Mutex::Lock lm (region_lock); - if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) { - - AudioRegionList::iterator x; + RegionList::iterator x; - for (x = audio_regions.begin(); x != audio_regions.end(); ++x) { + for (x = regions.begin(); x != regions.end(); ++x) { - oar = dynamic_cast<AudioRegion*> (x->second); - - if (ar->region_list_equivalent (*oar)) { - break; - } + if (region->region_list_equivalent (*x->second)) { + break; } + } - if (x == audio_regions.end()) { - - pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry; + if (x == regions.end()) { - entry.first = region->id(); - entry.second = ar; + pair<RegionList::key_type,RegionList::mapped_type> entry; - pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry); - - if (!x.second) { - return; - } + entry.first = region->id(); + entry.second = region; - added = true; - } + pair<RegionList::iterator,bool> x = regions.insert (entry); - } else { + if (!x.second) { + return; + } - fatal << _("programming error: ") - << X_("unknown region type passed to Session::add_region()") - << endmsg; - /*NOTREACHED*/ + added = true; + } - } } /* mark dirty because something has changed even if we didn't add the region to the region list. - */ - + */ + set_dirty(); - + if (added) { region->GoingAway.connect (mem_fun (*this, &Session::remove_region)); region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region)); - AudioRegionAdded (ar); /* EMIT SIGNAL */ + RegionAdded (region); /* EMIT SIGNAL */ } } @@ -2680,47 +2666,38 @@ Session::region_renamed (Region* region) void Session::remove_region (Region* region) { - AudioRegionList::iterator i; - AudioRegion* ar = 0; + RegionList::iterator i; bool removed = false; - + { Glib::Mutex::Lock lm (region_lock); - if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) { - if ((i = audio_regions.find (region->id())) != audio_regions.end()) { - audio_regions.erase (i); - removed = true; - } - - } else { - - fatal << _("programming error: ") - << X_("unknown region type passed to Session::remove_region()") - << endmsg; - /*NOTREACHED*/ + if ((i = regions.find (region->id())) != regions.end()) { + regions.erase (i); + removed = true; } + } /* mark dirty because something has changed even if we didn't remove the region from the region list. - */ + */ set_dirty(); if (removed) { - AudioRegionRemoved(ar); /* EMIT SIGNAL */ + RegionRemoved(region); /* EMIT SIGNAL */ } } Region* Session::find_whole_file_parent (Region& child) { - AudioRegionList::iterator i; - AudioRegion* region; + RegionList::iterator i; + Region* region; Glib::Mutex::Lock lm (region_lock); - for (i = audio_regions.begin(); i != audio_regions.end(); ++i) { + for (i = regions.begin(); i != regions.end(); ++i) { region = i->second; @@ -2812,17 +2789,16 @@ Session::remove_region_from_region_list (Region& r) } /* Source Management */ - void -Session::add_audio_source (AudioSource* source) +Session::add_source (Source* source) { - pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry; + pair<SourceList::key_type, SourceList::mapped_type> entry; { - Glib::Mutex::Lock lm (audio_source_lock); + Glib::Mutex::Lock lm (source_lock); entry.first = source->id(); entry.second = source; - audio_sources.insert (entry); + sources.insert (entry); } source->GoingAway.connect (mem_fun (this, &Session::remove_source)); @@ -2834,13 +2810,13 @@ Session::add_audio_source (AudioSource* source) void Session::remove_source (Source* source) { - AudioSourceList::iterator i; + SourceList::iterator i; { - Glib::Mutex::Lock lm (audio_source_lock); + Glib::Mutex::Lock lm (source_lock); - if ((i = audio_sources.find (source->id())) != audio_sources.end()) { - audio_sources.erase (i); + if ((i = sources.find (source->id())) != sources.end()) { + sources.erase (i); } } @@ -2860,11 +2836,11 @@ Session::remove_source (Source* source) Source * Session::source_by_id (const PBD::ID& id) { - Glib::Mutex::Lock lm (audio_source_lock); - AudioSourceList::iterator i; + Glib::Mutex::Lock lm (source_lock); + SourceList::iterator i; Source* source = 0; - if ((i = audio_sources.find (id)) != audio_sources.end()) { + if ((i = sources.find (id)) != sources.end()) { source = i->second; } @@ -3479,9 +3455,9 @@ Session::record_enable_change_all (bool yn) shared_ptr<RouteList> r = routes.reader (); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - AudioTrack* at; + Track* at; - if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) { + if ((at = dynamic_cast<Track*>((*i).get())) != 0) { at->set_record_enable (yn, this); } } @@ -3791,9 +3767,9 @@ Session::freeze (InterThreadInfo& itt) for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - AudioTrack *at; + Track *at; - if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) { + if ((at = dynamic_cast<Track*>((*i).get())) != 0) { /* XXX this is wrong because itt.progress will keep returning to zero at the start of every track. */ @@ -3986,7 +3962,7 @@ Session::ntracks () const shared_ptr<RouteList> r = routes.reader (); for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { - if (dynamic_cast<AudioTrack*> ((*i).get())) { + if (dynamic_cast<Track*> ((*i).get())) { ++n; } } @@ -4001,7 +3977,7 @@ Session::nbusses () const shared_ptr<RouteList> r = routes.reader (); for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { - if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) { + if (dynamic_cast<Track*> ((*i).get()) == 0) { ++n; } } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 2a08859205..5e96a8ca8a 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -63,8 +63,11 @@ #include <ardour/midi_diskstream.h> #include <ardour/utils.h> #include <ardour/audioplaylist.h> +#include <ardour/midi_playlist.h> +#include <ardour/smf_source.h> #include <ardour/audiofilesource.h> #include <ardour/destructive_filesource.h> +#include <ardour/midi_source.h> #include <ardour/sndfile_helpers.h> #include <ardour/auditioner.h> #include <ardour/export.h> @@ -82,6 +85,7 @@ #include <ardour/version.h> #include <ardour/location.h> #include <ardour/audioregion.h> +#include <ardour/midi_region.h> #include <ardour/crossfade.h> #include <ardour/control_protocol_manager.h> @@ -264,7 +268,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) /* These are all static "per-class" signals */ Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region)); - AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source)); + Source::SourceCreated.connect (mem_fun (*this, &Session::add_source)); Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist)); Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect)); Diskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream)); @@ -1348,26 +1352,19 @@ Session::state(bool full_state) child = node->add_child ("Sources"); if (full_state) { - Glib::Mutex::Lock sl (audio_source_lock); + Glib::Mutex::Lock sl (source_lock); - for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) { + for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) { - /* Don't save information about AudioFileSources that are empty */ - - AudioFileSource* fs; - if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) { - DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs); + DestructiveFileSource* const dfs = dynamic_cast<DestructiveFileSource*> (siter->second); - /* destructive file sources are OK if they are empty, because - we will re-use them every time. - */ + /* Don't save sources that are empty, unless they're destructive (which are OK + if they are empty, because we will re-use them every time.) + */ - if (!dfs) { - if (fs->length() == 0) { - continue; - } - } + if ( ! dfs && siter->second->length() == 0) { + continue; } child->add_child_nocopy (siter->second->get_state()); @@ -1379,7 +1376,7 @@ Session::state(bool full_state) if (full_state) { Glib::Mutex::Lock rl (region_lock); - for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) { + for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { /* only store regions not attached to playlists */ @@ -1769,7 +1766,7 @@ Session::load_regions (const XMLNode& node) { XMLNodeList nlist; XMLNodeConstIterator niter; - AudioRegion* region; + Region* region; nlist = node.children(); @@ -1783,9 +1780,33 @@ Session::load_regions (const XMLNode& node) return 0; } -AudioRegion * +Region * Session::XMLRegionFactory (const XMLNode& node, bool full) { + const XMLProperty* type = node.property("type"); + + try { + + if ( !type || type->value() == "audio" ) { + + return XMLAudioRegionFactory (node, full); + + } else if (type->value() == "midi") { + + return XMLMidiRegionFactory (node, full); + + } + + } catch (failed_constructor& err) { + return 0; + } + + return 0; +} + +AudioRegion * +Session::XMLAudioRegionFactory (const XMLNode& node, bool full) +{ const XMLProperty* prop; Source* source; AudioSource* as; @@ -1855,14 +1876,65 @@ Session::XMLRegionFactory (const XMLNode& node, bool full) } } +MidiRegion * +Session::XMLMidiRegionFactory (const XMLNode& node, bool full) +{ + const XMLProperty* prop; + Source* source; + MidiSource* ms; + MidiRegion::SourceList sources; + uint32_t nchans = 1; + + if (node.name() != X_("Region")) { + return 0; + } + + if ((prop = node.property (X_("channels"))) != 0) { + nchans = atoi (prop->value().c_str()); + } + + // Multiple midi channels? that's just crazy talk + assert(nchans == 1); + + if ((prop = node.property (X_("source-0"))) == 0) { + if ((prop = node.property ("source")) == 0) { + error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg; + return 0; + } + } + + PBD::ID s_id (prop->value()); + + if ((source = source_by_id (s_id)) == 0) { + error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg; + return 0; + } + + ms = dynamic_cast<MidiSource*>(source); + if (!ms) { + error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-audio source id =%1"), s_id) << endmsg; + return 0; + } + + sources.push_back (ms); + + try { + return new MidiRegion (sources, node); + } + + catch (failed_constructor& err) { + return 0; + } +} + XMLNode& Session::get_sources_as_xml () { XMLNode* node = new XMLNode (X_("Sources")); - Glib::Mutex::Lock lm (audio_source_lock); + Glib::Mutex::Lock lm (source_lock); - for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) { + for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) { node->add_child_nocopy (i->second->get_state()); } @@ -1923,13 +1995,29 @@ Session::XMLSourceFactory (const XMLNode& node) if (node.name() != "Source") { return 0; } + + DataType type = DataType::AUDIO; + const XMLProperty* prop = node.property("type"); + if (prop) { + type = DataType(prop->value()); + } try { + + + if (type == DataType::AUDIO) { + src = AudioFileSource::create (node); + + } else if (type == DataType::MIDI) { + + src = new SMFSource (node); + } - catch (failed_constructor& err) { - error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg; + + } catch (failed_constructor& err) { + error << _("Found a file that cannot be read by Ardour. Talk to the progammers.") << endmsg; return 0; } @@ -2241,17 +2329,28 @@ Session::load_unused_playlists (const XMLNode& node) return 0; } - Playlist * Session::XMLPlaylistFactory (const XMLNode& node) { + const XMLProperty* type = node.property("type"); + try { + + if ( !type || type->value() == "audio" ) { + return new AudioPlaylist (*this, node); - } + + } else if (type->value() == "midi") { - catch (failed_constructor& err) { + return new MidiPlaylist (*this, node); + + } + + } catch (failed_constructor& err) { return 0; } + + return 0; } int @@ -2961,9 +3060,9 @@ Session::cleanup_sources (Session::cleanup_report& rep) rep.paths.clear (); rep.space = 0; - for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) { + for (SourceList::iterator i = sources.begin(); i != sources.end(); ) { - AudioSourceList::iterator tmp; + SourceList::iterator tmp; tmp = i; ++tmp; @@ -2980,7 +3079,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) adding it to the list of all sources below */ - audio_sources.erase (i); + sources.erase (i); } i = tmp; @@ -2993,19 +3092,18 @@ Session::cleanup_sources (Session::cleanup_report& rep) for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) { - for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) { - AudioRegionList::iterator tmp; - AudioRegion* ar; + for (RegionList::iterator r = regions.begin(); r != regions.end(); ) { + RegionList::iterator tmp; tmp = r; ++tmp; - ar = r->second; + Region* const reg = r->second; - for (uint32_t n = 0; n < ar->n_channels(); ++n) { - if (&ar->source (n) == (*i)) { + for (uint32_t n = 0; n < reg->n_channels(); ++n) { + if (®->source (n) == (*i)) { /* this region is dead */ - remove_region (ar); + remove_region (reg); } } @@ -3050,7 +3148,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) /* add our current source list */ - for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) { + for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) { AudioFileSource* fs; if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) { diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 86e2e8a9aa..9a03d0fabd 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -54,6 +54,8 @@ SMFSource::SMFSource (std::string path, Flag flags) if (init (path, false)) { throw failed_constructor (); } + + SourceCreated (this); /* EMIT SIGNAL */ } SMFSource::SMFSource (const XMLNode& node) @@ -68,6 +70,8 @@ SMFSource::SMFSource (const XMLNode& node) if (init (_name, true)) { throw failed_constructor (); } + + SourceCreated (this); /* EMIT SIGNAL */ } SMFSource::~SMFSource () @@ -89,8 +93,9 @@ SMFSource::init (string pathstr, bool must_exist) { bool is_new = false; - _length = 0; + _length = 1024; // FIXME FIXME FIXME: force save + /* if (!find (pathstr, must_exist, is_new)) { cerr << "cannot find " << pathstr << " with me = " << must_exist << endl; return -1; @@ -99,6 +104,9 @@ SMFSource::init (string pathstr, bool must_exist) if (is_new && must_exist) { return -1; } + */ + + // Yeah, we sound it. Swear. return 0; } diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index b487d4e3a3..4d5f42b028 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -51,7 +51,7 @@ SndFileSource::SndFileSource (const XMLNode& node) } } - AudioSourceCreated (this); /* EMIT SIGNAL */ + SourceCreated (this); /* EMIT SIGNAL */ } SndFileSource::SndFileSource (string idstr, Flag flags) @@ -73,7 +73,7 @@ SndFileSource::SndFileSource (string idstr, Flag flags) } - AudioSourceCreated (this); /* EMIT SIGNAL */ + SourceCreated (this); /* EMIT SIGNAL */ } SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, jack_nframes_t rate, Flag flags) @@ -184,7 +184,7 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, } } - AudioSourceCreated (this); /* EMIT SIGNAL */ + SourceCreated (this); /* EMIT SIGNAL */ } diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc index e5aba19d2c..1506983e18 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -42,7 +42,11 @@ using std::max; using namespace ARDOUR; -Source::Source (string name) +sigc::signal<void,Source*> Source::SourceCreated; + + +Source::Source (string name, DataType type) + : _type(type) { _name = name; _use_cnt = 0; @@ -50,11 +54,12 @@ Source::Source (string name) } Source::Source (const XMLNode& node) + : _type(DataType::AUDIO) { _use_cnt = 0; _timestamp = 0; - if (set_state (node)) { + if (set_state (node) || _type == DataType::NIL) { throw failed_constructor(); } } @@ -70,6 +75,7 @@ Source::get_state () char buf[64]; node->add_property ("name", _name); + node->add_property ("type", _type.to_string()); _id.print (buf); node->add_property ("id", buf); @@ -98,6 +104,10 @@ Source::set_state (const XMLNode& node) return -1; } + if ((prop = node.property ("type")) != 0) { + _type = DataType(prop->value()); + } + if ((prop = node.property ("timestamp")) != 0) { sscanf (prop->value().c_str(), "%ld", &_timestamp); } |