mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 15:25:01 +01:00
- MIDI "recording" - rec region creation/drawing, actual MIDI region creation/view/pretty pictures/etc
- 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
This commit is contained in:
parent
0b572cdd84
commit
d752986314
53 changed files with 940 additions and 640 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2275,6 +2275,8 @@ Editor::new_region_from_selection ()
|
|||
void
|
||||
Editor::separate_region_from_selection ()
|
||||
{
|
||||
// FIXME: TYPE
|
||||
|
||||
bool doing_undo = false;
|
||||
|
||||
if (selection->time.empty()) {
|
||||
|
|
@ -2321,6 +2323,8 @@ Editor::separate_region_from_selection ()
|
|||
void
|
||||
Editor::separate_regions_using_location (Location& loc)
|
||||
{
|
||||
// FIXME: TYPE
|
||||
|
||||
bool doing_undo = false;
|
||||
|
||||
if (loc.is_mark()) {
|
||||
|
|
@ -2391,15 +2395,12 @@ Editor::crop_region_to_selection ()
|
|||
|
||||
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
||||
|
||||
AudioTimeAxisView* atv;
|
||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*i);
|
||||
|
||||
if ((atv = dynamic_cast<AudioTimeAxisView*> ((*i))) != 0) {
|
||||
if (rtv && rtv->is_track()) {
|
||||
|
||||
if (atv->is_audio_track()) {
|
||||
|
||||
if ((playlist = atv->playlist()) != 0) {
|
||||
playlists.push_back (playlist);
|
||||
}
|
||||
if ((playlist = rtv->playlist()) != 0) {
|
||||
playlists.push_back (playlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2460,8 +2461,7 @@ Editor::region_fill_track ()
|
|||
|
||||
// FIXME
|
||||
AudioRegion* const ar = dynamic_cast<AudioRegion*>(®ion);
|
||||
if (!ar)
|
||||
continue;
|
||||
assert(ar);
|
||||
|
||||
Playlist* pl = region.playlist();
|
||||
|
||||
|
|
@ -2475,7 +2475,7 @@ Editor::region_fill_track ()
|
|||
return;
|
||||
}
|
||||
|
||||
XMLNode &before = pl->get_state();
|
||||
XMLNode &before = pl->get_state();
|
||||
pl->add_region (*(new AudioRegion (*ar)), ar->last_frame(), times);
|
||||
session->add_command (new MementoCommand<Playlist>(*pl, before, pl->get_state()));
|
||||
}
|
||||
|
|
@ -2486,7 +2486,7 @@ Editor::region_fill_track ()
|
|||
void
|
||||
Editor::region_fill_selection ()
|
||||
{
|
||||
if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) {
|
||||
if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2613,7 +2613,7 @@ Editor::align_relative (RegionPoint what)
|
|||
}
|
||||
|
||||
struct RegionSortByTime {
|
||||
bool operator() (const AudioRegionView* a, const AudioRegionView* b) {
|
||||
bool operator() (const RegionView* a, const RegionView* b) {
|
||||
return a->region().position() < b->region().position();
|
||||
}
|
||||
};
|
||||
|
|
@ -2781,11 +2781,11 @@ Editor::trim_region_from_edit_cursor ()
|
|||
void
|
||||
Editor::unfreeze_route ()
|
||||
{
|
||||
if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) {
|
||||
if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_track()) {
|
||||
return;
|
||||
}
|
||||
|
||||
clicked_audio_trackview->audio_track()->unfreeze ();
|
||||
clicked_audio_trackview->track()->unfreeze ();
|
||||
}
|
||||
|
||||
void*
|
||||
|
|
@ -2812,7 +2812,7 @@ Editor::freeze_progress_timeout (void *arg)
|
|||
void
|
||||
Editor::freeze_route ()
|
||||
{
|
||||
if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) {
|
||||
if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_track()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,11 +29,11 @@
|
|||
#include <ardour/midi_diskstream.h>
|
||||
#include <ardour/midi_track.h>
|
||||
//#include <ardour/playlist_templates.h>
|
||||
#include <ardour/source.h>
|
||||
#include <ardour/midi_source.h>
|
||||
|
||||
#include "midi_streamview.h"
|
||||
#include "region_view.h"
|
||||
//#include "midi_regionview.h"
|
||||
#include "midi_region_view.h"
|
||||
#include "midi_time_axis.h"
|
||||
#include "canvas-simplerect.h"
|
||||
#include "region_selection.h"
|
||||
|
|
@ -52,55 +52,26 @@ using namespace Editing;
|
|||
MidiStreamView::MidiStreamView (MidiTimeAxisView& tv)
|
||||
: StreamView (tv)
|
||||
{
|
||||
region_color = _trackview.color();
|
||||
|
||||
if (tv.is_midi_track())
|
||||
if (tv.is_track())
|
||||
stream_base_color = color_map[cMidiTrackBase];
|
||||
else
|
||||
stream_base_color = color_map[cMidiBusBase];
|
||||
|
||||
/* set_position() will position the group */
|
||||
|
||||
canvas_group = new ArdourCanvas::Group(*_trackview.canvas_display);
|
||||
|
||||
canvas_rect = new ArdourCanvas::SimpleRect (*canvas_group);
|
||||
canvas_rect->property_x1() = 0.0;
|
||||
canvas_rect->property_y1() = 0.0;
|
||||
canvas_rect->property_x2() = 1000000.0;
|
||||
canvas_rect->property_y2() = (double) tv.height;
|
||||
canvas_rect->property_outline_color_rgba() = color_map[cMidiTrackOutline];
|
||||
canvas_rect->property_outline_what() = (guint32) (0x1|0x2|0x8); // outline ends and bottom
|
||||
|
||||
canvas_rect->property_fill_color_rgba() = stream_base_color;
|
||||
canvas_rect->property_outline_color_rgba() = color_map[cAudioTrackOutline];
|
||||
|
||||
canvas_rect->signal_event().connect (bind (mem_fun (_trackview.editor, &PublicEditor::canvas_stream_view_event), canvas_rect, &_trackview));
|
||||
|
||||
_samples_per_unit = _trackview.editor.get_current_zoom();
|
||||
|
||||
if (_trackview.is_midi_track()) {
|
||||
_trackview.midi_track()->DiskstreamChanged.connect (mem_fun (*this, &MidiStreamView::diskstream_changed));
|
||||
_trackview.session().TransportStateChange.connect (mem_fun (*this, &MidiStreamView::transport_changed));
|
||||
_trackview.get_diskstream()->RecordEnableChanged.connect (mem_fun (*this, &MidiStreamView::rec_enable_changed));
|
||||
_trackview.session().RecordStateChanged.connect (mem_fun (*this, &MidiStreamView::sess_rec_enable_changed));
|
||||
}
|
||||
|
||||
rec_updating = false;
|
||||
rec_active = false;
|
||||
use_rec_regions = tv.editor.show_waveforms_recording ();
|
||||
|
||||
ColorChanged.connect (mem_fun (*this, &MidiStreamView::color_handler));
|
||||
//use_rec_regions = tv.editor.show_waveforms_recording ();
|
||||
use_rec_regions = true;
|
||||
}
|
||||
|
||||
MidiStreamView::~MidiStreamView ()
|
||||
{
|
||||
undisplay_diskstream ();
|
||||
delete canvas_group;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MidiStreamView::add_region_view_internal (Region *r, bool wait_for_waves)
|
||||
{
|
||||
#if 0
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &MidiStreamView::add_region_view), r));
|
||||
|
||||
MidiRegion* region = dynamic_cast<MidiRegion*> (r);
|
||||
|
|
@ -122,30 +93,25 @@ MidiStreamView::add_region_view_internal (Region *r, bool wait_for_waves)
|
|||
}
|
||||
}
|
||||
|
||||
/* FIXME
|
||||
switch (_trackview.midi_track()->mode()) {
|
||||
case Normal:
|
||||
region_view = new MidiRegionView (canvas_group, _trackview, *region,
|
||||
_samples_per_unit, region_color);
|
||||
break;
|
||||
case Destructive:
|
||||
region_view = new TapeMidiRegionView (canvas_group, _trackview, *region,
|
||||
_samples_per_unit, region_color);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
// can't we all just get along?
|
||||
assert(_trackview.midi_track()->mode() != Destructive);
|
||||
|
||||
region_view = new MidiRegionView (canvas_group, _trackview, *region,
|
||||
_samples_per_unit, region_color);
|
||||
_samples_per_unit, region_color);
|
||||
|
||||
region_view->init (region_color, wait_for_waves);
|
||||
region_views.push_front (region_view);
|
||||
|
||||
/* follow global waveform setting */
|
||||
|
||||
// FIXME
|
||||
//region_view->set_waveform_visible(_trackview.editor.show_waveforms());
|
||||
|
||||
/* catch regionview going away */
|
||||
|
||||
region->GoingAway.connect (mem_fun (*this, &MidiStreamView::remove_region_view));
|
||||
|
||||
RegionViewAdded (region_view);
|
||||
#endif
|
||||
}
|
||||
|
||||
// FIXME: code duplication with AudioStreamVIew
|
||||
|
|
@ -183,26 +149,30 @@ MidiStreamView::redisplay_diskstream ()
|
|||
void
|
||||
MidiStreamView::setup_rec_box ()
|
||||
{
|
||||
#if 0
|
||||
// cerr << _trackview.name() << " streamview SRB\n";
|
||||
|
||||
if (_trackview.session().transport_rolling()) {
|
||||
|
||||
// cerr << "\trolling\n";
|
||||
cerr << "\tSHOW: rolling\n";
|
||||
|
||||
if (!rec_active &&
|
||||
_trackview.session().record_status() == Session::Recording &&
|
||||
_trackview.get_diskstream()->record_enabled()) {
|
||||
|
||||
if (_trackview.midi_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) {
|
||||
if (use_rec_regions && rec_regions.size() == rec_rects.size()) {
|
||||
|
||||
/* add a new region, but don't bother if they set use_rec_regions mid-record */
|
||||
|
||||
MidiRegion::SourceList sources;
|
||||
|
||||
// FIXME
|
||||
MidiDiskstream* ads = dynamic_cast<MidiDiskstream*>(_trackview.get_diskstream());
|
||||
assert(ads);
|
||||
MidiDiskstream* mds = dynamic_cast<MidiDiskstream*>(_trackview.get_diskstream());
|
||||
assert(mds);
|
||||
|
||||
sources.push_back((Source*)mds->write_source());
|
||||
|
||||
// FIXME
|
||||
rec_data_ready_connections.push_back (mds->write_source()->ViewDataRangeReady.connect (bind (mem_fun (*this, &MidiStreamView::rec_data_range_ready), mds->write_source())));
|
||||
|
||||
// handle multi
|
||||
|
||||
|
|
@ -222,30 +192,17 @@ MidiStreamView::setup_rec_box ()
|
|||
|
||||
/* start a new rec box */
|
||||
|
||||
MidiTrack* at;
|
||||
|
||||
at = _trackview.midi_track(); /* we know what it is already */
|
||||
MidiDiskstream& ds = at->midi_diskstream();
|
||||
MidiTrack* mt = _trackview.midi_track(); /* we know what it is already */
|
||||
MidiDiskstream& ds = mt->midi_diskstream();
|
||||
jack_nframes_t frame_pos = ds.current_capture_start ();
|
||||
gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
|
||||
gdouble xend;
|
||||
uint32_t fill_color;
|
||||
|
||||
switch (_trackview.midi_track()->mode()) {
|
||||
case Normal:
|
||||
xend = xstart;
|
||||
fill_color = color_map[cRecordingRectFill];
|
||||
break;
|
||||
|
||||
case Destructive:
|
||||
xend = xstart + 2;
|
||||
fill_color = color_map[cRecordingRectFill];
|
||||
/* make the recording rect translucent to allow
|
||||
the user to see the peak data coming in, etc.
|
||||
*/
|
||||
fill_color = UINT_RGBA_CHANGE_A (fill_color, 120);
|
||||
break;
|
||||
}
|
||||
assert(_trackview.midi_track()->mode() == Normal);
|
||||
|
||||
xend = xstart;
|
||||
fill_color = color_map[cRecordingRectFill];
|
||||
|
||||
ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group);
|
||||
rec_rect->property_x1() = xstart;
|
||||
|
|
@ -267,10 +224,16 @@ MidiStreamView::setup_rec_box ()
|
|||
rec_updating = true;
|
||||
rec_active = true;
|
||||
|
||||
// Show, damn you!
|
||||
rec_rect->show();
|
||||
rec_rect->raise_to_top();
|
||||
|
||||
} else if (rec_active &&
|
||||
(_trackview.session().record_status() != Session::Recording ||
|
||||
!_trackview.get_diskstream()->record_enabled())) {
|
||||
|
||||
cerr << "NO SHOW 1\n";
|
||||
|
||||
screen_update_connection.disconnect();
|
||||
rec_active = false;
|
||||
rec_updating = false;
|
||||
|
|
@ -279,21 +242,21 @@ MidiStreamView::setup_rec_box ()
|
|||
|
||||
} else {
|
||||
|
||||
// cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl;
|
||||
cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl;
|
||||
|
||||
if (!rec_rects.empty() || !rec_regions.empty()) {
|
||||
|
||||
/* disconnect rapid update */
|
||||
screen_update_connection.disconnect();
|
||||
|
||||
for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) {
|
||||
for (list<sigc::connection>::iterator prc = rec_data_ready_connections.begin(); prc != rec_data_ready_connections.end(); ++prc) {
|
||||
(*prc).disconnect();
|
||||
}
|
||||
peak_ready_connections.clear();
|
||||
rec_data_ready_connections.clear();
|
||||
|
||||
rec_updating = false;
|
||||
rec_active = false;
|
||||
last_rec_peak_frame = 0;
|
||||
last_rec_data_frame = 0;
|
||||
|
||||
/* remove temp regions */
|
||||
for (list<Region*>::iterator iter=rec_regions.begin(); iter != rec_regions.end(); )
|
||||
|
|
@ -324,15 +287,14 @@ MidiStreamView::setup_rec_box ()
|
|||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MidiStreamView::update_rec_regions ()
|
||||
{
|
||||
#if 0
|
||||
if (use_rec_regions) {
|
||||
|
||||
|
||||
uint32_t n = 0;
|
||||
|
||||
for (list<Region*>::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) {
|
||||
|
|
@ -356,9 +318,9 @@ MidiStreamView::update_rec_regions ()
|
|||
|
||||
if (region == rec_regions.back() && rec_active) {
|
||||
|
||||
if (last_rec_peak_frame > region->start()) {
|
||||
if (last_rec_data_frame > region->start()) {
|
||||
|
||||
jack_nframes_t nlen = last_rec_peak_frame - region->start();
|
||||
jack_nframes_t nlen = last_rec_data_frame - region->start();
|
||||
|
||||
if (nlen != region->length()) {
|
||||
|
||||
|
|
@ -408,7 +370,28 @@ MidiStreamView::update_rec_regions ()
|
|||
iter = tmp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MidiStreamView::rec_data_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * src)
|
||||
{
|
||||
// this is called from the butler thread for now
|
||||
// yeah we need a "peak" building thread or something. whatever. :)
|
||||
|
||||
ENSURE_GUI_THREAD(bind (mem_fun (*this, &MidiStreamView::rec_data_range_ready), start, cnt, src));
|
||||
|
||||
//cerr << "REC DATA: " << start << " --- " << cnt << endl;
|
||||
|
||||
if (rec_data_ready_map.size() == 0 || start+cnt > last_rec_data_frame) {
|
||||
last_rec_data_frame = start + cnt;
|
||||
}
|
||||
|
||||
rec_data_ready_map[src] = true;
|
||||
|
||||
if (rec_data_ready_map.size() == _trackview.get_diskstream()->n_channels().get(DataType::MIDI)) {
|
||||
this->update_rec_regions ();
|
||||
rec_data_ready_map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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&);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -28,13 +28,14 @@
|
|||
#include <pbd/stateful.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/data_type.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class Source : public Stateful, public sigc::trackable
|
||||
{
|
||||
public:
|
||||
Source (std::string name);
|
||||
Source (std::string name, DataType type);
|
||||
Source (const XMLNode&);
|
||||
virtual ~Source ();
|
||||
|
||||
|
|
@ -60,12 +61,14 @@ class Source : public Stateful, public sigc::trackable
|
|||
XMLNode& get_state ();
|
||||
int set_state (const XMLNode&);
|
||||
|
||||
static sigc::signal<void,Source*> SourceCreated;
|
||||
sigc::signal<void,Source *> GoingAway;
|
||||
|
||||
protected:
|
||||
void update_length (jack_nframes_t pos, jack_nframes_t cnt);
|
||||
|
||||
string _name;
|
||||
DataType _type;
|
||||
uint32_t _use_cnt;
|
||||
time_t _timestamp;
|
||||
jack_nframes_t _length;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class Track : public Route
|
|||
|
||||
void toggle_monitor_input ();
|
||||
|
||||
virtual bool can_record();
|
||||
bool can_record();
|
||||
|
||||
Diskstream& diskstream() const { return *_diskstream; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <pbd/basename.h>
|
||||
#include <glibmm/thread.h>
|
||||
#include <pbd/xml++.h>
|
||||
#include <pbd/memento_command.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/audioengine.h>
|
||||
|
|
@ -77,6 +78,7 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F
|
|||
|
||||
in_set_state = false;
|
||||
|
||||
assert(!destructive());
|
||||
DiskstreamCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
|
|
@ -129,6 +131,8 @@ MidiDiskstream::init (Diskstream::Flag f)
|
|||
_capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
|
||||
|
||||
_n_channels = ChanCount(DataType::MIDI, 1);
|
||||
|
||||
assert(recordable());
|
||||
}
|
||||
|
||||
MidiDiskstream::~MidiDiskstream ()
|
||||
|
|
@ -181,20 +185,18 @@ MidiDiskstream::non_realtime_input_change ()
|
|||
void
|
||||
MidiDiskstream::get_input_sources ()
|
||||
{
|
||||
#if 0
|
||||
if (_io->n_inputs() == 0) {
|
||||
cerr << "MidiDiskstream NO INPUTS?\n";
|
||||
uint32_t ni = _io->n_inputs().get(DataType::MIDI);
|
||||
|
||||
if (ni == 0) {
|
||||
return;
|
||||
} else {
|
||||
cerr << "INPUTS!\n";
|
||||
}
|
||||
|
||||
// FIXME this is weird and really different from AudioDiskstream
|
||||
|
||||
assert(_io->n_inputs() == 1);
|
||||
assert(_io->midi_input(0));
|
||||
// This is all we do for now at least
|
||||
assert(ni == 1);
|
||||
|
||||
_source_port = _io->midi_input(0);
|
||||
|
||||
/* I don't get it....
|
||||
const char **connections = _io->input(0)->get_connections ();
|
||||
|
||||
if (connections == 0 || connections[0] == 0) {
|
||||
|
|
@ -207,20 +209,12 @@ MidiDiskstream::get_input_sources ()
|
|||
|
||||
} else {
|
||||
_source_port = dynamic_cast<MidiPort*>(
|
||||
_session.engine().get_port_by_name (connections[0]));
|
||||
assert(_source_port);
|
||||
}
|
||||
|
||||
if (_source_port) {
|
||||
cerr << "SOURCE PORT!\n";
|
||||
} else {
|
||||
cerr << "NO SOURCE PORT?!\n";
|
||||
_session.engine().get_port_by_name (connections[0]) );
|
||||
}
|
||||
|
||||
if (connections) {
|
||||
free (connections);
|
||||
}
|
||||
#endif
|
||||
}*/
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -299,46 +293,13 @@ MidiDiskstream::use_copy_playlist ()
|
|||
}
|
||||
}
|
||||
|
||||
/** Overloaded from parent to die horribly
|
||||
*/
|
||||
void
|
||||
MidiDiskstream::setup_destructive_playlist ()
|
||||
MidiDiskstream::set_destructive (bool yn)
|
||||
{
|
||||
Region::SourceList srcs;
|
||||
|
||||
srcs.push_back (_write_source);
|
||||
/* a single full-sized region */
|
||||
|
||||
cerr << "Setup MIDI DS using " << srcs.front()->natural_position () << endl;
|
||||
|
||||
MidiRegion* region = new MidiRegion (srcs, 0, max_frames, _name);
|
||||
_playlist->add_region (*region, srcs.front()->natural_position());
|
||||
}
|
||||
|
||||
void
|
||||
MidiDiskstream::use_destructive_playlist ()
|
||||
{
|
||||
/* use the sources associated with the single full-extent region */
|
||||
|
||||
Playlist::RegionList* rl = _playlist->regions_at (0);
|
||||
|
||||
if (rl->empty()) {
|
||||
reset_write_sources (false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
MidiRegion* region = dynamic_cast<MidiRegion*> (rl->front());
|
||||
|
||||
if (region == 0) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
delete rl;
|
||||
|
||||
assert(region->n_channels() == 1);
|
||||
_write_source = dynamic_cast<SMFSource*>(®ion->source (0));
|
||||
assert(_write_source);
|
||||
_write_source->set_allow_remove_if_empty (false);
|
||||
|
||||
/* the source list will never be reset for a destructive track */
|
||||
assert( ! destructive());
|
||||
assert( ! yn);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -587,8 +548,8 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
|
|||
cerr << "DISKSTREAM GOT EVENT " << i << "!!\n";
|
||||
}
|
||||
|
||||
if (_source_port->size() == 0)
|
||||
cerr << "No events :/ (1)\n";
|
||||
//if (_source_port->size() == 0)
|
||||
// cerr << "No events :/ (1)\n";
|
||||
|
||||
|
||||
} else {
|
||||
|
|
@ -607,8 +568,8 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
|
|||
for (size_t i=0; i < _source_port->size(); ++i) {
|
||||
cerr << "DISKSTREAM GOT EVENT " << i << "!!\n";
|
||||
}
|
||||
if (_source_port->size() == 0)
|
||||
cerr << "No events :/ (2)\n";
|
||||
//if (_source_port->size() == 0)
|
||||
// cerr << "No events :/ (2)\n";
|
||||
RawMidi* buf = NULL; // FIXME FIXME FIXME (make it compile)
|
||||
assert(false);
|
||||
jack_nframes_t first = _capture_vector.len[0];
|
||||
|
|
@ -630,6 +591,10 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
|
|||
|
||||
if (rec_nframes) {
|
||||
|
||||
// FIXME: filthy hack to fool the GUI into thinking we're doing something
|
||||
if (_write_source)
|
||||
_write_source->ViewDataRangeReady (transport_frame, rec_nframes); /* EMIT SIGNAL */
|
||||
|
||||
/* data will be written to disk */
|
||||
|
||||
if (rec_nframes == nframes && rec_offset == 0) {
|
||||
|
|
@ -687,9 +652,9 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
|
|||
jack_nframes_t total = _playback_vector.len[0] + _playback_vector.len[1];
|
||||
|
||||
if (necessary_samples > total) {
|
||||
cerr << "DiskUnderrun\n";
|
||||
//cerr << "DiskUnderrun\n";
|
||||
//DiskUnderrun (); // FIXME
|
||||
goto out;
|
||||
//goto out;
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -758,12 +723,46 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
|
|||
}
|
||||
|
||||
return ret;
|
||||
|
||||
_processed = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
MidiDiskstream::commit (jack_nframes_t nframes)
|
||||
{
|
||||
return 0;
|
||||
bool need_butler = false;
|
||||
|
||||
if (_actual_speed < 0.0) {
|
||||
playback_sample -= playback_distance;
|
||||
} else {
|
||||
playback_sample += playback_distance;
|
||||
}
|
||||
|
||||
_playback_buf->increment_read_ptr (playback_distance);
|
||||
|
||||
if (adjust_capture_position) {
|
||||
_capture_buf->increment_write_ptr (adjust_capture_position);
|
||||
}
|
||||
|
||||
if (adjust_capture_position != 0) {
|
||||
capture_captured += adjust_capture_position;
|
||||
adjust_capture_position = 0;
|
||||
}
|
||||
|
||||
if (_slaved) {
|
||||
need_butler = _playback_buf->write_space() >= _playback_buf->bufsize() / 2;
|
||||
} else {
|
||||
need_butler = _playback_buf->write_space() >= disk_io_chunk_frames
|
||||
|| _capture_buf->read_space() >= disk_io_chunk_frames;
|
||||
}
|
||||
|
||||
state_lock.unlock();
|
||||
|
||||
_processed = false;
|
||||
|
||||
return need_butler;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -786,6 +785,7 @@ MidiDiskstream::overwrite_existing_buffers ()
|
|||
int
|
||||
MidiDiskstream::seek (jack_nframes_t frame, bool complete_refill)
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -810,12 +810,13 @@ MidiDiskstream::read (RawMidi* buf, jack_nframes_t& start, jack_nframes_t cnt, b
|
|||
int
|
||||
MidiDiskstream::do_refill_with_alloc ()
|
||||
{
|
||||
return 0;
|
||||
return do_refill();
|
||||
}
|
||||
|
||||
int
|
||||
MidiDiskstream::do_refill ()
|
||||
{
|
||||
// yeah, the data's ready. promise.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -832,17 +833,198 @@ MidiDiskstream::do_refill ()
|
|||
int
|
||||
MidiDiskstream::do_flush (Session::RunContext context, bool force_flush)
|
||||
{
|
||||
/* hey, so did you write that data? */
|
||||
|
||||
// oh yeah, you bet. wrote it good. honest.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
|
||||
{
|
||||
uint32_t buffer_position;
|
||||
bool more_work = true;
|
||||
int err = 0;
|
||||
MidiRegion* region = 0;
|
||||
jack_nframes_t total_capture;
|
||||
MidiRegion::SourceList srcs;
|
||||
MidiRegion::SourceList::iterator src;
|
||||
vector<CaptureInfo*>::iterator ci;
|
||||
bool mark_write_completed = false;
|
||||
|
||||
finish_capture (true);
|
||||
|
||||
/* butler is already stopped, but there may be work to do
|
||||
to flush remaining data to disk.
|
||||
*/
|
||||
|
||||
while (more_work && !err) {
|
||||
switch (do_flush (Session::TransportContext, true)) {
|
||||
case 0:
|
||||
more_work = false;
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
case -1:
|
||||
error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
|
||||
err++;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX is there anything we can do if err != 0 ? */
|
||||
Glib::Mutex::Lock lm (capture_info_lock);
|
||||
|
||||
if (capture_info.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (abort_capture) {
|
||||
|
||||
list<Source*>* deletion_list = new list<Source*>;
|
||||
|
||||
if (_write_source) {
|
||||
_write_source->mark_for_remove ();
|
||||
_write_source->release ();
|
||||
|
||||
deletion_list->push_back (_write_source);
|
||||
|
||||
_write_source = 0;
|
||||
}
|
||||
|
||||
/* new source set up in "out" below */
|
||||
|
||||
if (!deletion_list->empty()) {
|
||||
DeleteSources (deletion_list);
|
||||
} else {
|
||||
delete deletion_list;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
assert(_write_source);
|
||||
|
||||
for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
|
||||
total_capture += (*ci)->frames;
|
||||
}
|
||||
|
||||
/* figure out the name for this take */
|
||||
|
||||
SMFSource* s = _write_source;
|
||||
|
||||
if (s) {
|
||||
|
||||
srcs.push_back (s);
|
||||
|
||||
cerr << "MidiDiskstream: updating source after capture\n";
|
||||
s->update_header (capture_info.front()->start, when, twhen);
|
||||
|
||||
s->set_captured_for (_name);
|
||||
|
||||
}
|
||||
|
||||
/* Register a new region with the Session that
|
||||
describes the entire source. Do this first
|
||||
so that any sub-regions will obviously be
|
||||
children of this one (later!)
|
||||
*/
|
||||
try {
|
||||
assert(_write_source);
|
||||
region = new MidiRegion (srcs, _write_source->last_capture_start_frame(), total_capture,
|
||||
region_name_from_path (_write_source->name()),
|
||||
0, Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile));
|
||||
|
||||
region->special_set_position (capture_info.front()->start);
|
||||
}
|
||||
|
||||
|
||||
catch (failed_constructor& err) {
|
||||
error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
|
||||
/* XXX what now? */
|
||||
}
|
||||
|
||||
_last_capture_regions.push_back (region);
|
||||
|
||||
// cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
|
||||
|
||||
XMLNode &before = _playlist->get_state();
|
||||
_playlist->freeze ();
|
||||
|
||||
for (buffer_position = _write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
|
||||
|
||||
string region_name;
|
||||
_session.region_name (region_name, _write_source->name(), false);
|
||||
|
||||
// cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
|
||||
|
||||
try {
|
||||
region = new MidiRegion (srcs, buffer_position, (*ci)->frames, region_name);
|
||||
}
|
||||
|
||||
catch (failed_constructor& err) {
|
||||
error << _("MidiDiskstream: could not create region for captured audio!") << endmsg;
|
||||
continue; /* XXX is this OK? */
|
||||
}
|
||||
|
||||
_last_capture_regions.push_back (region);
|
||||
|
||||
// cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
|
||||
|
||||
i_am_the_modifier++;
|
||||
_playlist->add_region (*region, (*ci)->start);
|
||||
i_am_the_modifier--;
|
||||
|
||||
buffer_position += (*ci)->frames;
|
||||
}
|
||||
|
||||
_playlist->thaw ();
|
||||
XMLNode &after = _playlist->get_state();
|
||||
_session.add_command (new MementoCommand<Playlist>(*_playlist, before, after));
|
||||
|
||||
mark_write_completed = true;
|
||||
|
||||
reset_write_sources (mark_write_completed);
|
||||
|
||||
}
|
||||
|
||||
for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
|
||||
delete *ci;
|
||||
}
|
||||
|
||||
capture_info.clear ();
|
||||
capture_start_frame = 0;
|
||||
}
|
||||
|
||||
void
|
||||
MidiDiskstream::finish_capture (bool rec_monitors_input)
|
||||
{
|
||||
was_recording = false;
|
||||
|
||||
if (capture_captured == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Why must we destroy?
|
||||
assert(!destructive());
|
||||
|
||||
CaptureInfo* ci = new CaptureInfo;
|
||||
|
||||
ci->start = capture_start_frame;
|
||||
ci->frames = capture_captured;
|
||||
|
||||
/* XXX theoretical race condition here. Need atomic exchange ?
|
||||
However, the circumstances when this is called right
|
||||
now (either on record-disable or transport_stopped)
|
||||
mean that no actual race exists. I think ...
|
||||
We now have a capture_info_lock, but it is only to be used
|
||||
to synchronize in the transport_stop and the capture info
|
||||
accessors, so that invalidation will not occur (both non-realtime).
|
||||
*/
|
||||
|
||||
// cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
|
||||
|
||||
capture_info.push_back (ci);
|
||||
capture_captured = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -852,12 +1034,8 @@ MidiDiskstream::set_record_enabled (bool yn)
|
|||
return;
|
||||
}
|
||||
|
||||
/* can't rec-enable in destructive mode if transport is before start */
|
||||
|
||||
if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!destructive());
|
||||
|
||||
if (yn && _source_port == 0) {
|
||||
|
||||
/* pick up connections not initiated *from* the IO object
|
||||
|
|
@ -1014,11 +1192,7 @@ MidiDiskstream::set_state (const XMLNode& node)
|
|||
_playlist->set_orig_diskstream_id (_id);
|
||||
}
|
||||
|
||||
if (!destructive() && capture_pending_node) {
|
||||
/* destructive streams have one and only one source per channel,
|
||||
and so they never end up in pending capture in any useful
|
||||
sense.
|
||||
*/
|
||||
if (capture_pending_node) {
|
||||
use_pending_capture_data (*capture_pending_node);
|
||||
}
|
||||
|
||||
|
|
@ -1083,10 +1257,7 @@ MidiDiskstream::use_new_write_source (uint32_t n)
|
|||
}
|
||||
|
||||
_write_source->use ();
|
||||
|
||||
/* do not remove destructive files even if they are empty */
|
||||
|
||||
_write_source->set_allow_remove_if_empty (!destructive());
|
||||
_write_source->set_allow_remove_if_empty (true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1098,29 +1269,11 @@ MidiDiskstream::reset_write_sources (bool mark_write_complete, bool force)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!destructive()) {
|
||||
|
||||
if (_write_source && mark_write_complete) {
|
||||
_write_source->mark_streaming_write_completed ();
|
||||
}
|
||||
use_new_write_source ();
|
||||
|
||||
} else {
|
||||
if (_write_source == 0) {
|
||||
use_new_write_source ();
|
||||
}
|
||||
}
|
||||
|
||||
if (destructive()) {
|
||||
|
||||
/* we now have all our write sources set up, so create the
|
||||
playlist's single region.
|
||||
*/
|
||||
|
||||
if (_playlist->empty()) {
|
||||
setup_destructive_playlist ();
|
||||
}
|
||||
if (_write_source && mark_write_complete) {
|
||||
_write_source->mark_streaming_write_completed ();
|
||||
}
|
||||
use_new_write_source ();
|
||||
assert(_write_source);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
RegionList::iterator x;
|
||||
|
||||
AudioRegionList::iterator x;
|
||||
for (x = regions.begin(); x != regions.end(); ++x) {
|
||||
|
||||
for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
|
||||
if (region->region_list_equivalent (*x->second)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
oar = dynamic_cast<AudioRegion*> (x->second);
|
||||
if (x == regions.end()) {
|
||||
|
||||
if (ar->region_list_equivalent (*oar)) {
|
||||
break;
|
||||
}
|
||||
pair<RegionList::key_type,RegionList::mapped_type> entry;
|
||||
|
||||
entry.first = region->id();
|
||||
entry.second = region;
|
||||
|
||||
pair<RegionList::iterator,bool> x = regions.insert (entry);
|
||||
|
||||
if (!x.second) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x == audio_regions.end()) {
|
||||
added = true;
|
||||
}
|
||||
|
||||
pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
|
||||
|
||||
entry.first = region->id();
|
||||
entry.second = ar;
|
||||
|
||||
pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
|
||||
|
||||
if (!x.second) {
|
||||
return;
|
||||
}
|
||||
|
||||
added = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
fatal << _("programming error: ")
|
||||
<< X_("unknown region type passed to Session::add_region()")
|
||||
<< endmsg;
|
||||
/*NOTREACHED*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,8 +63,11 @@
|
|||
#include <ardour/midi_diskstream.h>
|
||||
#include <ardour/utils.h>
|
||||
#include <ardour/audioplaylist.h>
|
||||
#include <ardour/midi_playlist.h>
|
||||
#include <ardour/smf_source.h>
|
||||
#include <ardour/audiofilesource.h>
|
||||
#include <ardour/destructive_filesource.h>
|
||||
#include <ardour/midi_source.h>
|
||||
#include <ardour/sndfile_helpers.h>
|
||||
#include <ardour/auditioner.h>
|
||||
#include <ardour/export.h>
|
||||
|
|
@ -82,6 +85,7 @@
|
|||
#include <ardour/version.h>
|
||||
#include <ardour/location.h>
|
||||
#include <ardour/audioregion.h>
|
||||
#include <ardour/midi_region.h>
|
||||
#include <ardour/crossfade.h>
|
||||
#include <ardour/control_protocol_manager.h>
|
||||
|
||||
|
|
@ -264,7 +268,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
|||
/* These are all static "per-class" signals */
|
||||
|
||||
Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
|
||||
AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
|
||||
Source::SourceCreated.connect (mem_fun (*this, &Session::add_source));
|
||||
Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
|
||||
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
|
||||
Diskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
|
||||
|
|
@ -1348,26 +1352,19 @@ Session::state(bool full_state)
|
|||
child = node->add_child ("Sources");
|
||||
|
||||
if (full_state) {
|
||||
Glib::Mutex::Lock sl (audio_source_lock);
|
||||
Glib::Mutex::Lock sl (source_lock);
|
||||
|
||||
for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
|
||||
for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
|
||||
|
||||
/* Don't save information about AudioFileSources that are empty */
|
||||
|
||||
AudioFileSource* fs;
|
||||
|
||||
if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) {
|
||||
DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
|
||||
DestructiveFileSource* const dfs = dynamic_cast<DestructiveFileSource*> (siter->second);
|
||||
|
||||
/* destructive file sources are OK if they are empty, because
|
||||
we will re-use them every time.
|
||||
*/
|
||||
/* Don't save sources that are empty, unless they're destructive (which are OK
|
||||
if they are empty, because we will re-use them every time.)
|
||||
*/
|
||||
|
||||
if (!dfs) {
|
||||
if (fs->length() == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( ! dfs && siter->second->length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
child->add_child_nocopy (siter->second->get_state());
|
||||
|
|
@ -1379,7 +1376,7 @@ Session::state(bool full_state)
|
|||
if (full_state) {
|
||||
Glib::Mutex::Lock rl (region_lock);
|
||||
|
||||
for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
|
||||
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
|
||||
/* only store regions not attached to playlists */
|
||||
|
||||
|
|
@ -1769,7 +1766,7 @@ Session::load_regions (const XMLNode& node)
|
|||
{
|
||||
XMLNodeList nlist;
|
||||
XMLNodeConstIterator niter;
|
||||
AudioRegion* region;
|
||||
Region* region;
|
||||
|
||||
nlist = node.children();
|
||||
|
||||
|
|
@ -1783,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)
|
||||
{
|
||||
try {
|
||||
return new AudioPlaylist (*this, node);
|
||||
}
|
||||
const XMLProperty* type = node.property("type");
|
||||
|
||||
catch (failed_constructor& err) {
|
||||
try {
|
||||
|
||||
if ( !type || type->value() == "audio" ) {
|
||||
|
||||
return new AudioPlaylist (*this, node);
|
||||
|
||||
} else if (type->value() == "midi") {
|
||||
|
||||
return new MidiPlaylist (*this, node);
|
||||
|
||||
}
|
||||
|
||||
} catch (failed_constructor& err) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -2961,9 +3060,9 @@ Session::cleanup_sources (Session::cleanup_report& rep)
|
|||
rep.paths.clear ();
|
||||
rep.space = 0;
|
||||
|
||||
for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
|
||||
for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
|
||||
|
||||
AudioSourceList::iterator tmp;
|
||||
SourceList::iterator tmp;
|
||||
|
||||
tmp = i;
|
||||
++tmp;
|
||||
|
|
@ -2980,7 +3079,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
|
|||
adding it to the list of all sources below
|
||||
*/
|
||||
|
||||
audio_sources.erase (i);
|
||||
sources.erase (i);
|
||||
}
|
||||
|
||||
i = tmp;
|
||||
|
|
@ -2993,19 +3092,18 @@ Session::cleanup_sources (Session::cleanup_report& rep)
|
|||
|
||||
for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
|
||||
|
||||
for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
|
||||
AudioRegionList::iterator tmp;
|
||||
AudioRegion* ar;
|
||||
for (RegionList::iterator r = regions.begin(); r != regions.end(); ) {
|
||||
RegionList::iterator tmp;
|
||||
|
||||
tmp = r;
|
||||
++tmp;
|
||||
|
||||
ar = r->second;
|
||||
Region* const reg = r->second;
|
||||
|
||||
for (uint32_t n = 0; n < ar->n_channels(); ++n) {
|
||||
if (&ar->source (n) == (*i)) {
|
||||
for (uint32_t n = 0; n < reg->n_channels(); ++n) {
|
||||
if (®->source (n) == (*i)) {
|
||||
/* this region is dead */
|
||||
remove_region (ar);
|
||||
remove_region (reg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3050,7 +3148,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
|
|||
/* add our current source list
|
||||
*/
|
||||
|
||||
for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
|
||||
for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
|
||||
AudioFileSource* fs;
|
||||
|
||||
if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue