- MIDI "recording" - rec region creation/drawing, actual MIDI region creation/view...
authorDavid Robillard <d@drobilla.net>
Mon, 14 Aug 2006 08:44:14 +0000 (08:44 +0000)
committerDavid Robillard <d@drobilla.net>
Mon, 14 Aug 2006 08:44:14 +0000 (08:44 +0000)
- MIDI containing session saving and restoring (ie XML - Source, Region, Playlist; all but the actual .mid files)
- Numerous little fixes for audio specific stuff to accomplish the above
- Dirty hacks to accomplish the above
- Profit!!!

git-svn-id: svn://localhost/ardour2/branches/midi@821 d708f5d6-7413-0410-9779-e7cbd77b26cf

53 files changed:
gtk2_ardour/SConscript
gtk2_ardour/ardour_ui.cc
gtk2_ardour/audio_streamview.cc
gtk2_ardour/audio_streamview.h
gtk2_ardour/audio_time_axis.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_region_list.cc
gtk2_ardour/editor_tempodisplay.cc
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_streamview.cc
gtk2_ardour/midi_streamview.h
gtk2_ardour/midi_time_axis.cc
gtk2_ardour/midi_time_axis.h
gtk2_ardour/route_ui.cc
gtk2_ardour/route_ui.h
gtk2_ardour/streamview.cc
gtk2_ardour/streamview.h
libs/ardour/ardour/audiosource.h
libs/ardour/ardour/diskstream.h
libs/ardour/ardour/midi_diskstream.h
libs/ardour/ardour/midi_source.h
libs/ardour/ardour/midi_track.h
libs/ardour/ardour/playlist.h
libs/ardour/ardour/region.h
libs/ardour/ardour/session.h
libs/ardour/ardour/session_region.h
libs/ardour/ardour/smf_source.h
libs/ardour/ardour/source.h
libs/ardour/ardour/track.h
libs/ardour/audio_diskstream.cc
libs/ardour/audio_playlist.cc
libs/ardour/audioregion.cc
libs/ardour/audiosource.cc
libs/ardour/buffer.cc
libs/ardour/coreaudiosource.cc
libs/ardour/import.cc
libs/ardour/midi_diskstream.cc
libs/ardour/midi_playlist.cc
libs/ardour/midi_region.cc
libs/ardour/midi_source.cc
libs/ardour/midi_track.cc
libs/ardour/playlist.cc
libs/ardour/region.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/ardour/smf_source.cc
libs/ardour/sndfilesource.cc
libs/ardour/source.cc

index 8fb9a0717bc02ac81fea1f12ba4210749f53dc40..9035666bbb02faa0bcfc925be5eedfaa79a91927 100644 (file)
@@ -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
index 0e94259194c1534f0edc4737cac639b2714377fc..34718dfb1ce2ba5c8af39621d652872289a921ea 100644 (file)
@@ -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 ();
index 2e82d48ff36173dcd20c553efa3685e18d9f707c..523395c503b31e9023601ba2950a20dfa447606f 100644 (file)
@@ -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()) {
 
index 05ce8125f618d514b155851076b5d808f80b769c..979240bd503f85d00f3b84ce1406a76cef8771a8 100644 (file)
@@ -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__ */
index 893bcc21c004298e6b672b665c29ab77b7416064..7f6bc50222800028a6a672f424704fd7c695fae0 100644 (file)
@@ -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";
index 513251085c6d9f8c195bb684e400ae0e9c8762cc..b99198285593348acdc61e876eaaafe8114ceaf8 100644 (file)
@@ -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);
                                }
                        }
index b3735cf42a378eea0449e9ae314f02477de8dacb..3f2a278f0983013eba0ef973bb5abcaa26c1bcc8 100644 (file)
@@ -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);
index 754706ad9f98ebc535f40b51ed6baeef0d1e5bcb..de256ce0e64ae07517adfdbfa1002724a98ac1c2 100644 (file)
@@ -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);
index e8ba2b8a6032bce19af73d77172725eaa0e8070e..2f3aab1eb66aac0885414d8d45f1defda5c67fed 100644 (file)
@@ -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);
                }
        }
index a05dcba9e3131101b636bed3fe2335d776817bd7..f459f2434144611c635b1edee06cbaaf340fca84 100644 (file)
@@ -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;
        }
 
index 9b69026a013c01279f6638bcba8d29cb36454227..30e19c484c23df47f3db423b9e2e8791dac37e06 100644 (file)
@@ -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*>(&region);
-               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;
        }
        
index 5cf099433b1588c2481ba4b6c4ff119ebfa5c30f..7df91cfa4f75f9cee39064513e3649085deedfa1 100644 (file)
@@ -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);
index 9f7fe7cf095c9f5e1aa289855c0c668716c0d46a..2e4e092ebd4e01a76dcbc962e7f6286b8189a8d1 100644 (file)
@@ -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) {
 
index d716a5605aadf8a22420a5d1a3ba164babc5eca9..2e102b4f70a6fbd8bef29a2959187aefc41b2cd4 100644 (file)
@@ -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;
 }
 
index 60372e640fbba4494c5a81a85a17a3df0a098a29..5f939ab58306a5a3c15db4521c9ffe5f52790cab 100644 (file)
 #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
index 0b13f9fd7f40adee2879b0ba981e3c8bec808536..107a804db8e1cccd0cf810f06c47bd68d53404a4 100644 (file)
@@ -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);
index 041eebff10c069c559e64120ba04d4299975d476..9300986960b590f92577f9cd9e4ba0aef9770d7d 100644 (file)
@@ -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";
index be01e16d26b50fbfd641eebec8483f2ee8eb69be..df1c964fee4c0cbbc7fcaf9cb38496a3921f95d0 100644 (file)
@@ -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;
index e90355fd0af2ba124a1ccc8bb8c57edf078f7d50..6b3c2a820cc7d8d1dcc29dde232b13b0d9d24489 100644 (file)
@@ -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;
                }
                
@@ -592,6 +592,17 @@ RouteUI::reversibly_apply_audio_track_boolean (string name, void (AudioTrack::*f
        _session.commit_reversible_command ();
 }
 
+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)
 {
index 643c39b9604ab18242f5d9d793d53a3a7fa28127..156063a8e5f4ee9f5e46828a637acfeddeeb28c5 100644 (file)
@@ -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__ */
index d1d163d7a2ed746032a42f80b3ed39a180c1d4aa..82f941f9bdc482cfea5b7976a009d5b2d0affc73 100644 (file)
@@ -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 */
 
index 5a0e10974f9a8c3f472c9123629c24ca403aad99..bee51e88350c9787b76f51e74e1336847740fb6a 100644 (file)
@@ -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__ */
index 4af857c1d63ce3985209db2eb704ac033e6df4c3..c3c2f9bb9ac0e7014283fe0ee6a9dcfaa2f48869 100644 (file)
@@ -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;
index c4e85c00ceb6e389cdbe9bd02f8d9b1a89660f62..fa1126901d8c6d74b2a357f6f9223cd327147199 100644 (file)
@@ -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;
index a048cf40218071bdc33bf186623e2e87658b8fa6..8085e6509aaff29ffd2078369fbdf3a8d8b43aaf 100644 (file)
@@ -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 ();
index 1c002890033270706779ff9be583e3273ea8b175..d4fec52609e0cd9e9832fc553d80afc89cf4788f 100644 (file)
@@ -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&);
index 9274cfbcf6f67f5ff0e566a5ecf56f1f443d9439..654eb98e302b7902a803504a2082c9b55866869f 100644 (file)
@@ -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);
 
index b389258860bce55ccbd9ae251852d56e0fd1ded4..59fd0f8bc5603f34a7cfc1191a483587436850dc 100644 (file)
@@ -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 */
index c0ff8be607a06b3e73dc92f8729ef993fabeb81b..80504ce0444d69eb93b0315bb28df52bc110c5c1 100644 (file)
@@ -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;
index a9b8cbf290d6cac04f31f74bb628e7f7f74cadba..2737d86a3fb70312fa591cc2af1173ab64f94d71 100644 (file)
@@ -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 ();
index 4f0fb92e3b878418e9c7bf47861132eef3e7f579..fae950baa68afff5434b6512eed37a14e4e1b5d4 100644 (file)
@@ -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);
        }
 }
index 83bc47d7d372b517a177ba696c1be32eeacc18ec..abb52456e3381bcafd6f8cc655265bc200c37c7f 100644 (file)
@@ -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; }
index dc1e93f8f29a8d5c1562fd83e89d2ee2d7a0826c..a8d0fed20ba05490a54a57e68eb6a2b479c70d47 100644 (file)
 #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;
index 4fc7cf4326b02b9c8656f5ae3f93d00d3d522ab6..15a0a28aab7beb74f25e2df38817a9c0d16e8266 100644 (file)
@@ -48,7 +48,7 @@ class Track : public Route
 
        void toggle_monitor_input ();
 
-       virtual bool can_record();
+       bool can_record();
 
        Diskstream& diskstream() const { return *_diskstream; }
 
index 6973ebd877afc805cb94a9e61ba9839ef7060f20..784a14bb2b03bea55f6960c422642e0a7af0d941 100644 (file)
@@ -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) {
index 328c9b25f5e2b75c32ce79ff36add52f4e956d0e..b621e587e96d64d0a11d2feb694a817484c5fbe0 100644 (file)
@@ -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"));
 
index 6b810c04ecb3435535767c22bff59f81cea3be9a..052049cda7c325ae830d94d14a886599bb5cf283 100644 (file)
@@ -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 */
 }
 
index bf97ef848a85a5489e6574239016006f87946ac5..9620565ae2074fa18de8cb2460d5fd7f1171d07a 100644 (file)
@@ -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;
index 85b9317f78ee8f83434781a1fff556f1a9fcb111..fa4669cef6d4d02c1006237aa4e9131f3a4b7b6f 100644 (file)
@@ -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";
 }
 
 
index f0fcac14e2fa312d61ece028c32dc9d19724b8f3..d2a9a8c8e650f9df0d1c89748b583b90301480eb 100644 (file)
@@ -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 
index c68eb16aae6745c4a4ea6134d6f254300465319c..6d98388941b94612f971cbea9daab0392e4be26c 100644 (file)
@@ -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;
                }
 
index 948afd149b5ffd5624ff9d91ccb290ca42ba03c1..2c88d5daa8d0d2a2d3462299008dcf79b1d6b3ac 100644 (file)
@@ -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*>(&region->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
index db28c06f17a09e4e6dfb39c9dde0432111d455b6..443c5b57bf49681f1643fd7545b93a67f01e404b 100644 (file)
@@ -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;
 
        }*/
 
index 0902337030f50837d92cce93b87e57dfe0f23ecf..5b8a49049ea80ef581b9db6ca5d38323c555c240 100644 (file)
@@ -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;
 }
 
index 4cda0f6ebd87d0a1b5d295c7b464f52442862142..6728231de676f88f1e3141aa86d9594ef9a4612e 100644 (file)
@@ -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;
index cdbd441cd69e88b81b395123ace360fa389bdac9..470759f3ac3c987d11cbb6c1465e31ba7a46ace5 100644 (file)
@@ -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);
 }
index 6d5e8f7847d5f0287cb96bbc21f540810b8d2a98..61aa5c587aca2ed0bfacad87f418a3442f9fa0ae 100644 (file)
@@ -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);
index 03a4d1d2a39bcfc4b6dba8a1dca9a7d63a453413..3481ee3eeaf4d57ba00edcb73b18342369b54226 100644 (file)
@@ -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());
index 9cfaf18cb0a95646c47f763284f75f5a45c226de..33165574a80e3167090ff91f5d183ce7dfd880d6 100644 (file)
@@ -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;
                }
        }
index 2a08859205f86a786223c3754cab8fde92e5dfde..5e96a8ca8af2719238a38a703f6ab01148f8cbf4 100644 (file)
 #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,8 +1780,32 @@ 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;
@@ -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 (&reg->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) {
index 86e2e8a9aaad9d912079dd2578cd0e264d949cfd..9a03d0fabd38b6fc94e05b7dbe20405eccb8c50d 100644 (file)
@@ -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;
 }
index b487d4e3a39e8efdf06685c5f550fe55d4bf0406..4d5f42b028064383991cd938dd10ee6a86c149a2 100644 (file)
@@ -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 */
 
 }
 
index e5aba19d2c32c86198a7de4190a160d44d152bf4..1506983e1811419c779ec623a5556c66dcb42c46 100644 (file)
@@ -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);
        }