From 79fc27de2ef9db51a8c7c69764b663a9921c5a40 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 1 Aug 2006 17:19:38 +0000 Subject: Mostly Cosmetic/Design changes to bring trunk and midi branch closer git-svn-id: svn://localhost/ardour2/branches/midi@733 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/SConscript | 6 +- gtk2_ardour/analysis_window.cc | 2 +- gtk2_ardour/ardour_ui.cc | 6 +- gtk2_ardour/ardour_ui.h | 2 +- gtk2_ardour/audio_region_editor.cc | 2 +- gtk2_ardour/audio_region_view.cc | 1103 +++++++++++++++++++++++++ gtk2_ardour/audio_region_view.h | 166 ++++ gtk2_ardour/audio_regionview.cc | 1105 -------------------------- gtk2_ardour/audio_regionview.h | 166 ---- gtk2_ardour/audio_streamview.cc | 4 +- gtk2_ardour/audio_time_axis.cc | 2 +- gtk2_ardour/crossfade_view.cc | 2 +- gtk2_ardour/editor.cc | 2 +- gtk2_ardour/editor_audiotrack.cc | 2 +- gtk2_ardour/editor_canvas_events.cc | 8 +- gtk2_ardour/editor_export_audio.cc | 2 +- gtk2_ardour/editor_keyboard.cc | 2 +- gtk2_ardour/editor_keys.cc | 2 +- gtk2_ardour/editor_mouse.cc | 15 +- gtk2_ardour/editor_ops.cc | 18 +- gtk2_ardour/editor_route_list.cc | 6 +- gtk2_ardour/editor_timefx.cc | 2 +- gtk2_ardour/midi_streamview.cc | 2 +- gtk2_ardour/midi_time_axis.cc | 2 +- gtk2_ardour/mixer_strip.cc | 2 +- gtk2_ardour/mixer_strip.h | 2 +- gtk2_ardour/region_gain_line.cc | 2 +- gtk2_ardour/region_selection.cc | 2 +- gtk2_ardour/region_view.cc | 476 +++++++++++ gtk2_ardour/region_view.h | 140 ++++ gtk2_ardour/regionview.cc | 476 ----------- gtk2_ardour/regionview.h | 140 ---- gtk2_ardour/route_time_axis.cc | 4 +- gtk2_ardour/route_time_axis.h | 2 +- gtk2_ardour/route_ui.cc | 2 +- gtk2_ardour/route_ui.h | 2 +- gtk2_ardour/selection.cc | 2 +- gtk2_ardour/streamview.cc | 6 +- gtk2_ardour/streamview.h | 4 +- gtk2_ardour/tape_region_view.cc | 101 +++ gtk2_ardour/tape_region_view.h | 47 ++ gtk2_ardour/taperegionview.cc | 101 --- gtk2_ardour/taperegionview.h | 47 -- libs/ardour/SConscript | 1 - libs/ardour/ardour/audio_diskstream.h | 21 +- libs/ardour/ardour/audio_track.h | 10 - libs/ardour/ardour/audioengine.h | 6 +- libs/ardour/ardour/audioregion.h | 79 +- libs/ardour/ardour/buffer.h | 36 +- libs/ardour/ardour/diskstream.h | 49 +- libs/ardour/ardour/io.h | 12 +- libs/ardour/ardour/midi_diskstream.h | 4 +- libs/ardour/ardour/midi_region.h | 4 - libs/ardour/ardour/midi_track.h | 2 +- libs/ardour/ardour/playlist.h | 1 - libs/ardour/ardour/region.h | 96 +-- libs/ardour/ardour/route.h | 4 +- libs/ardour/ardour/route_group.h | 3 +- libs/ardour/ardour/route_group_specialized.h | 6 +- libs/ardour/ardour/session.h | 25 +- libs/ardour/ardour/track.h | 25 +- libs/ardour/ardour/types.h | 6 + libs/ardour/audio_diskstream.cc | 73 +- libs/ardour/audio_track.cc | 92 +-- libs/ardour/audioengine.cc | 6 +- libs/ardour/audioregion.cc | 16 +- libs/ardour/auditioner.cc | 6 +- libs/ardour/diskstream.cc | 6 +- libs/ardour/io.cc | 20 +- libs/ardour/midi_diskstream.cc | 4 +- libs/ardour/midi_track.cc | 16 +- libs/ardour/region.cc | 12 +- libs/ardour/route.cc | 6 +- libs/ardour/session.cc | 37 +- libs/ardour/session_state.cc | 7 +- libs/ardour/smpte.cc | 405 ---------- libs/ardour/track.cc | 91 ++- 77 files changed, 2436 insertions(+), 2938 deletions(-) create mode 100644 gtk2_ardour/audio_region_view.cc create mode 100644 gtk2_ardour/audio_region_view.h delete mode 100644 gtk2_ardour/audio_regionview.cc delete mode 100644 gtk2_ardour/audio_regionview.h create mode 100644 gtk2_ardour/region_view.cc create mode 100644 gtk2_ardour/region_view.h delete mode 100644 gtk2_ardour/regionview.cc delete mode 100644 gtk2_ardour/regionview.h create mode 100644 gtk2_ardour/tape_region_view.cc create mode 100644 gtk2_ardour/tape_region_view.h delete mode 100644 gtk2_ardour/taperegionview.cc delete mode 100644 gtk2_ardour/taperegionview.h delete mode 100644 libs/ardour/smpte.cc diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 11cb8fcbce..827fd1ac56 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -162,9 +162,9 @@ redirect_automation_time_axis.cc redirect_box.cc region_gain_line.cc region_selection.cc -regionview.cc -audio_regionview.cc -taperegionview.cc +region_view.cc +audio_region_view.cc +tape_region_view.cc route_params_ui.cc route_redirect_selection.cc route_ui.cc diff --git a/gtk2_ardour/analysis_window.cc b/gtk2_ardour/analysis_window.cc index 9d9e928312..551e0b7d6d 100644 --- a/gtk2_ardour/analysis_window.cc +++ b/gtk2_ardour/analysis_window.cc @@ -35,7 +35,7 @@ #include "time_axis_view.h" #include "public_editor.h" #include "selection.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "i18n.h" diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 16a9be8faf..58b48d3d15 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1201,7 +1201,7 @@ ARDOUR_UI::toggle_record_enable (uint32_t dstream) Track* t; if ((t = dynamic_cast(r.get())) != 0) { - t->diskstream().set_record_enabled (!t->diskstream().record_enabled(), this); + t->diskstream().set_record_enabled (!t->diskstream().record_enabled()); } } if (session == 0) { @@ -2186,11 +2186,11 @@ ARDOUR_UI::halt_on_xrun_message () } void -ARDOUR_UI::delete_sources_in_the_right_thread (list* deletion_list) +ARDOUR_UI::delete_sources_in_the_right_thread (list* deletion_list) { ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list)); - for (list::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) { + for (list::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) { delete *i; } diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index ab2db06090..0af88eec18 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -647,7 +647,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI struct timeval last_peak_grab; struct timeval last_shuttle_request; - void delete_sources_in_the_right_thread (list*); + void delete_sources_in_the_right_thread (list*); void editor_display_control_changed (Editing::DisplayControl c); diff --git a/gtk2_ardour/audio_region_editor.cc b/gtk2_ardour/audio_region_editor.cc index b3e2edb126..194f358b42 100644 --- a/gtk2_ardour/audio_region_editor.cc +++ b/gtk2_ardour/audio_region_editor.cc @@ -25,7 +25,7 @@ #include #include "audio_region_editor.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "ardour_ui.h" #include "utils.h" #include "gui_thread.h" diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc new file mode 100644 index 0000000000..1aa214f52c --- /dev/null +++ b/gtk2_ardour/audio_region_view.cc @@ -0,0 +1,1103 @@ +/* + Copyright (C) 2001-2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "streamview.h" +#include "audio_region_view.h" +#include "audio_time_axis.h" +#include "simplerect.h" +#include "simpleline.h" +#include "waveview.h" +#include "public_editor.h" +#include "audio_region_editor.h" +#include "region_gain_line.h" +#include "ghostregion.h" +#include "audio_time_axis.h" +#include "utils.h" +#include "rgb_macros.h" +#include "gui_thread.h" + +#include "i18n.h" + +using namespace sigc; +using namespace ARDOUR; +using namespace PBD; +using namespace Editing; +using namespace ArdourCanvas; + +static const int32_t sync_mark_width = 9; + +AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu, + Gdk::Color& basic_color) + : RegionView (parent, tv, r, spu, basic_color) +{ +} + +AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu, + Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility) + : RegionView (parent, tv, r, spu, basic_color, visibility) +{ +} + +void +AudioRegionView::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); + + XMLNode *node; + + _amplitude_above_axis = 1.0; + zero_line = 0; + _flags = 0; + + if ((node = _region.extra_xml ("GUI")) != 0) { + set_flags (node); + } else { + _flags = WaveformVisible; + store_flags (); + } + + if (trackview.editor.new_regionviews_display_gain()) { + _flags |= EnvelopeVisible; + } + + compute_colors (basic_color); + + create_waves (); + + fade_in_shape = new ArdourCanvas::Polygon (*group); + fade_in_shape->property_fill_color_rgba() = fade_color; + fade_in_shape->set_data ("regionview", this); + + fade_out_shape = new ArdourCanvas::Polygon (*group); + fade_out_shape->property_fill_color_rgba() = fade_color; + fade_out_shape->set_data ("regionview", this); + + + { + uint32_t r,g,b,a; + UINT_TO_RGBA(fill_color,&r,&g,&b,&a); + + + fade_in_handle = new ArdourCanvas::SimpleRect (*group); + fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0); + fade_in_handle->property_outline_pixels() = 0; + fade_in_handle->property_y1() = 2.0; + fade_in_handle->property_y2() = 7.0; + + fade_in_handle->set_data ("regionview", this); + + fade_out_handle = new ArdourCanvas::SimpleRect (*group); + fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0); + fade_out_handle->property_outline_pixels() = 0; + fade_out_handle->property_y1() = 2.0; + fade_out_handle->property_y2() = 7.0; + + fade_out_handle->set_data ("regionview", this); + } + + string foo = _region.name(); + foo += ':'; + foo += "gain"; + + gain_line = new AudioRegionGainLine (foo, trackview.session(), *this, *group, audio_region().envelope()); + + if (!(_flags & EnvelopeVisible)) { + gain_line->hide (); + } else { + gain_line->show (); + } + + reset_width_dependent_items ((double) _region.length() / samples_per_unit); + + gain_line->reset (); + + set_height (trackview.height); + + region_muted (); + region_sync_changed (); + region_resized (BoundsChanged); + set_waveview_data_src(); + region_locked (); + envelope_active_changed (); + fade_in_active_changed (); + fade_out_active_changed (); + + _region.StateChanged.connect (mem_fun(*this, &AudioRegionView::region_changed)); + + fade_in_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_event), fade_in_shape, this)); + fade_in_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_handle_event), fade_in_handle, this)); + fade_out_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_event), fade_out_shape, this)); + fade_out_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_handle_event), fade_out_handle, this)); + + set_colors (); + + /* XXX sync mark drag? */ +} + +AudioRegionView::~AudioRegionView () +{ + in_destructor = true; + + RegionViewGoingAway (this); /* EMIT_SIGNAL */ + + for (vector::iterator cache = wave_caches.begin(); cache != wave_caches.end() ; ++cache) { + gnome_canvas_waveview_cache_destroy (*cache); + } + + /* all waveviews etc will be destroyed when the group is destroyed */ + + if (gain_line) { + delete gain_line; + } +} + +ARDOUR::AudioRegion& +AudioRegionView::audio_region() const +{ + // "Guaranteed" to succeed... + return dynamic_cast(_region); +} + +void +AudioRegionView::region_changed (Change what_changed) +{ + ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioRegionView::region_changed), what_changed)); + + RegionView::region_changed(what_changed); + + if (what_changed & AudioRegion::ScaleAmplitudeChanged) { + region_scale_amplitude_changed (); + } + if (what_changed & AudioRegion::FadeInChanged) { + fade_in_changed (); + } + if (what_changed & AudioRegion::FadeOutChanged) { + fade_out_changed (); + } + if (what_changed & AudioRegion::FadeInActiveChanged) { + fade_in_active_changed (); + } + if (what_changed & AudioRegion::FadeOutActiveChanged) { + fade_out_active_changed (); + } + if (what_changed & AudioRegion::EnvelopeActiveChanged) { + envelope_active_changed (); + } +} + +void +AudioRegionView::fade_in_changed () +{ + reset_fade_in_shape (); +} + +void +AudioRegionView::fade_out_changed () +{ + reset_fade_out_shape (); +} + +void +AudioRegionView::set_fade_in_active (bool yn) +{ + audio_region().set_fade_in_active (yn); +} + +void +AudioRegionView::set_fade_out_active (bool yn) +{ + audio_region().set_fade_out_active (yn); +} + +void +AudioRegionView::fade_in_active_changed () +{ + uint32_t r,g,b,a; + uint32_t col; + UINT_TO_RGBA(fade_color,&r,&g,&b,&a); + + if (audio_region().fade_in_active()) { + col = RGBA_TO_UINT(r,g,b,120); + fade_in_shape->property_fill_color_rgba() = col; + fade_in_shape->property_width_pixels() = 0; + fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0); + } else { + col = RGBA_TO_UINT(r,g,b,0); + fade_in_shape->property_fill_color_rgba() = col; + fade_in_shape->property_width_pixels() = 1; + fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255); + } +} + +void +AudioRegionView::fade_out_active_changed () +{ + uint32_t r,g,b,a; + uint32_t col; + UINT_TO_RGBA(fade_color,&r,&g,&b,&a); + + if (audio_region().fade_out_active()) { + col = RGBA_TO_UINT(r,g,b,120); + fade_out_shape->property_fill_color_rgba() = col; + fade_out_shape->property_width_pixels() = 0; + fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0); + } else { + col = RGBA_TO_UINT(r,g,b,0); + fade_out_shape->property_fill_color_rgba() = col; + fade_out_shape->property_width_pixels() = 1; + fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255); + } +} + + +void +AudioRegionView::region_scale_amplitude_changed () +{ + ENSURE_GUI_THREAD (mem_fun(*this, &AudioRegionView::region_scale_amplitude_changed)); + + for (uint32_t n = 0; n < waves.size(); ++n) { + // force a reload of the cache + waves[n]->property_data_src() = &_region; + } +} + +void +AudioRegionView::region_resized (Change what_changed) +{ + RegionView::region_resized(what_changed); + + if (what_changed & Change (StartChanged|LengthChanged)) { + + for (uint32_t n = 0; n < waves.size(); ++n) { + waves[n]->property_region_start() = _region.start(); + } + + for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + + for (vector::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) { + (*w)->property_region_start() = _region.start(); + } + } + } +} + +void +AudioRegionView::reset_width_dependent_items (double pixel_width) +{ + RegionView::reset_width_dependent_items(pixel_width); + assert(_pixel_width == pixel_width); + + if (zero_line) { + zero_line->property_x2() = pixel_width - 1.0; + } + + if (fade_in_handle) { + if (pixel_width <= 6.0) { + fade_in_handle->hide(); + fade_out_handle->hide(); + } else { + if (_height < 5.0) { + fade_in_handle->hide(); + fade_out_handle->hide(); + } else { + fade_in_handle->show(); + fade_out_handle->show(); + } + } + } + + reset_fade_shapes (); +} + +void +AudioRegionView::region_muted () +{ + RegionView::region_muted(); + + for (uint32_t n=0; n < waves.size(); ++n) { + if (_region.muted()) { + waves[n]->property_wave_color() = color_map[cMutedWaveForm]; + } else { + waves[n]->property_wave_color() = color_map[cWaveForm]; + } + } +} + + +void +AudioRegionView::set_height (gdouble height) +{ + uint32_t wcnt = waves.size(); + + // FIXME: ick + TimeAxisViewItem::set_height (height - 2); + + _height = height; + + for (uint32_t n=0; n < wcnt; ++n) { + gdouble ht; + + if ((height) <= NAME_HIGHLIGHT_THRESH) { + ht = ((height-2*wcnt) / (double) wcnt); + } else { + ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt); + } + + gdouble yoff = n * (ht+1); + + waves[n]->property_height() = ht; + waves[n]->property_y() = yoff + 2; + } + + if (gain_line) { + if ((height/wcnt) < NAME_HIGHLIGHT_SIZE) { + gain_line->hide (); + } else { + if (_flags & EnvelopeVisible) { + gain_line->show (); + } + } + gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE)); + } + + manage_zero_line (); + reset_fade_shapes (); + + if (name_text) { + name_text->raise_to_top(); + } +} + +void +AudioRegionView::manage_zero_line () +{ + if (!zero_line) { + return; + } + + if (_height >= 100) { + gdouble wave_midpoint = (_height - NAME_HIGHLIGHT_SIZE) / 2.0; + zero_line->property_y1() = wave_midpoint; + zero_line->property_y2() = wave_midpoint; + zero_line->show(); + } else { + zero_line->hide(); + } +} + +void +AudioRegionView::reset_fade_shapes () +{ + reset_fade_in_shape (); + reset_fade_out_shape (); +} + +void +AudioRegionView::reset_fade_in_shape () +{ + reset_fade_in_shape_width ((jack_nframes_t) audio_region().fade_in().back()->when); +} + +void +AudioRegionView::reset_fade_in_shape_width (jack_nframes_t width) +{ + if (fade_in_handle == 0) { + return; + } + + /* smallest size for a fade is 64 frames */ + + width = std::max ((jack_nframes_t) 64, width); + + Points* points; + double pwidth = width / samples_per_unit; + uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth); + double h; + + if (_height < 5) { + fade_in_shape->hide(); + fade_in_handle->hide(); + return; + } + + double handle_center; + handle_center = pwidth; + + if (handle_center > 7.0) { + handle_center -= 3.0; + } else { + handle_center = 3.0; + } + + fade_in_handle->property_x1() = handle_center - 3.0; + fade_in_handle->property_x2() = handle_center + 3.0; + + if (pwidth < 5) { + fade_in_shape->hide(); + return; + } + + fade_in_shape->show(); + + float curve[npoints]; + audio_region().fade_in().get_vector (0, audio_region().fade_in().back()->when, curve, npoints); + + points = get_canvas_points ("fade in shape", npoints+3); + + if (_height > NAME_HIGHLIGHT_THRESH) { + h = _height - NAME_HIGHLIGHT_SIZE; + } else { + h = _height; + } + + /* points *MUST* be in anti-clockwise order */ + + uint32_t pi, pc; + double xdelta = pwidth/npoints; + + for (pi = 0, pc = 0; pc < npoints; ++pc) { + (*points)[pi].set_x(1 + (pc * xdelta)); + (*points)[pi++].set_y(2 + (h - (curve[pc] * h))); + } + + /* fold back */ + + (*points)[pi].set_x(pwidth); + (*points)[pi++].set_y(2); + + (*points)[pi].set_x(1); + (*points)[pi++].set_y(2); + + /* connect the dots ... */ + + (*points)[pi] = (*points)[0]; + + fade_in_shape->property_points() = *points; + delete points; +} + +void +AudioRegionView::reset_fade_out_shape () +{ + reset_fade_out_shape_width ((jack_nframes_t) audio_region().fade_out().back()->when); +} + +void +AudioRegionView::reset_fade_out_shape_width (jack_nframes_t width) +{ + if (fade_out_handle == 0) { + return; + } + + /* smallest size for a fade is 64 frames */ + + width = std::max ((jack_nframes_t) 64, width); + + Points* points; + double pwidth = width / samples_per_unit; + uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth); + double h; + + if (_height < 5) { + fade_out_shape->hide(); + fade_out_handle->hide(); + return; + } + + double handle_center; + handle_center = (_region.length() - width) / samples_per_unit; + + if (handle_center > 7.0) { + handle_center -= 3.0; + } else { + handle_center = 3.0; + } + + fade_out_handle->property_x1() = handle_center - 3.0; + fade_out_handle->property_x2() = handle_center + 3.0; + + /* don't show shape if its too small */ + + if (pwidth < 5) { + fade_out_shape->hide(); + return; + } + + fade_out_shape->show(); + + float curve[npoints]; + audio_region().fade_out().get_vector (0, audio_region().fade_out().back()->when, curve, npoints); + + if (_height > NAME_HIGHLIGHT_THRESH) { + h = _height - NAME_HIGHLIGHT_SIZE; + } else { + h = _height; + } + + /* points *MUST* be in anti-clockwise order */ + + points = get_canvas_points ("fade out shape", npoints+3); + + uint32_t pi, pc; + double xdelta = pwidth/npoints; + + for (pi = 0, pc = 0; pc < npoints; ++pc) { + (*points)[pi].set_x(_pixel_width - 1 - pwidth + (pc*xdelta)); + (*points)[pi++].set_y(2 + (h - (curve[pc] * h))); + } + + /* fold back */ + + (*points)[pi].set_x(_pixel_width); + (*points)[pi++].set_y(h); + + (*points)[pi].set_x(_pixel_width); + (*points)[pi++].set_y(2); + + /* connect the dots ... */ + + (*points)[pi] = (*points)[0]; + + fade_out_shape->property_points() = *points; + delete points; +} + +void +AudioRegionView::set_samples_per_unit (gdouble spu) +{ + RegionView::set_samples_per_unit (spu); + + for (uint32_t n=0; n < waves.size(); ++n) { + waves[n]->property_samples_per_unit() = spu; + } + + if (gain_line) { + gain_line->reset (); + } + reset_fade_shapes (); +} + +void +AudioRegionView::set_amplitude_above_axis (gdouble spp) +{ + for (uint32_t n=0; n < waves.size(); ++n) { + waves[n]->property_amplitude_above_axis() = spp; + } +} + +void +AudioRegionView::compute_colors (Gdk::Color& basic_color) +{ + RegionView::compute_colors(basic_color); + + uint32_t r, g, b, a; + + /* gain color computed in envelope_active_changed() */ + + UINT_TO_RGBA (fill_color, &r, &g, &b, &a); + fade_color = RGBA_TO_UINT(r,g,b,120); +} + +void +AudioRegionView::set_colors () +{ + RegionView::set_colors(); + + if (gain_line) { + gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]); + } + + for (uint32_t n=0; n < waves.size(); ++n) { + if (_region.muted()) { + waves[n]->property_wave_color() = color_map[cMutedWaveForm]; + } else { + waves[n]->property_wave_color() = color_map[cWaveForm]; + } + } +} + +void +AudioRegionView::show_region_editor () +{ + if (editor == 0) { + editor = new AudioRegionEditor (trackview.session(), audio_region(), *this); + // GTK2FIX : how to ensure float without realizing + // editor->realize (); + // trackview.editor.ensure_float (*editor); + } + + editor->show_all (); + editor->get_window()->raise(); +} + +void +AudioRegionView::set_waveform_visible (bool yn) +{ + if (((_flags & WaveformVisible) != yn)) { + if (yn) { + for (uint32_t n=0; n < waves.size(); ++n) { + waves[n]->show(); + } + _flags |= WaveformVisible; + } else { + for (uint32_t n=0; n < waves.size(); ++n) { + waves[n]->hide(); + } + _flags &= ~WaveformVisible; + } + store_flags (); + } +} + +void +AudioRegionView::temporarily_hide_envelope () +{ + if (gain_line) { + gain_line->hide (); + } +} + +void +AudioRegionView::unhide_envelope () +{ + if (gain_line && (_flags & EnvelopeVisible)) { + gain_line->show (); + } +} + +void +AudioRegionView::set_envelope_visible (bool yn) +{ + if (gain_line && ((_flags & EnvelopeVisible) != yn)) { + if (yn) { + gain_line->show (); + _flags |= EnvelopeVisible; + } else { + gain_line->hide (); + _flags &= ~EnvelopeVisible; + } + store_flags (); + } +} + +void +AudioRegionView::create_waves () +{ + bool create_zero_line = true; + + RouteTimeAxisView& atv (*(dynamic_cast(&trackview))); // ick + + if (!atv.get_diskstream()) { + return; + } + + uint32_t nchans = atv.get_diskstream()->n_channels(); + + /* in tmp_waves, set up null pointers for each channel so the vector is allocated */ + for (uint32_t n = 0; n < nchans; ++n) { + tmp_waves.push_back (0); + } + + for (uint32_t n = 0; n < nchans; ++n) { + + if (n >= audio_region().n_channels()) { + break; + } + + wave_caches.push_back (WaveView::create_cache ()); + + if (wait_for_data) { + if (audio_region().source(n).peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) { + create_one_wave (n, true); + } else { + create_zero_line = false; + } + } else { + create_one_wave (n, true); + } + } + + if (create_zero_line) { + zero_line = new ArdourCanvas::SimpleLine (*group); + zero_line->property_x1() = (gdouble) 1.0; + zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0; + zero_line->property_color_rgba() = (guint) color_map[cZeroLine]; + manage_zero_line (); + } +} + +void +AudioRegionView::create_one_wave (uint32_t which, bool direct) +{ + RouteTimeAxisView& atv (*(dynamic_cast(&trackview))); // ick + uint32_t nchans = atv.get_diskstream()->n_channels(); + uint32_t n; + uint32_t nwaves = std::min (nchans, audio_region().n_channels()); + gdouble ht; + + if (trackview.height < NAME_HIGHLIGHT_SIZE) { + ht = ((trackview.height) / (double) nchans); + } else { + ht = ((trackview.height - NAME_HIGHLIGHT_SIZE) / (double) nchans); + } + + gdouble yoff = which * ht; + + WaveView *wave = new WaveView(*group); + + wave->property_data_src() = (gpointer) &_region; + wave->property_cache() = wave_caches[which]; + wave->property_cache_updater() = true; + wave->property_channel() = which; + wave->property_length_function() = (gpointer) region_length_from_c; + wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c; + wave->property_peak_function() = (gpointer) region_read_peaks_from_c; + wave->property_x() = 0.0; + wave->property_y() = yoff; + wave->property_height() = (double) ht; + wave->property_samples_per_unit() = samples_per_unit; + wave->property_amplitude_above_axis() = _amplitude_above_axis; + wave->property_wave_color() = _region.muted() ? color_map[cMutedWaveForm] : color_map[cWaveForm]; + wave->property_region_start() = _region.start(); + + if (!(_flags & WaveformVisible)) { + wave->hide(); + } + + /* note: calling this function is serialized by the lock + held in the peak building thread that signals that + peaks are ready for use *or* by the fact that it is + called one by one from the GUI thread. + */ + + if (which < nchans) { + tmp_waves[which] = wave; + } else { + /* n-channel track, >n-channel source */ + } + + /* see if we're all ready */ + + for (n = 0; n < nchans; ++n) { + if (tmp_waves[n] == 0) { + break; + } + } + + if (n == nwaves && waves.empty()) { + /* all waves are ready */ + tmp_waves.resize(nwaves); + + waves = tmp_waves; + tmp_waves.clear (); + + if (!zero_line) { + zero_line = new ArdourCanvas::SimpleLine (*group); + zero_line->property_x1() = (gdouble) 1.0; + zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0; + zero_line->property_color_rgba() = (guint) color_map[cZeroLine]; + manage_zero_line (); + } + } +} + +void +AudioRegionView::peaks_ready_handler (uint32_t which) +{ + Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &AudioRegionView::create_one_wave), which, false)); + + if (!waves.empty()) { + /* all waves created, don't hook into peaks ready anymore */ + data_ready_connection.disconnect (); + } +} + +void +AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev) +{ + if (gain_line == 0) { + return; + } + + double x, y; + + /* don't create points that can't be seen */ + + set_envelope_visible (true); + + x = ev->button.x; + y = ev->button.y; + + item->w2i (x, y); + + jack_nframes_t fx = trackview.editor.pixel_to_frame (x); + + if (fx > _region.length()) { + return; + } + + /* compute vertical fractional position */ + + y = 1.0 - (y / (trackview.height - NAME_HIGHLIGHT_SIZE)); + + /* map using gain line */ + + gain_line->view_to_model_y (y); + + trackview.session().begin_reversible_command (_("add gain control point")); + trackview.session().add_undo (audio_region().envelope().get_memento()); + + + if (!audio_region().envelope_active()) { + trackview.session().add_undo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), false) ); + audio_region().set_envelope_active(true); + trackview.session().add_redo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), true) ); + } + + audio_region().envelope().add (fx, y); + + trackview.session().add_redo_no_execute (audio_region().envelope().get_memento()); + trackview.session().commit_reversible_command (); +} + +void +AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev) +{ + ControlPoint *cp = reinterpret_cast (item->get_data ("control_point")); + audio_region().envelope().erase (cp->model); +} + +void +AudioRegionView::store_flags() +{ + XMLNode *node = new XMLNode ("GUI"); + + node->add_property ("waveform-visible", (_flags & WaveformVisible) ? "yes" : "no"); + node->add_property ("envelope-visible", (_flags & EnvelopeVisible) ? "yes" : "no"); + + _region.add_extra_xml (*node); +} + +void +AudioRegionView::set_flags (XMLNode* node) +{ + XMLProperty *prop; + + if ((prop = node->property ("waveform-visible")) != 0) { + if (prop->value() == "yes") { + _flags |= WaveformVisible; + } + } + + if ((prop = node->property ("envelope-visible")) != 0) { + if (prop->value() == "yes") { + _flags |= EnvelopeVisible; + } + } +} + +void +AudioRegionView::set_waveform_shape (WaveformShape shape) +{ + bool yn; + + /* this slightly odd approach is to leave the door open to + other "shapes" such as spectral displays, etc. + */ + + switch (shape) { + case Rectified: + yn = true; + break; + + default: + yn = false; + break; + } + + if (yn != (bool) (_flags & WaveformRectified)) { + for (vector::iterator wave = waves.begin(); wave != waves.end() ; ++wave) { + (*wave)->property_rectified() = yn; + } + + if (zero_line) { + if (yn) { + zero_line->hide(); + } else { + zero_line->show(); + } + } + + if (yn) { + _flags |= WaveformRectified; + } else { + _flags &= ~WaveformRectified; + } + } +} + +GhostRegion* +AudioRegionView::add_ghost (AutomationTimeAxisView& atv) +{ + RouteTimeAxisView& myatv (*(dynamic_cast(&trackview))); // ick + double unit_position = _region.position () / samples_per_unit; + GhostRegion* ghost = new GhostRegion (atv, unit_position); + uint32_t nchans; + + nchans = myatv.get_diskstream()->n_channels(); + + for (uint32_t n = 0; n < nchans; ++n) { + + if (n >= audio_region().n_channels()) { + break; + } + + WaveView *wave = new WaveView(*ghost->group); + + wave->property_data_src() = &_region; + wave->property_cache() = wave_caches[n]; + wave->property_cache_updater() = false; + wave->property_channel() = n; + wave->property_length_function() = (gpointer)region_length_from_c; + wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c; + wave->property_peak_function() = (gpointer) region_read_peaks_from_c; + wave->property_x() = 0.0; + wave->property_samples_per_unit() = samples_per_unit; + wave->property_amplitude_above_axis() = _amplitude_above_axis; + wave->property_wave_color() = color_map[cGhostTrackWave]; + wave->property_region_start() = _region.start(); + + ghost->waves.push_back(wave); + } + + ghost->set_height (); + ghost->set_duration (_region.length() / samples_per_unit); + ghosts.push_back (ghost); + + ghost->GoingAway.connect (mem_fun(*this, &AudioRegionView::remove_ghost)); + + return ghost; +} + +void +AudioRegionView::entered () +{ + if (gain_line && _flags & EnvelopeVisible) { + gain_line->show_all_control_points (); + } + + uint32_t r,g,b,a; + UINT_TO_RGBA(fade_color,&r,&g,&b,&a); + a=255; + + if (fade_in_handle) { + fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); + fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); + } +} + +void +AudioRegionView::exited () +{ + if (gain_line) { + gain_line->hide_all_but_selected_control_points (); + } + + uint32_t r,g,b,a; + UINT_TO_RGBA(fade_color,&r,&g,&b,&a); + a=0; + + if (fade_in_handle) { + fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); + fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); + } +} + +void +AudioRegionView::envelope_active_changed () +{ + if (gain_line) { + gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]); + } +} + +void +AudioRegionView::set_waveview_data_src() +{ + + double unit_length= _region.length() / samples_per_unit; + + for (uint32_t n = 0; n < waves.size(); ++n) { + // TODO: something else to let it know the channel + waves[n]->property_data_src() = &_region; + } + + for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + + (*i)->set_duration (unit_length); + + for (vector::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) { + (*w)->property_data_src() = &_region; + } + } + +} + +void +AudioRegionView::color_handler (ColorID id, uint32_t val) +{ + switch (id) { + case cMutedWaveForm: + case cWaveForm: + set_colors (); + break; + + case cGainLineInactive: + case cGainLine: + envelope_active_changed(); + break; + + case cZeroLine: + if (zero_line) { + zero_line->property_color_rgba() = (guint) color_map[cZeroLine]; + } + break; + + case cGhostTrackWave: + break; + + default: + break; + } +} diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h new file mode 100644 index 0000000000..29b3f9d904 --- /dev/null +++ b/gtk2_ardour/audio_region_view.h @@ -0,0 +1,166 @@ +/* + Copyright (C) 2001-2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __gtk_ardour_audio_region_view_h__ +#define __gtk_ardour_audio_region_view_h__ + +#include + +#include +#include +#include +#include + +#include "region_view.h" +#include "route_time_axis.h" +#include "time_axis_view_item.h" +#include "automation_line.h" +#include "enums.h" +#include "waveview.h" +#include "canvas.h" +#include "color.h" + +namespace ARDOUR { + class AudioRegion; + class PeakData; +}; + +class AudioTimeAxisView; +class AudioRegionGainLine; +class AudioRegionEditor; +class GhostRegion; +class AutomationTimeAxisView; + +class AudioRegionView : public RegionView +{ + public: + AudioRegionView (ArdourCanvas::Group *, + RouteTimeAxisView&, + ARDOUR::AudioRegion&, + double initial_samples_per_unit, + Gdk::Color& basic_color); + + ~AudioRegionView (); + + virtual void init (Gdk::Color& base_color, bool wait_for_data = false); + + ARDOUR::AudioRegion& audio_region() const; + + void set_height (double); + void set_samples_per_unit (double); + + void set_amplitude_above_axis (gdouble spp); + + void temporarily_hide_envelope (); ///< Dangerous! + void unhide_envelope (); ///< Dangerous! + + void set_envelope_visible (bool); + void set_waveform_visible (bool yn); + void set_waveform_shape (WaveformShape); + + bool waveform_rectified() const { return _flags & WaveformRectified; } + bool waveform_visible() const { return _flags & WaveformVisible; } + bool envelope_visible() const { return _flags & EnvelopeVisible; } + + void show_region_editor (); + + void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event); + void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event); + + AudioRegionGainLine* get_gain_line() const { return gain_line; } + + void region_changed (ARDOUR::Change); + void envelope_active_changed (); + + GhostRegion* add_ghost (AutomationTimeAxisView&); + + void reset_fade_in_shape_width (jack_nframes_t); + void reset_fade_out_shape_width (jack_nframes_t); + void set_fade_in_active (bool); + void set_fade_out_active (bool); + + virtual void entered (); + virtual void exited (); + + protected: + + /* this constructor allows derived types + to specify their visibility requirements + to the TimeAxisViewItem parent class + */ + + AudioRegionView (ArdourCanvas::Group *, + RouteTimeAxisView&, + ARDOUR::AudioRegion&, + double samples_per_unit, + Gdk::Color& basic_color, + TimeAxisViewItem::Visibility); + + enum Flags { + EnvelopeVisible = 0x1, + WaveformVisible = 0x4, + WaveformRectified = 0x8 + }; + + vector waves; + vector tmp_waves; ///< see ::create_waves() + ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position + ArdourCanvas::SimpleLine* zero_line; + ArdourCanvas::Polygon* fade_in_shape; + ArdourCanvas::Polygon* fade_out_shape; + ArdourCanvas::SimpleRect* fade_in_handle; + ArdourCanvas::SimpleRect* fade_out_handle; + + AudioRegionGainLine * gain_line; + + double _amplitude_above_axis; + + uint32_t _flags; + uint32_t fade_color; + + void reset_fade_shapes (); + void reset_fade_in_shape (); + void reset_fade_out_shape (); + void fade_in_changed (); + void fade_out_changed (); + void fade_in_active_changed (); + void fade_out_active_changed (); + + void region_resized (ARDOUR::Change); + void region_moved (void *); + void region_muted (); + void region_scale_amplitude_changed (); + + void create_waves (); + void create_one_wave (uint32_t, bool); + void manage_zero_line (); + void peaks_ready_handler (uint32_t); + void set_flags (XMLNode *); + void store_flags (); + + void set_colors (); + void compute_colors (Gdk::Color&); + void reset_width_dependent_items (double pixel_width); + void set_waveview_data_src(); + + vector wave_caches; + + void color_handler (ColorID, uint32_t); +}; + +#endif /* __gtk_ardour_audio_region_view_h__ */ diff --git a/gtk2_ardour/audio_regionview.cc b/gtk2_ardour/audio_regionview.cc deleted file mode 100644 index f22028f33e..0000000000 --- a/gtk2_ardour/audio_regionview.cc +++ /dev/null @@ -1,1105 +0,0 @@ -/* - Copyright (C) 2001-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: regionview.cc 682 2006-07-14 03:43:32Z drobilla $ -*/ - -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include - -#include "streamview.h" -#include "audio_regionview.h" -#include "audio_time_axis.h" -#include "simplerect.h" -#include "simpleline.h" -#include "waveview.h" -#include "public_editor.h" -#include "audio_region_editor.h" -#include "region_gain_line.h" -#include "ghostregion.h" -#include "audio_time_axis.h" -#include "utils.h" -#include "rgb_macros.h" -#include "gui_thread.h" - -#include "i18n.h" - -using namespace sigc; -using namespace ARDOUR; -using namespace PBD; -using namespace Editing; -using namespace ArdourCanvas; - -static const int32_t sync_mark_width = 9; - -AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu, - Gdk::Color& basic_color) - : RegionView (parent, tv, r, spu, basic_color) -{ -} - -AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu, - Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility) - : RegionView (parent, tv, r, spu, basic_color, visibility) -{ -} - -void -AudioRegionView::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); - - XMLNode *node; - - _amplitude_above_axis = 1.0; - zero_line = 0; - _flags = 0; - - if ((node = _region.extra_xml ("GUI")) != 0) { - set_flags (node); - } else { - _flags = WaveformVisible; - store_flags (); - } - - if (trackview.editor.new_regionviews_display_gain()) { - _flags |= EnvelopeVisible; - } - - compute_colors (basic_color); - - create_waves (); - - fade_in_shape = new ArdourCanvas::Polygon (*group); - fade_in_shape->property_fill_color_rgba() = fade_color; - fade_in_shape->set_data ("regionview", this); - - fade_out_shape = new ArdourCanvas::Polygon (*group); - fade_out_shape->property_fill_color_rgba() = fade_color; - fade_out_shape->set_data ("regionview", this); - - - { - uint32_t r,g,b,a; - UINT_TO_RGBA(fill_color,&r,&g,&b,&a); - - - fade_in_handle = new ArdourCanvas::SimpleRect (*group); - fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0); - fade_in_handle->property_outline_pixels() = 0; - fade_in_handle->property_y1() = 2.0; - fade_in_handle->property_y2() = 7.0; - - fade_in_handle->set_data ("regionview", this); - - fade_out_handle = new ArdourCanvas::SimpleRect (*group); - fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0); - fade_out_handle->property_outline_pixels() = 0; - fade_out_handle->property_y1() = 2.0; - fade_out_handle->property_y2() = 7.0; - - fade_out_handle->set_data ("regionview", this); - } - - string foo = _region.name(); - foo += ':'; - foo += "gain"; - - gain_line = new AudioRegionGainLine (foo, trackview.session(), *this, *group, audio_region().envelope()); - - if (!(_flags & EnvelopeVisible)) { - gain_line->hide (); - } else { - gain_line->show (); - } - - reset_width_dependent_items ((double) _region.length() / samples_per_unit); - - gain_line->reset (); - - set_height (trackview.height); - - region_muted (); - region_sync_changed (); - region_resized (BoundsChanged); - set_waveview_data_src(); - region_locked (); - envelope_active_changed (); - fade_in_active_changed (); - fade_out_active_changed (); - - _region.StateChanged.connect (mem_fun(*this, &AudioRegionView::region_changed)); - - fade_in_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_event), fade_in_shape, this)); - fade_in_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_handle_event), fade_in_handle, this)); - fade_out_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_event), fade_out_shape, this)); - fade_out_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_handle_event), fade_out_handle, this)); - - set_colors (); - - /* XXX sync mark drag? */ -} - -AudioRegionView::~AudioRegionView () -{ - in_destructor = true; - - RegionViewGoingAway (this); /* EMIT_SIGNAL */ - - for (vector::iterator cache = wave_caches.begin(); cache != wave_caches.end() ; ++cache) { - gnome_canvas_waveview_cache_destroy (*cache); - } - - /* all waveviews etc will be destroyed when the group is destroyed */ - - if (gain_line) { - delete gain_line; - } -} - -ARDOUR::AudioRegion& -AudioRegionView::audio_region() const -{ - // "Guaranteed" to succeed... - return dynamic_cast(_region); -} - -void -AudioRegionView::region_changed (Change what_changed) -{ - ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioRegionView::region_changed), what_changed)); - - RegionView::region_changed(what_changed); - - if (what_changed & AudioRegion::ScaleAmplitudeChanged) { - region_scale_amplitude_changed (); - } - if (what_changed & AudioRegion::FadeInChanged) { - fade_in_changed (); - } - if (what_changed & AudioRegion::FadeOutChanged) { - fade_out_changed (); - } - if (what_changed & AudioRegion::FadeInActiveChanged) { - fade_in_active_changed (); - } - if (what_changed & AudioRegion::FadeOutActiveChanged) { - fade_out_active_changed (); - } - if (what_changed & AudioRegion::EnvelopeActiveChanged) { - envelope_active_changed (); - } -} - -void -AudioRegionView::fade_in_changed () -{ - reset_fade_in_shape (); -} - -void -AudioRegionView::fade_out_changed () -{ - reset_fade_out_shape (); -} - -void -AudioRegionView::set_fade_in_active (bool yn) -{ - audio_region().set_fade_in_active (yn); -} - -void -AudioRegionView::set_fade_out_active (bool yn) -{ - audio_region().set_fade_out_active (yn); -} - -void -AudioRegionView::fade_in_active_changed () -{ - uint32_t r,g,b,a; - uint32_t col; - UINT_TO_RGBA(fade_color,&r,&g,&b,&a); - - if (audio_region().fade_in_active()) { - col = RGBA_TO_UINT(r,g,b,120); - fade_in_shape->property_fill_color_rgba() = col; - fade_in_shape->property_width_pixels() = 0; - fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0); - } else { - col = RGBA_TO_UINT(r,g,b,0); - fade_in_shape->property_fill_color_rgba() = col; - fade_in_shape->property_width_pixels() = 1; - fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255); - } -} - -void -AudioRegionView::fade_out_active_changed () -{ - uint32_t r,g,b,a; - uint32_t col; - UINT_TO_RGBA(fade_color,&r,&g,&b,&a); - - if (audio_region().fade_out_active()) { - col = RGBA_TO_UINT(r,g,b,120); - fade_out_shape->property_fill_color_rgba() = col; - fade_out_shape->property_width_pixels() = 0; - fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0); - } else { - col = RGBA_TO_UINT(r,g,b,0); - fade_out_shape->property_fill_color_rgba() = col; - fade_out_shape->property_width_pixels() = 1; - fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255); - } -} - - -void -AudioRegionView::region_scale_amplitude_changed () -{ - ENSURE_GUI_THREAD (mem_fun(*this, &AudioRegionView::region_scale_amplitude_changed)); - - for (uint32_t n = 0; n < waves.size(); ++n) { - // force a reload of the cache - waves[n]->property_data_src() = &_region; - } -} - -void -AudioRegionView::region_resized (Change what_changed) -{ - RegionView::region_resized(what_changed); - - if (what_changed & Change (StartChanged|LengthChanged)) { - - for (uint32_t n = 0; n < waves.size(); ++n) { - waves[n]->property_region_start() = _region.start(); - } - - for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { - - for (vector::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) { - (*w)->property_region_start() = _region.start(); - } - } - } -} - -void -AudioRegionView::reset_width_dependent_items (double pixel_width) -{ - RegionView::reset_width_dependent_items(pixel_width); - assert(_pixel_width == pixel_width); - - if (zero_line) { - zero_line->property_x2() = pixel_width - 1.0; - } - - if (fade_in_handle) { - if (pixel_width <= 6.0) { - fade_in_handle->hide(); - fade_out_handle->hide(); - } else { - if (_height < 5.0) { - fade_in_handle->hide(); - fade_out_handle->hide(); - } else { - fade_in_handle->show(); - fade_out_handle->show(); - } - } - } - - reset_fade_shapes (); -} - -void -AudioRegionView::region_muted () -{ - RegionView::region_muted(); - - for (uint32_t n=0; n < waves.size(); ++n) { - if (_region.muted()) { - waves[n]->property_wave_color() = color_map[cMutedWaveForm]; - } else { - waves[n]->property_wave_color() = color_map[cWaveForm]; - } - } -} - - -void -AudioRegionView::set_height (gdouble height) -{ - uint32_t wcnt = waves.size(); - - // FIXME: ick - TimeAxisViewItem::set_height (height - 2); - - _height = height; - - for (uint32_t n=0; n < wcnt; ++n) { - gdouble ht; - - if ((height) <= NAME_HIGHLIGHT_THRESH) { - ht = ((height-2*wcnt) / (double) wcnt); - } else { - ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt); - } - - gdouble yoff = n * (ht+1); - - waves[n]->property_height() = ht; - waves[n]->property_y() = yoff + 2; - } - - if (gain_line) { - if ((height/wcnt) < NAME_HIGHLIGHT_SIZE) { - gain_line->hide (); - } else { - if (_flags & EnvelopeVisible) { - gain_line->show (); - } - } - gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE)); - } - - manage_zero_line (); - reset_fade_shapes (); - - if (name_text) { - name_text->raise_to_top(); - } -} - -void -AudioRegionView::manage_zero_line () -{ - if (!zero_line) { - return; - } - - if (_height >= 100) { - gdouble wave_midpoint = (_height - NAME_HIGHLIGHT_SIZE) / 2.0; - zero_line->property_y1() = wave_midpoint; - zero_line->property_y2() = wave_midpoint; - zero_line->show(); - } else { - zero_line->hide(); - } -} - -void -AudioRegionView::reset_fade_shapes () -{ - reset_fade_in_shape (); - reset_fade_out_shape (); -} - -void -AudioRegionView::reset_fade_in_shape () -{ - reset_fade_in_shape_width ((jack_nframes_t) audio_region().fade_in().back()->when); -} - -void -AudioRegionView::reset_fade_in_shape_width (jack_nframes_t width) -{ - if (fade_in_handle == 0) { - return; - } - - /* smallest size for a fade is 64 frames */ - - width = std::max ((jack_nframes_t) 64, width); - - Points* points; - double pwidth = width / samples_per_unit; - uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth); - double h; - - if (_height < 5) { - fade_in_shape->hide(); - fade_in_handle->hide(); - return; - } - - double handle_center; - handle_center = pwidth; - - if (handle_center > 7.0) { - handle_center -= 3.0; - } else { - handle_center = 3.0; - } - - fade_in_handle->property_x1() = handle_center - 3.0; - fade_in_handle->property_x2() = handle_center + 3.0; - - if (pwidth < 5) { - fade_in_shape->hide(); - return; - } - - fade_in_shape->show(); - - float curve[npoints]; - audio_region().fade_in().get_vector (0, audio_region().fade_in().back()->when, curve, npoints); - - points = get_canvas_points ("fade in shape", npoints+3); - - if (_height > NAME_HIGHLIGHT_THRESH) { - h = _height - NAME_HIGHLIGHT_SIZE; - } else { - h = _height; - } - - /* points *MUST* be in anti-clockwise order */ - - uint32_t pi, pc; - double xdelta = pwidth/npoints; - - for (pi = 0, pc = 0; pc < npoints; ++pc) { - (*points)[pi].set_x(1 + (pc * xdelta)); - (*points)[pi++].set_y(2 + (h - (curve[pc] * h))); - } - - /* fold back */ - - (*points)[pi].set_x(pwidth); - (*points)[pi++].set_y(2); - - (*points)[pi].set_x(1); - (*points)[pi++].set_y(2); - - /* connect the dots ... */ - - (*points)[pi] = (*points)[0]; - - fade_in_shape->property_points() = *points; - delete points; -} - -void -AudioRegionView::reset_fade_out_shape () -{ - reset_fade_out_shape_width ((jack_nframes_t) audio_region().fade_out().back()->when); -} - -void -AudioRegionView::reset_fade_out_shape_width (jack_nframes_t width) -{ - if (fade_out_handle == 0) { - return; - } - - /* smallest size for a fade is 64 frames */ - - width = std::max ((jack_nframes_t) 64, width); - - Points* points; - double pwidth = width / samples_per_unit; - uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth); - double h; - - if (_height < 5) { - fade_out_shape->hide(); - fade_out_handle->hide(); - return; - } - - double handle_center; - handle_center = (_region.length() - width) / samples_per_unit; - - if (handle_center > 7.0) { - handle_center -= 3.0; - } else { - handle_center = 3.0; - } - - fade_out_handle->property_x1() = handle_center - 3.0; - fade_out_handle->property_x2() = handle_center + 3.0; - - /* don't show shape if its too small */ - - if (pwidth < 5) { - fade_out_shape->hide(); - return; - } - - fade_out_shape->show(); - - float curve[npoints]; - audio_region().fade_out().get_vector (0, audio_region().fade_out().back()->when, curve, npoints); - - if (_height > NAME_HIGHLIGHT_THRESH) { - h = _height - NAME_HIGHLIGHT_SIZE; - } else { - h = _height; - } - - /* points *MUST* be in anti-clockwise order */ - - points = get_canvas_points ("fade out shape", npoints+3); - - uint32_t pi, pc; - double xdelta = pwidth/npoints; - - for (pi = 0, pc = 0; pc < npoints; ++pc) { - (*points)[pi].set_x(_pixel_width - 1 - pwidth + (pc*xdelta)); - (*points)[pi++].set_y(2 + (h - (curve[pc] * h))); - } - - /* fold back */ - - (*points)[pi].set_x(_pixel_width); - (*points)[pi++].set_y(h); - - (*points)[pi].set_x(_pixel_width); - (*points)[pi++].set_y(2); - - /* connect the dots ... */ - - (*points)[pi] = (*points)[0]; - - fade_out_shape->property_points() = *points; - delete points; -} - -void -AudioRegionView::set_samples_per_unit (gdouble spu) -{ - RegionView::set_samples_per_unit (spu); - - for (uint32_t n=0; n < waves.size(); ++n) { - waves[n]->property_samples_per_unit() = spu; - } - - if (gain_line) { - gain_line->reset (); - } - reset_fade_shapes (); -} - -void -AudioRegionView::set_amplitude_above_axis (gdouble spp) -{ - for (uint32_t n=0; n < waves.size(); ++n) { - waves[n]->property_amplitude_above_axis() = spp; - } -} - -void -AudioRegionView::compute_colors (Gdk::Color& basic_color) -{ - RegionView::compute_colors(basic_color); - - uint32_t r, g, b, a; - - /* gain color computed in envelope_active_changed() */ - - UINT_TO_RGBA (fill_color, &r, &g, &b, &a); - fade_color = RGBA_TO_UINT(r,g,b,120); -} - -void -AudioRegionView::set_colors () -{ - RegionView::set_colors(); - - if (gain_line) { - gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]); - } - - for (uint32_t n=0; n < waves.size(); ++n) { - if (_region.muted()) { - waves[n]->property_wave_color() = color_map[cMutedWaveForm]; - } else { - waves[n]->property_wave_color() = color_map[cWaveForm]; - } - } -} - -void -AudioRegionView::show_region_editor () -{ - if (editor == 0) { - editor = new AudioRegionEditor (trackview.session(), audio_region(), *this); - // GTK2FIX : how to ensure float without realizing - // editor->realize (); - // trackview.editor.ensure_float (*editor); - } - - editor->show_all (); - editor->get_window()->raise(); -} - -void -AudioRegionView::set_waveform_visible (bool yn) -{ - if (((_flags & WaveformVisible) != yn)) { - if (yn) { - for (uint32_t n=0; n < waves.size(); ++n) { - waves[n]->show(); - } - _flags |= WaveformVisible; - } else { - for (uint32_t n=0; n < waves.size(); ++n) { - waves[n]->hide(); - } - _flags &= ~WaveformVisible; - } - store_flags (); - } -} - -void -AudioRegionView::temporarily_hide_envelope () -{ - if (gain_line) { - gain_line->hide (); - } -} - -void -AudioRegionView::unhide_envelope () -{ - if (gain_line && (_flags & EnvelopeVisible)) { - gain_line->show (); - } -} - -void -AudioRegionView::set_envelope_visible (bool yn) -{ - if (gain_line && ((_flags & EnvelopeVisible) != yn)) { - if (yn) { - gain_line->show (); - _flags |= EnvelopeVisible; - } else { - gain_line->hide (); - _flags &= ~EnvelopeVisible; - } - store_flags (); - } -} - -void -AudioRegionView::create_waves () -{ - bool create_zero_line = true; - - RouteTimeAxisView& atv (*(dynamic_cast(&trackview))); // ick - - if (!atv.get_diskstream()) { - return; - } - - uint32_t nchans = atv.get_diskstream()->n_channels(); - - /* in tmp_waves, set up null pointers for each channel so the vector is allocated */ - for (uint32_t n = 0; n < nchans; ++n) { - tmp_waves.push_back (0); - } - - for (uint32_t n = 0; n < nchans; ++n) { - - if (n >= audio_region().n_channels()) { - break; - } - - wave_caches.push_back (WaveView::create_cache ()); - - if (wait_for_data) { - if (audio_region().source(n).peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) { - create_one_wave (n, true); - } else { - create_zero_line = false; - } - } else { - create_one_wave (n, true); - } - } - - if (create_zero_line) { - zero_line = new ArdourCanvas::SimpleLine (*group); - zero_line->property_x1() = (gdouble) 1.0; - zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0; - zero_line->property_color_rgba() = (guint) color_map[cZeroLine]; - manage_zero_line (); - } -} - -void -AudioRegionView::create_one_wave (uint32_t which, bool direct) -{ - RouteTimeAxisView& atv (*(dynamic_cast(&trackview))); // ick - uint32_t nchans = atv.get_diskstream()->n_channels(); - uint32_t n; - uint32_t nwaves = std::min (nchans, audio_region().n_channels()); - gdouble ht; - - if (trackview.height < NAME_HIGHLIGHT_SIZE) { - ht = ((trackview.height) / (double) nchans); - } else { - ht = ((trackview.height - NAME_HIGHLIGHT_SIZE) / (double) nchans); - } - - gdouble yoff = which * ht; - - WaveView *wave = new WaveView(*group); - - wave->property_data_src() = (gpointer) &_region; - wave->property_cache() = wave_caches[which]; - wave->property_cache_updater() = true; - wave->property_channel() = which; - wave->property_length_function() = (gpointer) region_length_from_c; - wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c; - wave->property_peak_function() = (gpointer) region_read_peaks_from_c; - wave->property_x() = 0.0; - wave->property_y() = yoff; - wave->property_height() = (double) ht; - wave->property_samples_per_unit() = samples_per_unit; - wave->property_amplitude_above_axis() = _amplitude_above_axis; - wave->property_wave_color() = _region.muted() ? color_map[cMutedWaveForm] : color_map[cWaveForm]; - wave->property_region_start() = _region.start(); - - if (!(_flags & WaveformVisible)) { - wave->hide(); - } - - /* note: calling this function is serialized by the lock - held in the peak building thread that signals that - peaks are ready for use *or* by the fact that it is - called one by one from the GUI thread. - */ - - if (which < nchans) { - tmp_waves[which] = wave; - } else { - /* n-channel track, >n-channel source */ - } - - /* see if we're all ready */ - - for (n = 0; n < nchans; ++n) { - if (tmp_waves[n] == 0) { - break; - } - } - - if (n == nwaves && waves.empty()) { - /* all waves are ready */ - tmp_waves.resize(nwaves); - - waves = tmp_waves; - tmp_waves.clear (); - - if (!zero_line) { - zero_line = new ArdourCanvas::SimpleLine (*group); - zero_line->property_x1() = (gdouble) 1.0; - zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0; - zero_line->property_color_rgba() = (guint) color_map[cZeroLine]; - manage_zero_line (); - } - } -} - -void -AudioRegionView::peaks_ready_handler (uint32_t which) -{ - Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &AudioRegionView::create_one_wave), which, false)); - - if (!waves.empty()) { - /* all waves created, don't hook into peaks ready anymore */ - data_ready_connection.disconnect (); - } -} - -void -AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev) -{ - if (gain_line == 0) { - return; - } - - double x, y; - - /* don't create points that can't be seen */ - - set_envelope_visible (true); - - x = ev->button.x; - y = ev->button.y; - - item->w2i (x, y); - - jack_nframes_t fx = trackview.editor.pixel_to_frame (x); - - if (fx > _region.length()) { - return; - } - - /* compute vertical fractional position */ - - y = 1.0 - (y / (trackview.height - NAME_HIGHLIGHT_SIZE)); - - /* map using gain line */ - - gain_line->view_to_model_y (y); - - trackview.session().begin_reversible_command (_("add gain control point")); - trackview.session().add_undo (audio_region().envelope().get_memento()); - - - if (!audio_region().envelope_active()) { - trackview.session().add_undo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), false) ); - audio_region().set_envelope_active(true); - trackview.session().add_redo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), true) ); - } - - audio_region().envelope().add (fx, y); - - trackview.session().add_redo_no_execute (audio_region().envelope().get_memento()); - trackview.session().commit_reversible_command (); -} - -void -AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev) -{ - ControlPoint *cp = reinterpret_cast (item->get_data ("control_point")); - audio_region().envelope().erase (cp->model); -} - -void -AudioRegionView::store_flags() -{ - XMLNode *node = new XMLNode ("GUI"); - - node->add_property ("waveform-visible", (_flags & WaveformVisible) ? "yes" : "no"); - node->add_property ("envelope-visible", (_flags & EnvelopeVisible) ? "yes" : "no"); - - _region.add_extra_xml (*node); -} - -void -AudioRegionView::set_flags (XMLNode* node) -{ - XMLProperty *prop; - - if ((prop = node->property ("waveform-visible")) != 0) { - if (prop->value() == "yes") { - _flags |= WaveformVisible; - } - } - - if ((prop = node->property ("envelope-visible")) != 0) { - if (prop->value() == "yes") { - _flags |= EnvelopeVisible; - } - } -} - -void -AudioRegionView::set_waveform_shape (WaveformShape shape) -{ - bool yn; - - /* this slightly odd approach is to leave the door open to - other "shapes" such as spectral displays, etc. - */ - - switch (shape) { - case Rectified: - yn = true; - break; - - default: - yn = false; - break; - } - - if (yn != (bool) (_flags & WaveformRectified)) { - for (vector::iterator wave = waves.begin(); wave != waves.end() ; ++wave) { - (*wave)->property_rectified() = yn; - } - - if (zero_line) { - if (yn) { - zero_line->hide(); - } else { - zero_line->show(); - } - } - - if (yn) { - _flags |= WaveformRectified; - } else { - _flags &= ~WaveformRectified; - } - } -} - -GhostRegion* -AudioRegionView::add_ghost (AutomationTimeAxisView& atv) -{ - RouteTimeAxisView& myatv (*(dynamic_cast(&trackview))); // ick - double unit_position = _region.position () / samples_per_unit; - GhostRegion* ghost = new GhostRegion (atv, unit_position); - uint32_t nchans; - - nchans = myatv.get_diskstream()->n_channels(); - - for (uint32_t n = 0; n < nchans; ++n) { - - if (n >= audio_region().n_channels()) { - break; - } - - WaveView *wave = new WaveView(*ghost->group); - - wave->property_data_src() = &_region; - wave->property_cache() = wave_caches[n]; - wave->property_cache_updater() = false; - wave->property_channel() = n; - wave->property_length_function() = (gpointer)region_length_from_c; - wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c; - wave->property_peak_function() = (gpointer) region_read_peaks_from_c; - wave->property_x() = 0.0; - wave->property_samples_per_unit() = samples_per_unit; - wave->property_amplitude_above_axis() = _amplitude_above_axis; - wave->property_wave_color() = color_map[cGhostTrackWave]; - wave->property_region_start() = _region.start(); - - ghost->waves.push_back(wave); - } - - ghost->set_height (); - ghost->set_duration (_region.length() / samples_per_unit); - ghosts.push_back (ghost); - - ghost->GoingAway.connect (mem_fun(*this, &AudioRegionView::remove_ghost)); - - return ghost; -} - -void -AudioRegionView::entered () -{ - if (gain_line && _flags & EnvelopeVisible) { - gain_line->show_all_control_points (); - } - - uint32_t r,g,b,a; - UINT_TO_RGBA(fade_color,&r,&g,&b,&a); - a=255; - - if (fade_in_handle) { - fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); - fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); - } -} - -void -AudioRegionView::exited () -{ - if (gain_line) { - gain_line->hide_all_but_selected_control_points (); - } - - uint32_t r,g,b,a; - UINT_TO_RGBA(fade_color,&r,&g,&b,&a); - a=0; - - if (fade_in_handle) { - fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); - fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); - } -} - -void -AudioRegionView::envelope_active_changed () -{ - if (gain_line) { - gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]); - } -} - -void -AudioRegionView::set_waveview_data_src() -{ - - double unit_length= _region.length() / samples_per_unit; - - for (uint32_t n = 0; n < waves.size(); ++n) { - // TODO: something else to let it know the channel - waves[n]->property_data_src() = &_region; - } - - for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { - - (*i)->set_duration (unit_length); - - for (vector::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) { - (*w)->property_data_src() = &_region; - } - } - -} - -void -AudioRegionView::color_handler (ColorID id, uint32_t val) -{ - switch (id) { - case cMutedWaveForm: - case cWaveForm: - set_colors (); - break; - - case cGainLineInactive: - case cGainLine: - envelope_active_changed(); - break; - - case cZeroLine: - if (zero_line) { - zero_line->property_color_rgba() = (guint) color_map[cZeroLine]; - } - break; - - case cGhostTrackWave: - break; - - default: - break; - } -} diff --git a/gtk2_ardour/audio_regionview.h b/gtk2_ardour/audio_regionview.h deleted file mode 100644 index b59f5f4791..0000000000 --- a/gtk2_ardour/audio_regionview.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - Copyright (C) 2001-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __gtk_ardour_audio_region_view_h__ -#define __gtk_ardour_audio_region_view_h__ - -#include - -#include -#include -#include -#include - -#include "regionview.h" -#include "route_time_axis.h" -#include "time_axis_view_item.h" -#include "automation_line.h" -#include "enums.h" -#include "waveview.h" -#include "canvas.h" -#include "color.h" - -namespace ARDOUR { - class AudioRegion; - class PeakData; -}; - -class AudioTimeAxisView; -class AudioRegionGainLine; -class AudioRegionEditor; -class GhostRegion; -class AutomationTimeAxisView; - -class AudioRegionView : public RegionView -{ - public: - AudioRegionView (ArdourCanvas::Group *, - RouteTimeAxisView&, - ARDOUR::AudioRegion&, - double initial_samples_per_unit, - Gdk::Color& basic_color); - - ~AudioRegionView (); - - virtual void init (Gdk::Color& base_color, bool wait_for_data = false); - - ARDOUR::AudioRegion& audio_region() const; - - void set_height (double); - void set_samples_per_unit (double); - - void set_amplitude_above_axis (gdouble spp); - - void temporarily_hide_envelope (); ///< Dangerous! - void unhide_envelope (); ///< Dangerous! - - void set_envelope_visible (bool); - void set_waveform_visible (bool yn); - void set_waveform_shape (WaveformShape); - - bool waveform_rectified() const { return _flags & WaveformRectified; } - bool waveform_visible() const { return _flags & WaveformVisible; } - bool envelope_visible() const { return _flags & EnvelopeVisible; } - - void show_region_editor (); - - void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event); - void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event); - - AudioRegionGainLine* get_gain_line() const { return gain_line; } - - void region_changed (ARDOUR::Change); - void envelope_active_changed (); - - GhostRegion* add_ghost (AutomationTimeAxisView&); - - void reset_fade_in_shape_width (jack_nframes_t); - void reset_fade_out_shape_width (jack_nframes_t); - void set_fade_in_active (bool); - void set_fade_out_active (bool); - - virtual void entered (); - virtual void exited (); - - protected: - - /* this constructor allows derived types - to specify their visibility requirements - to the TimeAxisViewItem parent class - */ - - AudioRegionView (ArdourCanvas::Group *, - RouteTimeAxisView&, - ARDOUR::AudioRegion&, - double samples_per_unit, - Gdk::Color& basic_color, - TimeAxisViewItem::Visibility); - - enum Flags { - EnvelopeVisible = 0x1, - WaveformVisible = 0x4, - WaveformRectified = 0x8 - }; - - vector waves; - vector tmp_waves; ///< see ::create_waves() - ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position - ArdourCanvas::SimpleLine* zero_line; - ArdourCanvas::Polygon* fade_in_shape; - ArdourCanvas::Polygon* fade_out_shape; - ArdourCanvas::SimpleRect* fade_in_handle; - ArdourCanvas::SimpleRect* fade_out_handle; - - AudioRegionGainLine * gain_line; - - double _amplitude_above_axis; - - uint32_t _flags; - uint32_t fade_color; - - void reset_fade_shapes (); - void reset_fade_in_shape (); - void reset_fade_out_shape (); - void fade_in_changed (); - void fade_out_changed (); - void fade_in_active_changed (); - void fade_out_active_changed (); - - void region_resized (ARDOUR::Change); - void region_moved (void *); - void region_muted (); - void region_scale_amplitude_changed (); - - void create_waves (); - void create_one_wave (uint32_t, bool); - void manage_zero_line (); - void peaks_ready_handler (uint32_t); - void set_flags (XMLNode *); - void store_flags (); - - void set_colors (); - void compute_colors (Gdk::Color&); - void reset_width_dependent_items (double pixel_width); - void set_waveview_data_src(); - - vector wave_caches; - - void color_handler (ColorID, uint32_t); -}; - -#endif /* __gtk_ardour_audio_region_view_h__ */ diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index 0d0cd7889c..68df5ffe43 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -32,8 +32,8 @@ #include #include "audio_streamview.h" -#include "audio_regionview.h" -#include "taperegionview.h" +#include "audio_region_view.h" +#include "tape_region_view.h" #include "audio_time_axis.h" #include "canvas-waveview.h" #include "canvas-simplerect.h" diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index 13383fa6a4..376e05aa4c 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -63,7 +63,7 @@ #include "plugin_ui.h" #include "prompter.h" #include "public_editor.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "simplerect.h" #include "audio_streamview.h" #include "utils.h" diff --git a/gtk2_ardour/crossfade_view.cc b/gtk2_ardour/crossfade_view.cc index bb9ee08861..087af25e73 100644 --- a/gtk2_ardour/crossfade_view.cc +++ b/gtk2_ardour/crossfade_view.cc @@ -29,7 +29,7 @@ #include "rgb_macros.h" #include "audio_time_axis.h" #include "public_editor.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "utils.h" #include "canvas_impl.h" diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index fcd17cdb4c..518ef7217a 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -56,7 +56,7 @@ #include "keyboard.h" #include "marker.h" #include "playlist_selector.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "rgb_macros.h" #include "selection.h" #include "audio_streamview.h" diff --git a/gtk2_ardour/editor_audiotrack.cc b/gtk2_ardour/editor_audiotrack.cc index cc6a36c95a..00a8e1db9f 100644 --- a/gtk2_ardour/editor_audiotrack.cc +++ b/gtk2_ardour/editor_audiotrack.cc @@ -4,7 +4,7 @@ #include "editor.h" #include "editing.h" #include "audio_time_axis.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "selection.h" using namespace ARDOUR; diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 090d3aa591..d52c71442f 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -26,7 +26,7 @@ #include "editor.h" #include "public_editor.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "audio_streamview.h" #include "crossfade_view.h" #include "audio_time_axis.h" @@ -216,8 +216,6 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg { gint ret = FALSE; - /* FIXME: type specific */ - switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: @@ -255,8 +253,6 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg bool Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv) { - /* FIXME: type specific */ - bool ret = FALSE; switch (event->type) { @@ -707,8 +703,6 @@ Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas:: { bool ret = false; - /* FIXME: type specific (audio only) */ - switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index 2575c99c67..7e26ba37b2 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -31,7 +31,7 @@ #include "selection.h" #include "time_axis_view.h" #include "audio_time_axis.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include #include diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc index 5258e6a70a..d2b7c1160e 100644 --- a/gtk2_ardour/editor_keyboard.cc +++ b/gtk2_ardour/editor_keyboard.cc @@ -22,7 +22,7 @@ #include #include "editor.h" -#include "regionview.h" +#include "region_view.h" #include "selection.h" #include "i18n.h" diff --git a/gtk2_ardour/editor_keys.cc b/gtk2_ardour/editor_keys.cc index f18c5f164c..1bcaafd279 100644 --- a/gtk2_ardour/editor_keys.cc +++ b/gtk2_ardour/editor_keys.cc @@ -30,7 +30,7 @@ #include "ardour_ui.h" #include "editor.h" #include "time_axis_view.h" -#include "regionview.h" +#include "region_view.h" #include "selection.h" #include "i18n.h" diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 10d791a606..9b7ad99acb 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -33,7 +33,7 @@ #include "editor.h" #include "time_axis_view.h" #include "audio_time_axis.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "marker.h" #include "streamview.h" #include "region_gain_line.h" @@ -1049,8 +1049,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case MouseGain: - // FIXME - assert(dynamic_cast(clicked_regionview)); + // Gain only makes sense for audio regions + if ( ! dynamic_cast(clicked_regionview)) + break; + switch (item_type) { case RegionItem: dynamic_cast(clicked_regionview)->add_gain_point_event (item, event); @@ -2747,12 +2749,9 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) void Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { - /* FIXME: type specific (audio only) */ - double x_delta; double y_delta = 0; - AudioRegionView *rv = reinterpret_cast (drag_info.data); - assert(rv); + RegionView* rv = reinterpret_cast (drag_info.data); jack_nframes_t pending_region_position = 0; int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order; int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen @@ -2796,7 +2795,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) /* create a new region with the same name. */ - // FIXME: ew + // FIXME: ew. need a (virtual) Region::duplicate() or something? Region* newregion = NULL; if (dynamic_cast(&rv->region())) newregion = new AudioRegion (dynamic_cast(rv->region())); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 91409b3429..af366e18d0 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -51,7 +51,7 @@ #include "audio_time_axis.h" #include "automation_time_axis.h" #include "streamview.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "rgb_macros.h" #include "selection_templates.h" #include "selection.h" @@ -2117,20 +2117,14 @@ Editor::audition_selected_region () { if (!selection->regions.empty()) { RegionView* rv = *(selection->regions.begin()); - // FIXME - AudioRegion* const ar = dynamic_cast(&rv->region()); - assert(ar); - session->audition_region (*ar); + session->audition_region (rv->region()); } } void Editor::audition_playlist_region_standalone (Region& region) { - // FIXME - AudioRegion* const ar = dynamic_cast(®ion); - assert(ar); - session->audition_region (*ar); + session->audition_region (region); } void @@ -2195,12 +2189,12 @@ Editor::region_from_selection () continue; } - if ((current = dynamic_cast (current_r)) != 0) { + current = dynamic_cast (current_r); + assert(current); // FIXME + if (current != 0) { internal_start = start - current->position(); session->region_name (new_name, current->name(), true); region = new AudioRegion (*current, internal_start, selection_cnt, new_name); - } else { - assert(false); // FIXME } } } diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index 7863b0c1a1..eb994d06b9 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -54,10 +54,10 @@ Editor::handle_new_route (boost::shared_ptr route) } // FIXME - Buffer::Type type = route->default_type(); - assert(type == Buffer::AUDIO || type == Buffer::MIDI); + DataType type = route->default_type(); + assert(type == ARDOUR::AUDIO || type == ARDOUR::MIDI); - if (type == Buffer::AUDIO) + if (type == ARDOUR::AUDIO) tv = new AudioTimeAxisView (*this, *session, route, track_canvas); else tv = new MidiTimeAxisView (*this, *session, route, track_canvas); diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc index 5fbc3d3a3a..79772090f6 100644 --- a/gtk2_ardour/editor_timefx.cc +++ b/gtk2_ardour/editor_timefx.cc @@ -28,7 +28,7 @@ #include "editor.h" #include "audio_time_axis.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "region_selection.h" #include diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc index 9be0c8dfdd..60372e640f 100644 --- a/gtk2_ardour/midi_streamview.cc +++ b/gtk2_ardour/midi_streamview.cc @@ -32,7 +32,7 @@ #include #include "midi_streamview.h" -#include "regionview.h" +#include "region_view.h" //#include "midi_regionview.h" #include "midi_time_axis.h" #include "canvas-simplerect.h" diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index 543cb8bb10..041eebff10 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -61,7 +61,7 @@ #include "public_editor.h" #include "redirect_automation_line.h" #include "redirect_automation_time_axis.h" -#include "regionview.h" +#include "region_view.h" #include "rgb_macros.h" #include "selection.h" #include "simplerect.h" diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index cd2b2c15ba..8258eb3c00 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -744,7 +744,7 @@ MixerStrip::fast_update () } void -MixerStrip::diskstream_changed (void *src) +MixerStrip::diskstream_changed () { Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &MixerStrip::update_diskstream_display)); } diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h index 5460134f5e..2819917568 100644 --- a/gtk2_ardour/mixer_strip.h +++ b/gtk2_ardour/mixer_strip.h @@ -177,7 +177,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox void edit_input_configuration (); void edit_output_configuration (); - void diskstream_changed (void *src); + void diskstream_changed (); Gtk::Menu *send_action_menu; void build_send_action_menu (); diff --git a/gtk2_ardour/region_gain_line.cc b/gtk2_ardour/region_gain_line.cc index ee966a064f..a542be054e 100644 --- a/gtk2_ardour/region_gain_line.cc +++ b/gtk2_ardour/region_gain_line.cc @@ -2,7 +2,7 @@ #include #include "region_gain_line.h" -#include "audio_regionview.h" +#include "audio_region_view.h" #include "utils.h" #include "time_axis_view.h" diff --git a/gtk2_ardour/region_selection.cc b/gtk2_ardour/region_selection.cc index aadedce423..f8c9f384a9 100644 --- a/gtk2_ardour/region_selection.cc +++ b/gtk2_ardour/region_selection.cc @@ -20,7 +20,7 @@ #include -#include "regionview.h" +#include "region_view.h" #include "region_selection.h" using namespace ARDOUR; diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc new file mode 100644 index 0000000000..80d38a3cac --- /dev/null +++ b/gtk2_ardour/region_view.cc @@ -0,0 +1,476 @@ +/* + Copyright (C) 2001-2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "streamview.h" +#include "region_view.h" +#include "route_time_axis.h" +#include "simplerect.h" +#include "simpleline.h" +#include "waveview.h" +#include "public_editor.h" +#include "region_editor.h" +#include "ghostregion.h" +#include "route_time_axis.h" +#include "utils.h" +#include "rgb_macros.h" +#include "gui_thread.h" + +#include "i18n.h" + +using namespace sigc; +using namespace ARDOUR; +using namespace PBD; +using namespace Editing; +using namespace ArdourCanvas; + +static const int32_t sync_mark_width = 9; + +sigc::signal RegionView::RegionViewGoingAway; + +RegionView::RegionView (ArdourCanvas::Group* parent, + TimeAxisView& tv, + ARDOUR::Region& r, + double spu, + Gdk::Color& basic_color) + : TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(), + TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText| + TimeAxisViewItem::ShowNameHighlight| + TimeAxisViewItem::ShowFrame)) + , _region (r) +{ +} + +RegionView::RegionView (ArdourCanvas::Group* parent, + TimeAxisView& tv, + ARDOUR::Region& r, + double spu, + Gdk::Color& basic_color, + TimeAxisViewItem::Visibility visibility) + : TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(), visibility) + , _region (r) +{ +} + +void +RegionView::init (Gdk::Color& basic_color, bool wfd) +{ + editor = 0; + valid = true; + in_destructor = false; + _height = 0; + wait_for_data = wfd; + + compute_colors (basic_color); + + name_highlight->set_data ("regionview", this); + name_text->set_data ("regionview", this); + + /* an equilateral triangle */ + ArdourCanvas::Points shape; + shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1)); + shape.push_back (Gnome::Art::Point ((sync_mark_width - 1)/2, 1)); + shape.push_back (Gnome::Art::Point (0, sync_mark_width - 1)); + shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1)); + + sync_mark = new ArdourCanvas::Polygon (*group); + sync_mark->property_points() = shape; + sync_mark->property_fill_color_rgba() = fill_color; + sync_mark->hide(); + + reset_width_dependent_items ((double) _region.length() / samples_per_unit); + + set_height (trackview.height); + + region_muted (); + region_sync_changed (); + region_resized (BoundsChanged); + region_locked (); + + _region.StateChanged.connect (mem_fun(*this, &RegionView::region_changed)); + + group->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this)); + name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this)); + + set_colors (); + + ColorChanged.connect (mem_fun (*this, &RegionView::color_handler)); + + /* XXX sync mark drag? */ +} + +RegionView::~RegionView () +{ + in_destructor = true; + + RegionViewGoingAway (this); /* EMIT_SIGNAL */ + + for (vector::iterator g = ghosts.begin(); g != ghosts.end(); ++g) { + delete *g; + } + + if (editor) { + delete editor; + } +} + +gint +RegionView::_lock_toggle (ArdourCanvas::Item* item, GdkEvent* ev, void* arg) +{ + switch (ev->type) { + case GDK_BUTTON_RELEASE: + static_cast(arg)->lock_toggle (); + return TRUE; + break; + default: + break; + } + return FALSE; +} + +void +RegionView::lock_toggle () +{ + _region.set_locked (!_region.locked()); +} + +void +RegionView::region_changed (Change what_changed) +{ + ENSURE_GUI_THREAD (bind (mem_fun(*this, &RegionView::region_changed), what_changed)); + + if (what_changed & BoundsChanged) { + region_resized (what_changed); + region_sync_changed (); + } + if (what_changed & Region::MuteChanged) { + region_muted (); + } + if (what_changed & Region::OpacityChanged) { + region_opacity (); + } + if (what_changed & ARDOUR::NameChanged) { + region_renamed (); + } + if (what_changed & Region::SyncOffsetChanged) { + region_sync_changed (); + } + if (what_changed & Region::LayerChanged) { + region_layered (); + } + if (what_changed & Region::LockChanged) { + region_locked (); + } +} + +void +RegionView::region_locked () +{ + /* name will show locked status */ + region_renamed (); +} + +void +RegionView::region_resized (Change what_changed) +{ + double unit_length; + + if (what_changed & ARDOUR::PositionChanged) { + set_position (_region.position(), 0); + } + + if (what_changed & Change (StartChanged|LengthChanged)) { + + set_duration (_region.length(), 0); + + unit_length = _region.length() / samples_per_unit; + + reset_width_dependent_items (unit_length); + + for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + + (*i)->set_duration (unit_length); + + } + } +} + +void +RegionView::reset_width_dependent_items (double pixel_width) +{ + TimeAxisViewItem::reset_width_dependent_items (pixel_width); + _pixel_width = pixel_width; +} + +void +RegionView::region_layered () +{ + RouteTimeAxisView *rtv = dynamic_cast(&get_time_axis_view()); + assert(rtv); + rtv->view()->region_layered (this); +} + +void +RegionView::region_muted () +{ + set_frame_color (); + region_renamed (); +} + +void +RegionView::region_opacity () +{ + set_frame_color (); +} + +void +RegionView::raise () +{ + _region.raise (); +} + +void +RegionView::raise_to_top () +{ + _region.raise_to_top (); +} + +void +RegionView::lower () +{ + _region.lower (); +} + +void +RegionView::lower_to_bottom () +{ + _region.lower_to_bottom (); +} + +bool +RegionView::set_position (jack_nframes_t pos, void* src, double* ignored) +{ + double delta; + bool ret; + + if (!(ret = TimeAxisViewItem::set_position (pos, this, &delta))) { + return false; + } + + if (ignored) { + *ignored = delta; + } + + if (delta) { + for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + (*i)->group->move (delta, 0.0); + } + } + + return ret; +} + +void +RegionView::set_samples_per_unit (gdouble spu) +{ + TimeAxisViewItem::set_samples_per_unit (spu); + + for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + (*i)->set_samples_per_unit (spu); + (*i)->set_duration (_region.length() / samples_per_unit); + } + + region_sync_changed (); +} + +bool +RegionView::set_duration (jack_nframes_t frames, void *src) +{ + if (!TimeAxisViewItem::set_duration (frames, src)) { + return false; + } + + for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + (*i)->set_duration (_region.length() / samples_per_unit); + } + + return true; +} + +void +RegionView::compute_colors (Gdk::Color& basic_color) +{ + TimeAxisViewItem::compute_colors (basic_color); +} + +void +RegionView::set_colors () +{ + TimeAxisViewItem::set_colors (); + + if (sync_mark) { + sync_mark->property_fill_color_rgba() = fill_color; + } +} + +void +RegionView::set_frame_color () +{ + if (_region.opaque()) { + fill_opacity = 180; + } else { + fill_opacity = 100; + } + + TimeAxisViewItem::set_frame_color (); +} + +void +RegionView::hide_region_editor() +{ + if (editor) { + editor->hide_all (); + } +} + +void +RegionView::region_renamed () +{ + string str; + + if (_region.locked()) { + str += '>'; + str += _region.name(); + str += '<'; + } else { + str = _region.name(); + } + + if (_region.speed_mismatch (trackview.session().frame_rate())) { + str = string ("*") + str; + } + + if (_region.muted()) { + str = string ("!") + str; + } + + set_item_name (str, this); + set_name_text (str); +} + +void +RegionView::region_sync_changed () +{ + if (sync_mark == 0) { + return; + } + + int sync_dir; + jack_nframes_t sync_offset; + + sync_offset = _region.sync_offset (sync_dir); + + /* this has to handle both a genuine change of position, a change of samples_per_unit, + and a change in the bounds of the _region. + */ + + if (sync_offset == 0) { + + /* no sync mark - its the start of the region */ + + sync_mark->hide(); + + } else { + + if ((sync_dir < 0) || ((sync_dir > 0) && (sync_offset > _region.length()))) { + + /* no sync mark - its out of the bounds of the region */ + + sync_mark->hide(); + + } else { + + /* lets do it */ + + Points points; + + //points = sync_mark->property_points().get_value(); + + double offset = sync_offset / samples_per_unit; + points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1)); + points.push_back (Gnome::Art::Point (offset + ((sync_mark_width-1)/2), 1)); + points.push_back (Gnome::Art::Point (offset, sync_mark_width - 1)); + points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1)); + sync_mark->property_points().set_value (points); + sync_mark->show(); + + } + } +} + +void +RegionView::move (double x_delta, double y_delta) +{ + if (_region.locked() || (x_delta == 0 && y_delta == 0)) { + return; + } + + get_canvas_group()->move (x_delta, y_delta); + + /* note: ghosts never leave their tracks so y_delta for them is always zero */ + + for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + (*i)->group->move (x_delta, 0.0); + } +} + +void +RegionView::remove_ghost (GhostRegion* ghost) +{ + if (in_destructor) { + return; + } + + for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + if (*i == ghost) { + ghosts.erase (i); + break; + } + } +} + +uint32_t +RegionView::get_fill_color () +{ + return fill_color; +} + diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h new file mode 100644 index 0000000000..d2d2c22760 --- /dev/null +++ b/gtk2_ardour/region_view.h @@ -0,0 +1,140 @@ +/* + Copyright (C) 2001-2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __gtk_ardour_region_view_h__ +#define __gtk_ardour_region_view_h__ + +#include + +#include +#include +#include +#include + +#include "time_axis_view_item.h" +#include "automation_line.h" +#include "enums.h" +#include "waveview.h" +#include "canvas.h" +#include "color.h" + +class TimeAxisView; +class RegionEditor; +class GhostRegion; +class AutomationTimeAxisView; + +class RegionView : public TimeAxisViewItem +{ + public: + RegionView (ArdourCanvas::Group* parent, + TimeAxisView& time_view, + ARDOUR::Region& region, + double samples_per_unit, + Gdk::Color& basic_color); + + ~RegionView (); + + virtual void init (Gdk::Color& base_color, bool wait_for_data); + + ARDOUR::Region& region() const { return _region; } + + bool is_valid() const { return valid; } + void set_valid (bool yn) { valid = yn; } + + virtual void set_height (double) = 0; + virtual void set_samples_per_unit (double); + virtual bool set_duration (jack_nframes_t, void*); + + void move (double xdelta, double ydelta); + + void raise (); + void raise_to_top (); + void lower (); + void lower_to_bottom (); + + bool set_position(jack_nframes_t pos, void* src, double* delta = 0); + + virtual void show_region_editor () = 0; + virtual void hide_region_editor(); + + virtual void region_changed (ARDOUR::Change); + + virtual GhostRegion* add_ghost (AutomationTimeAxisView&) = 0; + void remove_ghost (GhostRegion*); + + uint32_t get_fill_color (); + + virtual void entered () {} + virtual void exited () {} + + static sigc::signal RegionViewGoingAway; + sigc::signal GoingAway; + + protected: + + /** Allows derived types to specify their visibility requirements + * to the TimeAxisViewItem parent class + */ + RegionView (ArdourCanvas::Group *, + TimeAxisView&, + ARDOUR::Region&, + double samples_per_unit, + Gdk::Color& basic_color, + TimeAxisViewItem::Visibility); + + ARDOUR::Region& _region; + + ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position + ArdourCanvas::Text* no_wave_msg; + + RegionEditor *editor; + + vector control_points; + double current_visible_sync_position; + + bool valid; ///< see StreamView::redisplay_diskstream() + double _pixel_width; + double _height; + bool in_destructor; + + bool wait_for_data; + sigc::connection data_ready_connection; + + virtual void region_resized (ARDOUR::Change); + void region_moved (void *); + virtual void region_muted (); + void region_locked (); + void region_opacity (); + void region_layered (); + void region_renamed (); + void region_sync_changed (); + + static gint _lock_toggle (ArdourCanvas::Item*, GdkEvent*, void*); + void lock_toggle (); + + virtual void set_colors (); + virtual void compute_colors (Gdk::Color&); + virtual void set_frame_color (); + virtual void reset_width_dependent_items (double pixel_width); + + vector ghosts; + + virtual void color_handler (ColorID, uint32_t) {} +}; + +#endif /* __gtk_ardour_region_view_h__ */ diff --git a/gtk2_ardour/regionview.cc b/gtk2_ardour/regionview.cc deleted file mode 100644 index 411117b1af..0000000000 --- a/gtk2_ardour/regionview.cc +++ /dev/null @@ -1,476 +0,0 @@ -/* - Copyright (C) 2001-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include - -#include "streamview.h" -#include "regionview.h" -#include "route_time_axis.h" -#include "simplerect.h" -#include "simpleline.h" -#include "waveview.h" -#include "public_editor.h" -#include "region_editor.h" -#include "ghostregion.h" -#include "route_time_axis.h" -#include "utils.h" -#include "rgb_macros.h" -#include "gui_thread.h" - -#include "i18n.h" - -using namespace sigc; -using namespace ARDOUR; -using namespace PBD; -using namespace Editing; -using namespace ArdourCanvas; - -static const int32_t sync_mark_width = 9; - -sigc::signal RegionView::RegionViewGoingAway; - -RegionView::RegionView (ArdourCanvas::Group* parent, - TimeAxisView& tv, - ARDOUR::Region& r, - double spu, - Gdk::Color& basic_color) - : TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(), - TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText| - TimeAxisViewItem::ShowNameHighlight| - TimeAxisViewItem::ShowFrame)) - , _region (r) -{ -} - -RegionView::RegionView (ArdourCanvas::Group* parent, - TimeAxisView& tv, - ARDOUR::Region& r, - double spu, - Gdk::Color& basic_color, - TimeAxisViewItem::Visibility visibility) - : TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(), visibility) - , _region (r) -{ -} - -void -RegionView::init (Gdk::Color& basic_color, bool wfd) -{ - editor = 0; - valid = true; - in_destructor = false; - _height = 0; - wait_for_data = wfd; - - compute_colors (basic_color); - - name_highlight->set_data ("regionview", this); - name_text->set_data ("regionview", this); - - /* an equilateral triangle */ - ArdourCanvas::Points shape; - shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1)); - shape.push_back (Gnome::Art::Point ((sync_mark_width - 1)/2, 1)); - shape.push_back (Gnome::Art::Point (0, sync_mark_width - 1)); - shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1)); - - sync_mark = new ArdourCanvas::Polygon (*group); - sync_mark->property_points() = shape; - sync_mark->property_fill_color_rgba() = fill_color; - sync_mark->hide(); - - reset_width_dependent_items ((double) _region.length() / samples_per_unit); - - set_height (trackview.height); - - region_muted (); - region_sync_changed (); - region_resized (BoundsChanged); - region_locked (); - - _region.StateChanged.connect (mem_fun(*this, &RegionView::region_changed)); - - group->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this)); - name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this)); - - set_colors (); - - ColorChanged.connect (mem_fun (*this, &RegionView::color_handler)); - - /* XXX sync mark drag? */ -} - -RegionView::~RegionView () -{ - in_destructor = true; - - RegionViewGoingAway (this); /* EMIT_SIGNAL */ - - for (vector::iterator g = ghosts.begin(); g != ghosts.end(); ++g) { - delete *g; - } - - if (editor) { - delete editor; - } -} - -gint -RegionView::_lock_toggle (ArdourCanvas::Item* item, GdkEvent* ev, void* arg) -{ - switch (ev->type) { - case GDK_BUTTON_RELEASE: - static_cast(arg)->lock_toggle (); - return TRUE; - break; - default: - break; - } - return FALSE; -} - -void -RegionView::lock_toggle () -{ - _region.set_locked (!_region.locked()); -} - -void -RegionView::region_changed (Change what_changed) -{ - ENSURE_GUI_THREAD (bind (mem_fun(*this, &RegionView::region_changed), what_changed)); - - if (what_changed & BoundsChanged) { - region_resized (what_changed); - region_sync_changed (); - } - if (what_changed & Region::MuteChanged) { - region_muted (); - } - if (what_changed & Region::OpacityChanged) { - region_opacity (); - } - if (what_changed & ARDOUR::NameChanged) { - region_renamed (); - } - if (what_changed & Region::SyncOffsetChanged) { - region_sync_changed (); - } - if (what_changed & Region::LayerChanged) { - region_layered (); - } - if (what_changed & Region::LockChanged) { - region_locked (); - } -} - -void -RegionView::region_locked () -{ - /* name will show locked status */ - region_renamed (); -} - -void -RegionView::region_resized (Change what_changed) -{ - double unit_length; - - if (what_changed & ARDOUR::PositionChanged) { - set_position (_region.position(), 0); - } - - if (what_changed & Change (StartChanged|LengthChanged)) { - - set_duration (_region.length(), 0); - - unit_length = _region.length() / samples_per_unit; - - reset_width_dependent_items (unit_length); - - for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { - - (*i)->set_duration (unit_length); - - } - } -} - -void -RegionView::reset_width_dependent_items (double pixel_width) -{ - TimeAxisViewItem::reset_width_dependent_items (pixel_width); - _pixel_width = pixel_width; -} - -void -RegionView::region_layered () -{ - RouteTimeAxisView *rtv = dynamic_cast(&get_time_axis_view()); - assert(rtv); - rtv->view()->region_layered (this); -} - -void -RegionView::region_muted () -{ - set_frame_color (); - region_renamed (); -} - -void -RegionView::region_opacity () -{ - set_frame_color (); -} - -void -RegionView::raise () -{ - _region.raise (); -} - -void -RegionView::raise_to_top () -{ - _region.raise_to_top (); -} - -void -RegionView::lower () -{ - _region.lower (); -} - -void -RegionView::lower_to_bottom () -{ - _region.lower_to_bottom (); -} - -bool -RegionView::set_position (jack_nframes_t pos, void* src, double* ignored) -{ - double delta; - bool ret; - - if (!(ret = TimeAxisViewItem::set_position (pos, this, &delta))) { - return false; - } - - if (ignored) { - *ignored = delta; - } - - if (delta) { - for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { - (*i)->group->move (delta, 0.0); - } - } - - return ret; -} - -void -RegionView::set_samples_per_unit (gdouble spu) -{ - TimeAxisViewItem::set_samples_per_unit (spu); - - for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { - (*i)->set_samples_per_unit (spu); - (*i)->set_duration (_region.length() / samples_per_unit); - } - - region_sync_changed (); -} - -bool -RegionView::set_duration (jack_nframes_t frames, void *src) -{ - if (!TimeAxisViewItem::set_duration (frames, src)) { - return false; - } - - for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { - (*i)->set_duration (_region.length() / samples_per_unit); - } - - return true; -} - -void -RegionView::compute_colors (Gdk::Color& basic_color) -{ - TimeAxisViewItem::compute_colors (basic_color); -} - -void -RegionView::set_colors () -{ - TimeAxisViewItem::set_colors (); - - if (sync_mark) { - sync_mark->property_fill_color_rgba() = fill_color; - } -} - -void -RegionView::set_frame_color () -{ - if (_region.opaque()) { - fill_opacity = 180; - } else { - fill_opacity = 100; - } - - TimeAxisViewItem::set_frame_color (); -} - -void -RegionView::hide_region_editor() -{ - if (editor) { - editor->hide_all (); - } -} - -void -RegionView::region_renamed () -{ - string str; - - if (_region.locked()) { - str += '>'; - str += _region.name(); - str += '<'; - } else { - str = _region.name(); - } - - if (_region.speed_mismatch (trackview.session().frame_rate())) { - str = string ("*") + str; - } - - if (_region.muted()) { - str = string ("!") + str; - } - - set_item_name (str, this); - set_name_text (str); -} - -void -RegionView::region_sync_changed () -{ - if (sync_mark == 0) { - return; - } - - int sync_dir; - jack_nframes_t sync_offset; - - sync_offset = _region.sync_offset (sync_dir); - - /* this has to handle both a genuine change of position, a change of samples_per_unit, - and a change in the bounds of the _region. - */ - - if (sync_offset == 0) { - - /* no sync mark - its the start of the region */ - - sync_mark->hide(); - - } else { - - if ((sync_dir < 0) || ((sync_dir > 0) && (sync_offset > _region.length()))) { - - /* no sync mark - its out of the bounds of the region */ - - sync_mark->hide(); - - } else { - - /* lets do it */ - - Points points; - - //points = sync_mark->property_points().get_value(); - - double offset = sync_offset / samples_per_unit; - points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1)); - points.push_back (Gnome::Art::Point (offset + ((sync_mark_width-1)/2), 1)); - points.push_back (Gnome::Art::Point (offset, sync_mark_width - 1)); - points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1)); - sync_mark->property_points().set_value (points); - sync_mark->show(); - - } - } -} - -void -RegionView::move (double x_delta, double y_delta) -{ - if (_region.locked() || (x_delta == 0 && y_delta == 0)) { - return; - } - - get_canvas_group()->move (x_delta, y_delta); - - /* note: ghosts never leave their tracks so y_delta for them is always zero */ - - for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { - (*i)->group->move (x_delta, 0.0); - } -} - -void -RegionView::remove_ghost (GhostRegion* ghost) -{ - if (in_destructor) { - return; - } - - for (vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { - if (*i == ghost) { - ghosts.erase (i); - break; - } - } -} - -uint32_t -RegionView::get_fill_color () -{ - return fill_color; -} - diff --git a/gtk2_ardour/regionview.h b/gtk2_ardour/regionview.h deleted file mode 100644 index d2d2c22760..0000000000 --- a/gtk2_ardour/regionview.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright (C) 2001-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __gtk_ardour_region_view_h__ -#define __gtk_ardour_region_view_h__ - -#include - -#include -#include -#include -#include - -#include "time_axis_view_item.h" -#include "automation_line.h" -#include "enums.h" -#include "waveview.h" -#include "canvas.h" -#include "color.h" - -class TimeAxisView; -class RegionEditor; -class GhostRegion; -class AutomationTimeAxisView; - -class RegionView : public TimeAxisViewItem -{ - public: - RegionView (ArdourCanvas::Group* parent, - TimeAxisView& time_view, - ARDOUR::Region& region, - double samples_per_unit, - Gdk::Color& basic_color); - - ~RegionView (); - - virtual void init (Gdk::Color& base_color, bool wait_for_data); - - ARDOUR::Region& region() const { return _region; } - - bool is_valid() const { return valid; } - void set_valid (bool yn) { valid = yn; } - - virtual void set_height (double) = 0; - virtual void set_samples_per_unit (double); - virtual bool set_duration (jack_nframes_t, void*); - - void move (double xdelta, double ydelta); - - void raise (); - void raise_to_top (); - void lower (); - void lower_to_bottom (); - - bool set_position(jack_nframes_t pos, void* src, double* delta = 0); - - virtual void show_region_editor () = 0; - virtual void hide_region_editor(); - - virtual void region_changed (ARDOUR::Change); - - virtual GhostRegion* add_ghost (AutomationTimeAxisView&) = 0; - void remove_ghost (GhostRegion*); - - uint32_t get_fill_color (); - - virtual void entered () {} - virtual void exited () {} - - static sigc::signal RegionViewGoingAway; - sigc::signal GoingAway; - - protected: - - /** Allows derived types to specify their visibility requirements - * to the TimeAxisViewItem parent class - */ - RegionView (ArdourCanvas::Group *, - TimeAxisView&, - ARDOUR::Region&, - double samples_per_unit, - Gdk::Color& basic_color, - TimeAxisViewItem::Visibility); - - ARDOUR::Region& _region; - - ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position - ArdourCanvas::Text* no_wave_msg; - - RegionEditor *editor; - - vector control_points; - double current_visible_sync_position; - - bool valid; ///< see StreamView::redisplay_diskstream() - double _pixel_width; - double _height; - bool in_destructor; - - bool wait_for_data; - sigc::connection data_ready_connection; - - virtual void region_resized (ARDOUR::Change); - void region_moved (void *); - virtual void region_muted (); - void region_locked (); - void region_opacity (); - void region_layered (); - void region_renamed (); - void region_sync_changed (); - - static gint _lock_toggle (ArdourCanvas::Item*, GdkEvent*, void*); - void lock_toggle (); - - virtual void set_colors (); - virtual void compute_colors (Gdk::Color&); - virtual void set_frame_color (); - virtual void reset_width_dependent_items (double pixel_width); - - vector ghosts; - - virtual void color_handler (ColorID, uint32_t) {} -}; - -#endif /* __gtk_ardour_region_view_h__ */ diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 1eba885b44..cb9883b8e6 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -65,7 +65,7 @@ #include "point_selection.h" #include "prompter.h" #include "public_editor.h" -#include "regionview.h" +#include "region_view.h" #include "rgb_macros.h" #include "selection.h" #include "simplerect.h" @@ -815,7 +815,7 @@ RouteTimeAxisView::speed_changed () } void -RouteTimeAxisView::diskstream_changed (void *src) +RouteTimeAxisView::diskstream_changed () { Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &RouteTimeAxisView::update_diskstream_display)); } diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h index 476a135c39..d673f646a4 100644 --- a/gtk2_ardour/route_time_axis.h +++ b/gtk2_ardour/route_time_axis.h @@ -128,7 +128,7 @@ protected: }; - void diskstream_changed (void *src); + void diskstream_changed (); void update_diskstream_display (); gint edit_click (GdkEventButton *); diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 5ba143ad21..f4b602d39c 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -353,7 +353,7 @@ RouteUI::update_mute_display () } void -RouteUI::route_rec_enable_changed (void *src) +RouteUI::route_rec_enable_changed () { Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_rec_display)); } diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h index 2cb46eb16d..643c39b960 100644 --- a/gtk2_ardour/route_ui.h +++ b/gtk2_ardour/route_ui.h @@ -99,7 +99,7 @@ class RouteUI : public virtual AxisView void solo_changed(void*); void mute_changed(void*); virtual void redirects_changed (void *) {} - void route_rec_enable_changed(void*); + void route_rec_enable_changed(); void session_rec_enable_changed(); void build_solo_menu (void); diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc index dce8d9e1c6..086d878994 100644 --- a/gtk2_ardour/selection.cc +++ b/gtk2_ardour/selection.cc @@ -24,7 +24,7 @@ #include -#include "regionview.h" +#include "region_view.h" #include "selection.h" #include "selection_templates.h" #include "time_axis_view.h" diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index c94184272e..31452e315b 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -29,7 +29,7 @@ #include #include "streamview.h" -#include "regionview.h" +#include "region_view.h" #include "route_time_axis.h" #include "canvas-waveview.h" #include "canvas-simplerect.h" @@ -260,7 +260,7 @@ StreamView::playlist_state_changed (Change ignored) } void -StreamView::diskstream_changed (void *src_ignored) +StreamView::diskstream_changed () { Track *t; @@ -309,7 +309,7 @@ StreamView::region_layered (RegionView* rv) } void -StreamView::rec_enable_changed (void *src) +StreamView::rec_enable_changed () { Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &StreamView::setup_rec_box)); } diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h index baa779ba67..0bec319758 100644 --- a/gtk2_ardour/streamview.h +++ b/gtk2_ardour/streamview.h @@ -101,7 +101,7 @@ protected: //private: (FIXME?) void transport_changed(); - void rec_enable_changed(void* src = 0); + void rec_enable_changed(); void sess_rec_enable_changed(); virtual void setup_rec_box () = 0; void update_rec_box (); @@ -114,7 +114,7 @@ protected: void display_diskstream (ARDOUR::Diskstream* ); virtual void undisplay_diskstream (); virtual void redisplay_diskstream () = 0; - void diskstream_changed (void* ); + void diskstream_changed (); void playlist_state_changed (ARDOUR::Change); virtual void playlist_changed (ARDOUR::Diskstream* ); diff --git a/gtk2_ardour/tape_region_view.cc b/gtk2_ardour/tape_region_view.cc new file mode 100644 index 0000000000..bd5ce8af02 --- /dev/null +++ b/gtk2_ardour/tape_region_view.cc @@ -0,0 +1,101 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "tape_region_view.h" +#include "audio_time_axis.h" +#include "gui_thread.h" + +#include "i18n.h" + +using namespace sigc; +using namespace ARDOUR; +using namespace PBD; +using namespace Editing; +using namespace ArdourCanvas; + +const TimeAxisViewItem::Visibility TapeAudioRegionView::default_tape_visibility + = TimeAxisViewItem::Visibility ( + TimeAxisViewItem::ShowNameHighlight | + TimeAxisViewItem::ShowFrame | + TimeAxisViewItem::HideFrameRight | + TimeAxisViewItem::FullWidthNameHighlight); + +TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, + AudioRegion& r, + double spu, + Gdk::Color& basic_color) + + : AudioRegionView (parent, tv, r, spu, basic_color, + TimeAxisViewItem::Visibility ((r.position() != 0) ? default_tape_visibility : + TimeAxisViewItem::Visibility (default_tape_visibility|TimeAxisViewItem::HideFrameLeft))) +{ +} + +void +TapeAudioRegionView::init (Gdk::Color& basic_color, bool wfw) +{ + AudioRegionView::init(basic_color, wfw); + + /* every time the wave data changes and peaks are ready, redraw */ + + for (uint32_t n = 0; n < audio_region().n_channels(); ++n) { + audio_region().source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n)); + } + +} + +TapeAudioRegionView::~TapeAudioRegionView() +{ +} + +void +TapeAudioRegionView::update (uint32_t n) +{ + /* check that all waves are build and ready */ + + if (!tmp_waves.empty()) { + return; + } + + ENSURE_GUI_THREAD (bind (mem_fun(*this, &TapeAudioRegionView::update), n)); + + /* this triggers a cache invalidation and redraw in the waveview */ + + waves[n]->property_data_src() = &_region; +} + +void +TapeAudioRegionView::set_frame_color () +{ + fill_opacity = 255; + TimeAxisViewItem::set_frame_color (); +} diff --git a/gtk2_ardour/tape_region_view.h b/gtk2_ardour/tape_region_view.h new file mode 100644 index 0000000000..ed3852e3a9 --- /dev/null +++ b/gtk2_ardour/tape_region_view.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __gtk_ardour_tape_audio_region_view_h__ +#define __gtk_ardour_tape_audio_region_view_h__ + +#include + +#include "audio_region_view.h" + +class TapeAudioRegionView : public AudioRegionView +{ + public: + TapeAudioRegionView (ArdourCanvas::Group *, + RouteTimeAxisView&, + ARDOUR::AudioRegion&, + double initial_samples_per_unit, + Gdk::Color& base_color); + ~TapeAudioRegionView (); + + protected: + void init (Gdk::Color& base_color, bool wait_for_waves); + + void set_frame_color (); + void update (uint32_t n); + + static const TimeAxisViewItem::Visibility default_tape_visibility; +}; + +#endif /* __gtk_ardour_tape_audio_region_view_h__ */ diff --git a/gtk2_ardour/taperegionview.cc b/gtk2_ardour/taperegionview.cc deleted file mode 100644 index 19e6ba3ad3..0000000000 --- a/gtk2_ardour/taperegionview.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#include -#include - -#include - -#include - -#include -#include -#include -#include - -#include "taperegionview.h" -#include "audio_time_axis.h" -#include "gui_thread.h" - -#include "i18n.h" - -using namespace sigc; -using namespace ARDOUR; -using namespace PBD; -using namespace Editing; -using namespace ArdourCanvas; - -const TimeAxisViewItem::Visibility TapeAudioRegionView::default_tape_visibility - = TimeAxisViewItem::Visibility ( - TimeAxisViewItem::ShowNameHighlight | - TimeAxisViewItem::ShowFrame | - TimeAxisViewItem::HideFrameRight | - TimeAxisViewItem::FullWidthNameHighlight); - -TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, - AudioRegion& r, - double spu, - Gdk::Color& basic_color) - - : AudioRegionView (parent, tv, r, spu, basic_color, - TimeAxisViewItem::Visibility ((r.position() != 0) ? default_tape_visibility : - TimeAxisViewItem::Visibility (default_tape_visibility|TimeAxisViewItem::HideFrameLeft))) -{ -} - -void -TapeAudioRegionView::init (Gdk::Color& basic_color, bool wfw) -{ - AudioRegionView::init(basic_color, wfw); - - /* every time the wave data changes and peaks are ready, redraw */ - - for (uint32_t n = 0; n < audio_region().n_channels(); ++n) { - audio_region().source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n)); - } - -} - -TapeAudioRegionView::~TapeAudioRegionView() -{ -} - -void -TapeAudioRegionView::update (uint32_t n) -{ - /* check that all waves are build and ready */ - - if (!tmp_waves.empty()) { - return; - } - - ENSURE_GUI_THREAD (bind (mem_fun(*this, &TapeAudioRegionView::update), n)); - - /* this triggers a cache invalidation and redraw in the waveview */ - - waves[n]->property_data_src() = &_region; -} - -void -TapeAudioRegionView::set_frame_color () -{ - fill_opacity = 255; - TimeAxisViewItem::set_frame_color (); -} diff --git a/gtk2_ardour/taperegionview.h b/gtk2_ardour/taperegionview.h deleted file mode 100644 index c16e7a6916..0000000000 --- a/gtk2_ardour/taperegionview.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#ifndef __gtk_ardour_tape_audio_region_view_h__ -#define __gtk_ardour_tape_audio_region_view_h__ - -#include - -#include "audio_regionview.h" - -class TapeAudioRegionView : public AudioRegionView -{ - public: - TapeAudioRegionView (ArdourCanvas::Group *, - RouteTimeAxisView&, - ARDOUR::AudioRegion&, - double initial_samples_per_unit, - Gdk::Color& base_color); - ~TapeAudioRegionView (); - - protected: - void init (Gdk::Color& base_color, bool wait_for_waves); - - void set_frame_color (); - void update (uint32_t n); - - static const TimeAxisViewItem::Visibility default_tape_visibility; -}; - -#endif /* __gtk_ardour_tape_audio_region_view_h__ */ diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index 7b42ad8374..394df05f04 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -99,7 +99,6 @@ tempo.cc utils.cc version.cc mix.cc -smpte.cc """) arch_specific_objects = [ ] diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index ec15cf1caf..e2dfc5fd0c 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -60,6 +60,8 @@ class AudioDiskstream : public Diskstream AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable); AudioDiskstream (Session &, const XMLNode&); + const PBD::ID& id() const { return _id; } + // FIXME AudioDiskstream& ref() { _refcnt++; return *this; } @@ -78,7 +80,7 @@ class AudioDiskstream : public Diskstream if (n < channels.size()) return channels[n].source; return 0; } - void set_record_enabled (bool yn, void *src); + void set_record_enabled (bool yn); float peak_power(uint32_t n=0) { float x = channels[n].peak_power; @@ -121,7 +123,7 @@ class AudioDiskstream : public Diskstream /* stateful */ XMLNode& get_state(void); - int set_state(const XMLNode& node); + int set_state(const XMLNode& node); void monitor_input (bool); @@ -141,16 +143,7 @@ class AudioDiskstream : public Diskstream } } - static sigc::signal*> DeleteSources; - - int set_loop (Location *loc); - sigc::signal LoopSet; - - std::list& last_capture_regions () { - return _last_capture_regions; - } - - const PBD::ID& id() const { return _id; } + std::list& last_capture_regions () { return _last_capture_regions; } XMLNode* deprecated_io_node; @@ -248,8 +241,8 @@ class AudioDiskstream : public Diskstream void setup_destructive_playlist (); void use_destructive_playlist (); - void engage_record_enable (void* src); - void disengage_record_enable (void* src); + void engage_record_enable (); + void disengage_record_enable (); // Working buffers for do_refill (butler thread) static void allocate_working_buffers(); diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index 2616705918..15b99297c8 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -36,8 +36,6 @@ class AudioTrack : public Track AudioTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal); AudioTrack (Session&, const XMLNode&); ~AudioTrack (); - - int set_name (string str, void *src); int 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); @@ -48,16 +46,10 @@ class AudioTrack : public Track int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, bool can_record, bool rec_monitors_input); - void set_record_enable (bool yn, void *src); - AudioDiskstream& audio_diskstream() const; int use_diskstream (string name); int use_diskstream (const PBD::ID& id); - - void set_mode (TrackMode m); - - void set_latency_delay (jack_nframes_t); int export_stuff (vector& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t end_frame); @@ -69,8 +61,6 @@ class AudioTrack : public Track int set_state(const XMLNode& node); - bool record_enabled() const; - protected: XMLNode& state (bool full); diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index bac1e3720a..81370e379c 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -34,7 +34,7 @@ #include #include #include -#include +#include namespace ARDOUR { @@ -105,8 +105,8 @@ class AudioEngine : public sigc::trackable virtual const char *what() const throw() { return "could not connect to engine backend"; } }; - Port *register_input_port (Buffer::Type type, const std::string& portname); - Port *register_output_port (Buffer::Type type, const std::string& portname); + Port *register_input_port (DataType type, const std::string& portname); + Port *register_output_port (DataType type, const std::string& portname); int unregister_port (Port *); int connect (const std::string& source, const std::string& destination); diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index 54e2d73af0..683e946713 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -27,8 +27,9 @@ #include #include -#include #include +#include +#include #include class XMLNode; @@ -43,14 +44,14 @@ class AudioSource; struct AudioRegionState : public RegionState { - AudioRegionState (std::string why); - - Curve _fade_in; - Curve _fade_out; - Curve _envelope; - gain_t _scale_amplitude; - uint32_t _fade_in_disabled; - uint32_t _fade_out_disabled; + AudioRegionState (std::string why); + + Curve _fade_in; + Curve _fade_out; + Curve _envelope; + gain_t _scale_amplitude; + uint32_t _fade_in_disabled; + uint32_t _fade_out_disabled; }; class AudioRegion : public Region @@ -92,7 +93,7 @@ class AudioRegion : public Region vector master_source_names(); bool envelope_active () const { return _flags & Region::EnvelopeActive; } - bool fade_in_active () const { return _flags & Region::FadeIn; } + bool fade_in_active () const { return _flags & Region::FadeIn; } bool fade_out_active () const { return _flags & Region::FadeOut; } bool captured() const { return !(_flags & (Region::Flag (Region::Import|Region::External))); } @@ -100,20 +101,21 @@ class AudioRegion : public Region Curve& fade_out() { return _fade_out; } Curve& envelope() { return _envelope; } - jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t offset, jack_nframes_t cnt, uint32_t chan_n=0, double samples_per_unit= 1.0) const; - - virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, - uint32_t chan_n = 0, - jack_nframes_t read_frames = 0, - jack_nframes_t skip_frames = 0) const; + jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks, + jack_nframes_t offset, jack_nframes_t cnt, + uint32_t chan_n=0, double samples_per_unit= 1.0) const; - jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const; + virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buf, + float *gain_buf, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, + uint32_t chan_n = 0, + jack_nframes_t read_frames = 0, + jack_nframes_t skip_frames = 0) const; + jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buf, + float *gain_buf, char * workbuf, + jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const; XMLNode& state (bool); - XMLNode& get_state (); int set_state (const XMLNode&); static void set_default_fade (float steepness, jack_nframes_t len); @@ -140,10 +142,6 @@ class AudioRegion : public Region int separate_by_channel (ARDOUR::Session&, vector&) const; - uint32_t read_data_count() const { return _read_data_count; } - - ARDOUR::Playlist* playlist() const { return _playlist; } - UndoAction get_memento() const; /* filter */ @@ -167,20 +165,6 @@ class AudioRegion : public Region friend class Playlist; private: - SourceList sources; - SourceList master_sources; /* used when timefx are applied, so - we can always use the original - source. - */ - mutable Curve _fade_in; - FadeShape _fade_in_shape; - mutable Curve _fade_out; - FadeShape _fade_out_shape; - mutable Curve _envelope; - gain_t _scale_amplitude; - uint32_t _fade_in_disabled; - uint32_t _fade_out_disabled; - void set_default_fades (); void set_default_fade_in (); void set_default_fade_out (); @@ -192,10 +176,6 @@ class AudioRegion : public Region void recompute_gain_at_end (); void recompute_gain_at_start (); - bool copied() const { return _flags & Copied; } - void maybe_uncopy (); - void rename_after_first_edit (); - jack_nframes_t _read_at (const SourceList&, Sample *buf, Sample *mixdown_buffer, float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n = 0, @@ -212,6 +192,21 @@ class AudioRegion : public Region void envelope_changed (Change); void source_deleted (Source*); + + + SourceList sources; + + /** Used when timefx are applied, so we can always use the original source. */ + SourceList master_sources; + + mutable Curve _fade_in; + FadeShape _fade_in_shape; + mutable Curve _fade_out; + FadeShape _fade_out_shape; + mutable Curve _envelope; + gain_t _scale_amplitude; + uint32_t _fade_in_disabled; + uint32_t _fade_out_disabled; }; } /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h index f0ad3be67e..cd36a06e36 100644 --- a/libs/ardour/ardour/buffer.h +++ b/libs/ardour/ardour/buffer.h @@ -45,12 +45,7 @@ namespace ARDOUR { class Buffer { public: - /** Unfortunately using RTTI and dynamic_cast to find the type of the - * buffer is just too slow, this is done in very performance critical - * bits of the code. */ - enum Type { NIL = 0, AUDIO, MIDI }; - - Buffer(Type type, size_t capacity) + Buffer(DataType type, size_t capacity) : _type(type), _capacity(capacity), _size(0) {} @@ -65,7 +60,7 @@ public: /** Type of this buffer. * Based on this you can static cast a Buffer* to the desired type. */ - virtual Type type() const { return _type; } + virtual DataType type() const { return _type; } /** Jack type (eg JACK_DEFAULT_AUDIO_TYPE) */ const char* jack_type() const { return type_to_jack_type(type()); } @@ -74,8 +69,11 @@ public: const char* type_string() const { return type_to_string(type()); } /* The below static methods need to be separate from the above methods - * because the conversion is needed in places where there's no Buffer */ - static const char* type_to_jack_type(Type t) { + * because the conversion is needed in places where there's no Buffer. + * These should probably live somewhere else... + */ + + static const char* type_to_jack_type(DataType t) { switch (t) { case AUDIO: return JACK_DEFAULT_AUDIO_TYPE; case MIDI: return JACK_DEFAULT_MIDI_TYPE; @@ -83,7 +81,7 @@ public: } } - static const char* type_to_string(Type t) { + static const char* type_to_string(DataType t) { switch (t) { case AUDIO: return "audio"; case MIDI: return "midi"; @@ -92,7 +90,7 @@ public: } /** Used for loading from XML (route default types etc) */ - static Type type_from_string(const string& str) { + static DataType type_from_string(const string& str) { if (str == "audio") return AUDIO; else if (str == "midi") @@ -102,9 +100,9 @@ public: } protected: - Type _type; - size_t _capacity; - size_t _size; + DataType _type; + size_t _capacity; + size_t _size; }; @@ -119,8 +117,12 @@ public: : Buffer(AUDIO, capacity) , _data(NULL) { - _size = capacity; // For audio buffers, size = capacity always + _size = capacity; // For audio buffers, size = capacity (always) +#ifdef NO_POSIX_MEMALIGN + b = (Sample *) malloc(sizeof(Sample) * capacity); +#else posix_memalign((void**)_data, 16, sizeof(Sample) * capacity); +#endif assert(_data); memset(_data, 0, sizeof(Sample) * capacity); } @@ -146,7 +148,11 @@ public: : Buffer(MIDI, capacity) , _data(NULL) { +#ifdef NO_POSIX_MEMALIGN + b = (Sample *) malloc(sizeof(RawMidi) * capacity); +#else posix_memalign((void**)_data, 16, sizeof(RawMidi) * capacity); +#endif assert(_data); assert(_size == 0); memset(_data, 0, sizeof(Sample) * capacity); diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index ff25127ec9..ebce516d8b 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -54,9 +54,6 @@ class Session; class Playlist; class IO; -/* FIXME: There are (obviously) far too many virtual functions in this ATM. - * Just to get things off the ground, they'll be removed. */ - class Diskstream : public Stateful, public sigc::trackable { public: @@ -66,8 +63,8 @@ class Diskstream : public Stateful, public sigc::trackable Destructive = 0x4 }; - string name () const { return _name; } - virtual int set_name (string str, void* src); + string name () const { return _name; } + virtual int set_name (string str); ARDOUR::IO* io() const { return _io; } void set_io (ARDOUR::IO& io); @@ -83,14 +80,14 @@ class Diskstream : public Stateful, public sigc::trackable void unset_flag (Flag f) { _flags &= ~f; } AlignStyle alignment_style() const { return _alignment_style; } - void set_align_style (AlignStyle); - void set_persistent_align_style (AlignStyle a) { _persistent_alignment_style = a; } + void set_align_style (AlignStyle); + void set_persistent_align_style (AlignStyle a) { _persistent_alignment_style = a; } jack_nframes_t roll_delay() const { return _roll_delay; } - void set_roll_delay (jack_nframes_t); + void set_roll_delay (jack_nframes_t); - bool record_enabled() const { return g_atomic_int_get (&_record_enabled); } - virtual void set_record_enabled (bool yn, void *src) = 0; + bool record_enabled() const { return g_atomic_int_get (&_record_enabled); } + virtual void set_record_enabled (bool yn) = 0; bool destructive() const { return _flags & Destructive; } virtual void set_destructive (bool yn); @@ -120,8 +117,8 @@ class Diskstream : public Stateful, public sigc::trackable uint32_t n_channels() { return _n_channels; } - static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; } - static void set_disk_io_chunk_frames (uint32_t n) { disk_io_chunk_frames = n; } + static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; } + static void set_disk_io_chunk_frames (uint32_t n) { disk_io_chunk_frames = n; } /* Stateful */ virtual XMLNode& get_state(void) = 0; @@ -136,23 +133,23 @@ class Diskstream : public Stateful, public sigc::trackable bool slaved() const { return _slaved; } void set_slaved(bool yn) { _slaved = yn; } - virtual int set_loop (Location *loc); - sigc::signal LoopSet; + int set_loop (Location *loc); std::list& last_capture_regions () { return _last_capture_regions; } void handle_input_change (IOChange, void *src); - sigc::signal RecordEnableChanged; - sigc::signal SpeedChanged; - sigc::signal ReverseChanged; - sigc::signal PlaylistChanged; - sigc::signal AlignmentStyleChanged; + sigc::signal RecordEnableChanged; + sigc::signal SpeedChanged; + sigc::signal ReverseChanged; + sigc::signal PlaylistChanged; + sigc::signal AlignmentStyleChanged; + sigc::signal LoopSet; static sigc::signal DiskOverrun; static sigc::signal DiskUnderrun; static sigc::signal DiskstreamCreated; // XXX use a ref with sigc2 - //static sigc::signal*> DeleteSources; + static sigc::signal*> DeleteSources; protected: friend class Session; @@ -160,10 +157,9 @@ class Diskstream : public Stateful, public sigc::trackable Diskstream (Session &, const string& name, Flag f = Recordable); Diskstream (Session &, const XMLNode&); - /* the Session is the only point of access for these - because they require that the Session is "inactive" - while they are called. - */ + /* the Session is the only point of access for these because they require + * that the Session is "inactive" while they are called. + */ virtual void set_pending_overwrite (bool) = 0; virtual int overwrite_existing_buffers () = 0; @@ -191,7 +187,7 @@ class Diskstream : public Stateful, public sigc::trackable //private: - /* use unref() to destroy a diskstream */ + /** Use unref() to destroy a diskstream */ virtual ~Diskstream(); enum TransitionType { @@ -201,8 +197,7 @@ class Diskstream : public Stateful, public sigc::trackable struct CaptureTransition { TransitionType type; - // the start or end file frame pos - jack_nframes_t capture_val; + jack_nframes_t capture_val; ///< The start or end file frame position }; /* The two central butler operations */ diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 94e1483ad6..35b20f655e 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include using std::string; using std::vector; @@ -67,7 +67,7 @@ class IO : public Stateful, public ARDOUR::StateManager IO (Session&, string name, int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1, - Buffer::Type default_type = Buffer::AUDIO); + DataType default_type = AUDIO); virtual ~IO(); @@ -81,7 +81,7 @@ class IO : public Stateful, public ARDOUR::StateManager void set_output_minimum (int n); void set_output_maximum (int n); - Buffer::Type default_type() const { return _default_type; } + DataType default_type() const { return _default_type; } const string& name() const { return _name; } virtual int set_name (string str, void *src); @@ -116,8 +116,8 @@ class IO : public Stateful, public ARDOUR::StateManager Connection *input_connection() const { return _input_connection; } Connection *output_connection() const { return _output_connection; } - int add_input_port (string source, void *src, Buffer::Type type = Buffer::NIL); - int add_output_port (string destination, void *src, Buffer::Type type = Buffer::NIL); + int add_input_port (string source, void *src, DataType type = NIL); + int add_output_port (string destination, void *src, DataType type = NIL); int remove_input_port (Port *, void *src); int remove_output_port (Port *, void *src); @@ -284,7 +284,7 @@ public: PBD::ID _id; bool no_panner_reset; XMLNode* deferred_state; - Buffer::Type _default_type; + DataType _default_type; virtual void set_deferred_state() {} diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h index 5998363d69..7877bfaf1c 100644 --- a/libs/ardour/ardour/midi_diskstream.h +++ b/libs/ardour/ardour/midi_diskstream.h @@ -73,7 +73,7 @@ class MidiDiskstream : public Diskstream //void set_align_style (AlignStyle); //void set_persistent_align_style (AlignStyle); - void set_record_enabled (bool yn, void *src); + void set_record_enabled (bool yn); //void set_speed (double); int use_playlist (Playlist *); @@ -82,8 +82,6 @@ class MidiDiskstream : public Diskstream Playlist *playlist () { return _playlist; } - static sigc::signal*> DeleteSources; - /* stateful */ XMLNode& get_state(void); diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h index 1371162b14..ec47a91b95 100644 --- a/libs/ardour/ardour/midi_region.h +++ b/libs/ardour/ardour/midi_region.h @@ -121,10 +121,6 @@ class MidiRegion : public Region StateManager::State* state_factory (std::string why) const; Change restore_state (StateManager::State&); - bool copied() const { return _flags & Copied; } - void maybe_uncopy (); - void rename_after_first_edit (); - jack_nframes_t _read_at (const SourceList&, unsigned char *buf, unsigned char *mixdown_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n = 0, diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 9874cfa56d..185e840ec9 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -82,7 +82,7 @@ protected: uint32_t n_process_buffers (); private: - int set_diskstream (MidiDiskstream&, void *); + int set_diskstream (MidiDiskstream&); void set_state_part_two (); void set_state_part_three (); diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index add253982f..9fb5b0eb2b 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -54,7 +54,6 @@ class Playlist : public Stateful, public StateManager { Playlist (const Playlist&, string name, bool hidden = false); Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false); - //virtual jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, char * workbuf, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0) = 0; virtual void clear (bool with_delete = false, bool with_save = true); virtual void dump () const; virtual UndoAction get_memento() const = 0; diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index a138f66042..3773a3b893 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -24,7 +24,6 @@ #include #include -#include #include class XMLNode; @@ -36,22 +35,22 @@ class Source; enum RegionEditState { EditChangesNothing = 0, - EditChangesName = 1, - EditChangesID = 2 + EditChangesName = 1, + EditChangesID = 2 }; -struct RegionState : public StateManager::State { - - RegionState (std::string why) : StateManager::State (why) {} - - jack_nframes_t _start; - jack_nframes_t _length; - jack_nframes_t _position; - uint32_t _flags; - jack_nframes_t _sync_position; - layer_t _layer; - string _name; - mutable RegionEditState _first_edit; +struct RegionState : public StateManager::State +{ + RegionState (std::string why) : StateManager::State (why) {} + + jack_nframes_t _start; + jack_nframes_t _length; + jack_nframes_t _position; + uint32_t _flags; + jack_nframes_t _sync_position; + layer_t _layer; + string _name; + mutable RegionEditState _first_edit; }; class Region : public Stateful, public StateManager @@ -95,7 +94,7 @@ class Region : public Stateful, public StateManager Region (const Region&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags); Region (const Region&); Region (const XMLNode&); - ~Region(); + virtual ~Region(); const PBD::ID& id() const { return _id; } @@ -105,9 +104,10 @@ class Region : public Stateful, public StateManager void set_name (string str); jack_nframes_t position () const { return _position; } - jack_nframes_t start () const { return _start; } - jack_nframes_t length() const { return _length; } - layer_t layer () const { return _layer; } + jack_nframes_t start () const { return _start; } + jack_nframes_t length() const { return _length; } + layer_t layer () const { return _layer; } + jack_nframes_t sync_offset(int& dir) const; jack_nframes_t sync_position() const; @@ -118,14 +118,13 @@ class Region : public Stateful, public StateManager jack_nframes_t first_frame() const { return _position; } jack_nframes_t last_frame() const { return _position + _length - 1; } - bool hidden() const { return _flags & Hidden; } - bool muted() const { return _flags & Muted; } - bool opaque () const { return _flags & Opaque; } - //bool envelope_active () const { return _flags & EnvelopeActive; } - bool locked() const { return _flags & Locked; } - bool automatic() const { return _flags & Automatic; } + bool hidden() const { return _flags & Hidden; } + bool muted() const { return _flags & Muted; } + bool opaque () const { return _flags & Opaque; } + bool locked() const { return _flags & Locked; } + bool automatic() const { return _flags & Automatic; } bool whole_file() const { return _flags & WholeFile ; } - Flag flags() const { return _flags; } + Flag flags() const { return _flags; } virtual bool should_save_state () const { return !(_flags & DoNotSaveState); }; @@ -148,12 +147,6 @@ class Region : public Stateful, public StateManager virtual bool speed_mismatch (float) const = 0; - /*virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, - uint32_t chan_n = 0, - jack_nframes_t read_frames = 0, - jack_nframes_t skip_frames = 0) const = 0;*/ - /* EDITING OPERATIONS */ void set_length (jack_nframes_t, void *src); @@ -181,7 +174,6 @@ class Region : public Stateful, public StateManager void set_hidden (bool yn); void set_muted (bool yn); void set_opaque (bool yn); - //void set_envelope_active (bool yn); void set_locked (bool yn); virtual uint32_t read_data_count() const { return _read_data_count; } @@ -197,9 +189,9 @@ class Region : public Stateful, public StateManager /* serialization */ + XMLNode& get_state (); virtual XMLNode& state (bool); - XMLNode& get_state (); - int set_state (const XMLNode&); + virtual int set_state (const XMLNode&); sigc::signal GoingAway; @@ -219,23 +211,6 @@ class Region : public Stateful, public StateManager void set_last_layer_op (uint64_t when); protected: - - jack_nframes_t _start; - jack_nframes_t _length; - jack_nframes_t _position; - Flag _flags; - jack_nframes_t _sync_position; - layer_t _layer; - string _name; - mutable RegionEditState _first_edit; - int _frozen; - Glib::Mutex lock; - PBD::ID _id; - ARDOUR::Playlist* _playlist; - mutable uint32_t _read_data_count; // modified in read() - Change pending_changed; - uint64_t _last_layer_op; // timestamp - XMLNode& get_short_state (); /* used only by Session */ /* state management */ @@ -259,6 +234,23 @@ class Region : public Stateful, public StateManager virtual bool verify_length (jack_nframes_t) = 0; virtual void recompute_at_start () = 0; virtual void recompute_at_end () = 0; + + + jack_nframes_t _start; + jack_nframes_t _length; + jack_nframes_t _position; + Flag _flags; + jack_nframes_t _sync_position; + layer_t _layer; + string _name; + mutable RegionEditState _first_edit; + int _frozen; + Glib::Mutex lock; + PBD::ID _id; + ARDOUR::Playlist* _playlist; + mutable uint32_t _read_data_count; // modified in read() + Change pending_changed; + uint64_t _last_layer_op; // timestamp }; } /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index c85f34f1fa..ea4a2374d4 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -40,7 +40,7 @@ #include #include #include -#include +#include namespace ARDOUR { @@ -70,7 +70,7 @@ class Route : public IO Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max, - Flag flags = Flag(0), Buffer::Type default_type = Buffer::AUDIO); + Flag flags = Flag(0), DataType default_type = AUDIO); Route (Session&, const XMLNode&); virtual ~Route(); diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h index 11253eda5b..e9fad1aa2b 100644 --- a/libs/ardour/ardour/route_group.h +++ b/libs/ardour/ardour/route_group.h @@ -35,6 +35,7 @@ using std::list; namespace ARDOUR { class Route; +class Track; class AudioTrack; class Session; @@ -90,7 +91,7 @@ class RouteGroup : public Stateful, public sigc::trackable { /* to use these, #include */ - template void apply (void (AudioTrack::*func)(T, void *), T val, void *src); + template void apply (void (Track::*func)(T, void *), T val, void *src); /* fills at_set with all members of the group that are AudioTracks */ diff --git a/libs/ardour/ardour/route_group_specialized.h b/libs/ardour/ardour/route_group_specialized.h index 0424002dcd..250d3744df 100644 --- a/libs/ardour/ardour/route_group_specialized.h +++ b/libs/ardour/ardour/route_group_specialized.h @@ -7,11 +7,11 @@ namespace ARDOUR { template void -RouteGroup::apply (void (AudioTrack::*func)(T, void *), T val, void *src) +RouteGroup::apply (void (Track::*func)(T, void *), T val, void *src) { for (list::iterator i = routes.begin(); i != routes.end(); i++) { - AudioTrack *at; - if ((at = dynamic_cast(*i)) != 0) { + Track *at; + if ((at = dynamic_cast(*i)) != 0) { (at->*func)(val, this); } } diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index dd8ec4806a..d39807be3f 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -168,18 +168,18 @@ class Session : public sigc::trackable, public Stateful Replace, Clear }; - - Type type; - Action action; - jack_nframes_t action_frame; - jack_nframes_t target_frame; - float speed; + + Type type; + Action action; + jack_nframes_t action_frame; + jack_nframes_t target_frame; + float speed; union { - void* ptr; - bool yes_or_no; - Session::SlaveSource slave; - Route* route; + void* ptr; + bool yes_or_no; + Session::SlaveSource slave; + Route* route; }; list audio_range; @@ -555,9 +555,6 @@ class Session : public sigc::trackable, public Stateful void remove_route (boost::shared_ptr); void resort_routes (); void resort_routes_using (boost::shared_ptr); - void resort_routes_proxy (void* src) { - resort_routes (); - } AudioEngine &engine() { return _engine; }; @@ -739,7 +736,7 @@ class Session : public sigc::trackable, public Stateful boost::shared_ptr the_auditioner() { return auditioner; } void audition_playlist (); - void audition_region (AudioRegion&); + void audition_region (Region&); void cancel_audition (); bool is_auditioning () const; diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index 86bfeb0c9b..707ead1573 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -31,11 +31,11 @@ class RouteGroup; class Track : public Route { public: - Track (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, Buffer::Type default_type = Buffer::AUDIO); + Track (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = AUDIO); - virtual ~Track () {} + virtual ~Track (); - virtual int set_name (string str, void *src) = 0; + int set_name (string str, void *src); virtual int 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) = 0; @@ -49,18 +49,17 @@ class Track : public Route void toggle_monitor_input (); bool can_record() const { return true; } - virtual void set_record_enable (bool yn, void *src) = 0; Diskstream& diskstream() const { return *_diskstream; } virtual int use_diskstream (string name) = 0; virtual int use_diskstream (const PBD::ID& id) = 0; - TrackMode mode() const { return _mode; } - virtual void set_mode (TrackMode m) = 0; + TrackMode mode() const { return _mode; } + void set_mode (TrackMode m); jack_nframes_t update_total_latency(); - virtual void set_latency_delay (jack_nframes_t) = 0; + void set_latency_delay (jack_nframes_t); enum FreezeState { NoFreeze, @@ -82,15 +81,17 @@ class Track : public Route PBD::Controllable& rec_enable_control() { return _rec_enable_control; } - virtual bool record_enabled() const = 0; + bool record_enabled() const; + void set_record_enable (bool yn, void *src); + void set_meter_point (MeterPoint, void* src); - sigc::signal ModeChanged; - sigc::signal DiskstreamChanged; - sigc::signal FreezeChange; + sigc::signal ModeChanged; + sigc::signal DiskstreamChanged; + sigc::signal FreezeChange; protected: - Track (Session& sess, const XMLNode& node, Buffer::Type default_type = Buffer::AUDIO); + Track (Session& sess, const XMLNode& node, DataType default_type = AUDIO); virtual XMLNode& state (bool full) = 0; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index c5b79a950c..eb86470ebc 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -245,6 +245,12 @@ namespace ARDOUR { PeakDatum min; PeakDatum max; }; + + enum DataType { + NIL = 0, + AUDIO, + MIDI + }; } std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf); diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 5f6ce05016..7f0cb55821 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -54,8 +54,6 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -sigc::signal*> AudioDiskstream::DeleteSources; - size_t AudioDiskstream::_working_buffers_size = 0; Sample* AudioDiskstream::_mixdown_buffer = 0; gain_t* AudioDiskstream::_gain_buffer = 0; @@ -140,13 +138,8 @@ AudioDiskstream::init (Diskstream::Flag f) set_block_size (_session.get_block_size()); allocate_temporary_buffers (); - pending_overwrite = false; - overwrite_frame = 0; - overwrite_queued = false; - input_change_pending = NoChange; - add_channel (); - _n_channels = 1; + assert(_n_channels == 1); } void @@ -420,6 +413,7 @@ AudioDiskstream::use_destructive_playlist () for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) { (*chan).write_source = dynamic_cast(®ion->source (n)); + assert((*chan).write_source); (*chan).write_source->set_allow_remove_if_empty (false); } @@ -589,7 +583,7 @@ AudioDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes returns a non-zero value, in which case, ::commit should not be called. */ - // If we can't take the state lock return. + // If we can't take the state lock return. if (!state_lock.trylock()) { return 1; } @@ -983,7 +977,7 @@ AudioDiskstream::seek (jack_nframes_t frame, bool complete_refill) /* can't rec-enable in destructive mode if transport is before start */ if (destructive() && record_enabled() && frame < _session.current_start_frame()) { - disengage_record_enable (this); + disengage_record_enable (); } playback_sample = frame; @@ -1328,6 +1322,16 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer, char * return ret; } +/** Flush pending data to disk. + * + * Important note: this function will write *AT MOST* disk_io_chunk_frames + * of data to disk. it will never write more than that. If it writes that + * much and there is more than that waiting to be written, it will return 1, + * otherwise 0 on success or -1 on failure. + * + * If there is less than disk_io_chunk_frames to be written, no data will be + * written at all unless @a force_flush is true. + */ int AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) { @@ -1338,16 +1342,6 @@ AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) RingBufferNPT::rw_vector vector; RingBufferNPT::rw_vector transvec; jack_nframes_t total; - - /* important note: this function will write *AT MOST* - disk_io_chunk_frames of data to disk. it will never - write more than that. if its writes that much and there - is more than that waiting to be written, it will return 1, - otherwise 0 on success or -1 on failure. - - if there is less than disk_io_chunk_frames to be written, - no data will be written at all unless `force_flush' is true. - */ _write_data_count = 0; @@ -1362,7 +1356,6 @@ AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) goto out; } - /* if there are 2+ chunks of disk i/o possible for this track, let the caller know so that it can arrange for us to be called again, ASAP. @@ -1479,7 +1472,6 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca ChannelList::iterator chan; vector::iterator ci; uint32_t n = 0; - list* deletion_list; bool mark_write_completed = false; finish_capture (true); @@ -1512,7 +1504,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca ChannelList::iterator chan; - deletion_list = new list; + list* deletion_list = new list; for ( chan = channels.begin(); chan != channels.end(); ++chan) { @@ -1699,7 +1691,7 @@ AudioDiskstream::finish_capture (bool rec_monitors_input) } void -AudioDiskstream::set_record_enabled (bool yn, void* src) +AudioDiskstream::set_record_enabled (bool yn) { if (!recordable() || !_session.record_enabling_legal()) { return; @@ -1726,17 +1718,17 @@ AudioDiskstream::set_record_enabled (bool yn, void* src) if (record_enabled() != yn) { if (yn) { - engage_record_enable (src); + engage_record_enable (); } else { - disengage_record_enable (src); + disengage_record_enable (); } } } void -AudioDiskstream::engage_record_enable (void* src) +AudioDiskstream::engage_record_enable () { - bool rolling = _session.transport_speed() != 0.0f; + bool rolling = _session.transport_speed() != 0.0f; g_atomic_int_set (&_record_enabled, 1); capturing_sources.clear (); @@ -1753,11 +1745,11 @@ AudioDiskstream::engage_record_enable (void* src) } } - RecordEnableChanged (src); /* EMIT SIGNAL */ + RecordEnableChanged (); /* EMIT SIGNAL */ } void -AudioDiskstream::disengage_record_enable (void* src) +AudioDiskstream::disengage_record_enable () { g_atomic_int_set (&_record_enabled, 0); if (Config->get_use_hardware_monitoring()) { @@ -1768,7 +1760,7 @@ AudioDiskstream::disengage_record_enable (void* src) } } capturing_sources.clear (); - RecordEnableChanged (src); /* EMIT SIGNAL */ + RecordEnableChanged (); /* EMIT SIGNAL */ } @@ -1875,8 +1867,7 @@ AudioDiskstream::set_state (const XMLNode& node) } // create necessary extra channels - // we are always constructed with one - // and we always need one + // we are always constructed with one and we always need one if (nchans > _n_channels) { @@ -2181,22 +2172,6 @@ AudioDiskstream::capture_buffer_load () const (double) channels.front().capture_buf->bufsize()); } -int -AudioDiskstream::set_loop (Location *location) -{ - if (location) { - if (location->start() >= location->end()) { - error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl; - return -1; - } - } - - loop_location = location; - - LoopSet (location); /* EMIT SIGNAL */ - return 0; -} - int AudioDiskstream::use_pending_capture_data (XMLNode& node) { diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index eae9076105..78af23e3df 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -57,28 +57,17 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode AudioDiskstream* ds = new AudioDiskstream (_session, name, dflags); - _declickable = true; - _freeze_record.state = NoFreeze; - _saved_meter_point = _meter_point; - _mode = mode; - set_diskstream (*ds, this); } AudioTrack::AudioTrack (Session& sess, const XMLNode& node) : Track (sess, node) { - _freeze_record.state = NoFreeze; set_state (node); - _declickable = true; - _saved_meter_point = _meter_point; } AudioTrack::~AudioTrack () { - if (_diskstream) { - _diskstream->unref(); - } } int @@ -155,13 +144,13 @@ AudioTrack::set_diskstream (AudioDiskstream& ds, void *src) } } - _diskstream->set_record_enabled (false, this); + _diskstream->set_record_enabled (false); _diskstream->monitor_input (false); ic_connection.disconnect(); ic_connection = input_changed.connect (mem_fun (*_diskstream, &Diskstream::handle_input_change)); - DiskstreamChanged (src); /* EMIT SIGNAL */ + DiskstreamChanged (); /* EMIT SIGNAL */ return 0; } @@ -192,41 +181,6 @@ AudioTrack::use_diskstream (const PBD::ID& id) return set_diskstream (*dstream, this); } -bool -AudioTrack::record_enabled () const -{ - return _diskstream->record_enabled (); -} - -void -AudioTrack::set_record_enable (bool yn, void *src) -{ - if (_freeze_record.state == Frozen) { - return; - } - - if (_mix_group && src != _mix_group && _mix_group->is_active()) { - _mix_group->apply (&AudioTrack::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); - } - - _rec_enable_control.Changed (); -} - AudioDiskstream& AudioTrack::audio_diskstream() const { @@ -672,28 +626,6 @@ AudioTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jac return audio_diskstream().process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input); } -int -AudioTrack::set_name (string str, void *src) -{ - int ret; - - if (record_enabled() && _session.actively_recording()) { - /* this messes things up if done while recording */ - return -1; - } - - if (audio_diskstream().set_name (str, src)) { - return -1; - } - - /* save state so that the statefile fully reflects any filename changes */ - - if ((ret = IO::set_name (str, src)) == 0) { - _session.save_state (""); - } - return ret; -} - int AudioTrack::export_stuff (vector& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t start, jack_nframes_t nframes) { @@ -795,13 +727,6 @@ AudioTrack::export_stuff (vector& buffers, char * workbuf, uint32_t nbu return 0; } -void -AudioTrack::set_latency_delay (jack_nframes_t longest_session_latency) -{ - Route::set_latency_delay (longest_session_latency); - audio_diskstream().set_roll_delay (_roll_delay); -} - void AudioTrack::bounce (InterThreadInfo& itt) { @@ -902,7 +827,7 @@ AudioTrack::freeze (InterThreadInfo& itt) region->set_locked (true); diskstream.use_playlist (dynamic_cast(new_playlist)); - diskstream.set_record_enabled (false, this); + diskstream.set_record_enabled (false); _freeze_record.state = Frozen; FreezeChange(); /* EMIT SIGNAL */ @@ -940,14 +865,3 @@ AudioTrack::unfreeze () FreezeChange (); /* EMIT SIGNAL */ } -void -AudioTrack::set_mode (TrackMode m) -{ - if (_diskstream) { - if (_mode != m) { - _mode = m; - audio_diskstream().set_destructive (m == Destructive); - ModeChanged(); - } - } -} diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 72708b46f8..5618c7ef5f 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -42,7 +43,6 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -// Why here? [DR] jack_nframes_t Port::_short_over_length = 2; jack_nframes_t Port::_long_over_length = 10; @@ -389,7 +389,7 @@ AudioEngine::remove_session () } Port * -AudioEngine::register_input_port (Buffer::Type type, const string& portname) +AudioEngine::register_input_port (DataType type, const string& portname) { if (!_running) { if (!_has_run) { @@ -421,7 +421,7 @@ AudioEngine::register_input_port (Buffer::Type type, const string& portname) } Port * -AudioEngine::register_output_port (Buffer::Type type, const string& portname) +AudioEngine::register_output_port (DataType type, const string& portname) { if (!_running) { if (!_has_run) { diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index b137229c36..fff1c99598 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -48,13 +48,13 @@ using namespace ARDOUR; /* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */ -Change AudioRegion::FadeInChanged = ARDOUR::new_change(); -Change AudioRegion::FadeOutChanged = ARDOUR::new_change(); -Change AudioRegion::FadeInActiveChanged = ARDOUR::new_change(); -Change AudioRegion::FadeOutActiveChanged = ARDOUR::new_change(); +Change AudioRegion::FadeInChanged = ARDOUR::new_change(); +Change AudioRegion::FadeOutChanged = ARDOUR::new_change(); +Change AudioRegion::FadeInActiveChanged = ARDOUR::new_change(); +Change AudioRegion::FadeOutActiveChanged = ARDOUR::new_change(); Change AudioRegion::EnvelopeActiveChanged = ARDOUR::new_change(); Change AudioRegion::ScaleAmplitudeChanged = ARDOUR::new_change(); -Change AudioRegion::EnvelopeChanged = ARDOUR::new_change(); +Change AudioRegion::EnvelopeChanged = ARDOUR::new_change(); AudioRegionState::AudioRegionState (string why) : RegionState (why), @@ -633,12 +633,6 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff return to_read; } -XMLNode& -AudioRegion::get_state () -{ - return state (true); -} - XMLNode& AudioRegion::state (bool full) { diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc index 38fb2e5859..81f64d2671 100644 --- a/libs/ardour/auditioner.cc +++ b/libs/ardour/auditioner.cc @@ -44,12 +44,12 @@ Auditioner::Auditioner (Session& s) defer_pan_reset (); if (left.length()) { - add_output_port (left, this, Buffer::AUDIO); + add_output_port (left, this, AUDIO); } if (right.length()) { audio_diskstream().add_channel(); - add_output_port (right, this, Buffer::AUDIO); + add_output_port (right, this, AUDIO); } allow_pan_reset (); @@ -67,7 +67,7 @@ Auditioner::~Auditioner () AudioPlaylist& Auditioner::prepare_playlist () { - // FIXME + // FIXME auditioner is still audio-only AudioPlaylist* const apl = dynamic_cast(_diskstream->playlist()); assert(apl); diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index 9fc2ded0ce..9312de5bf1 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -58,7 +58,7 @@ using namespace PBD; jack_nframes_t Diskstream::disk_io_chunk_frames = 0; sigc::signal Diskstream::DiskstreamCreated; -//sigc::signal*> Diskstream::DeleteSources; +sigc::signal*> Diskstream::DeleteSources; sigc::signal Diskstream::DiskOverrun; sigc::signal Diskstream::DiskUnderrun; @@ -124,7 +124,7 @@ Diskstream::init (Flag f) Diskstream::~Diskstream () { - // Taken by derived class destrctors.. assure lock? + // Taken by derived class destrctors.. should assure locked here somehow? //Glib::Mutex::Lock lm (state_lock); if (_playlist) @@ -369,7 +369,7 @@ Diskstream::playlist_deleted (Playlist* pl) } int -Diskstream::set_name (string str, void *src) +Diskstream::set_name (string str) { if (str != _name) { assert(playlist()); diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 1c8de5008a..a70bf8abd3 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -102,7 +102,7 @@ static bool sort_ports_by_name (Port* a, Port* b) */ IO::IO (Session& s, string name, int input_min, int input_max, int output_min, int output_max, - Buffer::Type default_type) + DataType default_type) : _session (s), _name (name), _default_type(default_type), @@ -789,15 +789,15 @@ IO::remove_output_port (Port* port, void* src) * * @param destination Name of input port to connect new port to. * @param src Source for emitted ConfigurationChanged signal. - * @param type Data type of port. Default value (Buffer::NIL) will use this IO's default type. + * @param type Data type of port. Default value (NIL) will use this IO's default type. */ int -IO::add_output_port (string destination, void* src, Buffer::Type type) +IO::add_output_port (string destination, void* src, DataType type) { Port* our_port; char name[64]; - if (type == Buffer::NIL) + if (type == NIL) type = _default_type; { @@ -904,12 +904,12 @@ IO::remove_input_port (Port* port, void* src) * @param src Source for emitted ConfigurationChanged signal. */ int -IO::add_input_port (string source, void* src, Buffer::Type type) +IO::add_input_port (string source, void* src, DataType type) { Port* our_port; char name[64]; - if (type == Buffer::NIL) + if (type == NIL) type = _default_type; { @@ -1026,10 +1026,8 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src) char buf[64]; - /* Create a new input port */ + /* Create a new input port (of the default type) */ - // FIXME: of what type? - if (_input_maximum == 1) { snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str()); } @@ -1128,10 +1126,8 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src) out_changed = true; } - /* create any necessary new ports */ + /* create any necessary new ports (of the default type) */ - // FIXME: of what type? - while (_ninputs < nin) { char buf[64]; diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 4602fc8f67..a43e5e9024 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -55,8 +55,6 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -sigc::signal*> MidiDiskstream::DeleteSources; - MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag) : Diskstream(sess, name, flag) , _playlist(NULL) @@ -412,7 +410,7 @@ MidiDiskstream::finish_capture (bool rec_monitors_input) } void -MidiDiskstream::set_record_enabled (bool yn, void* src) +MidiDiskstream::set_record_enabled (bool yn) { } diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 1e00879d53..bdf242bed0 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -40,7 +40,7 @@ using namespace ARDOUR; using namespace PBD; MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode) - : Track (sess, name, flag, mode, Buffer::MIDI) + : Track (sess, name, flag, mode, MIDI) { MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0); @@ -61,7 +61,7 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo _saved_meter_point = _meter_point; _mode = mode; - set_diskstream (*ds, this); + set_diskstream (*ds); } MidiTrack::MidiTrack (Session& sess, const XMLNode& node) @@ -82,7 +82,7 @@ MidiTrack::~MidiTrack () int -MidiTrack::set_diskstream (MidiDiskstream& ds, void *src) +MidiTrack::set_diskstream (MidiDiskstream& ds) { if (_diskstream) { _diskstream->unref(); @@ -92,13 +92,13 @@ MidiTrack::set_diskstream (MidiDiskstream& ds, void *src) _diskstream->set_io (*this); _diskstream->set_destructive (_mode == Destructive); - _diskstream->set_record_enabled (false, this); + _diskstream->set_record_enabled (false); //_diskstream->monitor_input (false); ic_connection.disconnect(); ic_connection = input_changed.connect (mem_fun (*_diskstream, &MidiDiskstream::handle_input_change)); - DiskstreamChanged (src); /* EMIT SIGNAL */ + DiskstreamChanged (); /* EMIT SIGNAL */ return 0; } @@ -113,7 +113,7 @@ MidiTrack::use_diskstream (string name) return -1; } - return set_diskstream (*dstream, this); + return set_diskstream (*dstream); } int @@ -126,7 +126,7 @@ MidiTrack::use_diskstream (const PBD::ID& id) return -1; } - return set_diskstream (*dstream, this); + return set_diskstream (*dstream); } bool @@ -517,7 +517,7 @@ MidiTrack::set_name (string str, void *src) return -1; } - if (_diskstream->set_name (str, src)) { + if (_diskstream->set_name (str)) { return -1; } diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 50d0033080..037c844324 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -39,13 +39,13 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -Change Region::FadeChanged = ARDOUR::new_change (); +Change Region::FadeChanged = ARDOUR::new_change (); Change Region::SyncOffsetChanged = ARDOUR::new_change (); -Change Region::MuteChanged = ARDOUR::new_change (); -Change Region::OpacityChanged = ARDOUR::new_change (); -Change Region::LockChanged = ARDOUR::new_change (); -Change Region::LayerChanged = ARDOUR::new_change (); -Change Region::HiddenChanged = ARDOUR::new_change (); +Change Region::MuteChanged = ARDOUR::new_change (); +Change Region::OpacityChanged = ARDOUR::new_change (); +Change Region::LockChanged = ARDOUR::new_change (); +Change Region::LayerChanged = ARDOUR::new_change (); +Change Region::HiddenChanged = ARDOUR::new_change (); sigc::signal Region::CheckNewRegion; diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 95b5d0ddaf..713eed1b82 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -51,7 +52,7 @@ using namespace PBD; uint32_t Route::order_key_cnt = 0; -Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, Buffer::Type default_type) +Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type) : IO (sess, name, input_min, input_max, output_min, output_max, default_type), _flags (flg), _solo_control (*this, ToggleControllable::SoloControl), @@ -1332,7 +1333,6 @@ Route::state(bool full_state) node->add_property("flags", buf); } - // FIXME: assumes there's only audio and MIDI types node->add_property("default-type", Buffer::type_to_string(_default_type)); node->add_property("active", _active?"yes":"no"); @@ -1511,7 +1511,7 @@ Route::set_state (const XMLNode& node) if ((prop = node.property ("default-type")) != 0) { _default_type = Buffer::type_from_string(prop->value()); - assert(_default_type != Buffer::NIL); + assert(_default_type != NIL); } if ((prop = node.property ("phase-invert")) != 0) { diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 011d1d6237..40457c33db 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -728,7 +728,7 @@ Session::when_engine_running () _master_out->defer_pan_reset (); while ((int) _master_out->n_inputs() < _master_out->input_maximum()) { - if (_master_out->add_input_port ("", this)) { // FIXME + if (_master_out->add_input_port ("", this, AUDIO)) { error << _("cannot setup master inputs") << endmsg; break; @@ -736,7 +736,7 @@ Session::when_engine_running () } n = 0; while ((int) _master_out->n_outputs() < _master_out->output_maximum()) { - if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) { // FIXME + if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this, AUDIO)) { error << _("cannot setup master outputs") << endmsg; break; @@ -1763,7 +1763,7 @@ Session::new_midi_track (TrackMode mode) track->set_control_outs (cports); } #endif - track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes_proxy)); + track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); add_route (track); @@ -1808,7 +1808,7 @@ Session::new_midi_route () } while (n < (UINT_MAX-1)); try { - shared_ptr bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::MIDI)); + shared_ptr bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), MIDI)); if (bus->ensure_io (1, 1, false, this)) { error << (_("cannot configure 1 in/1 out configuration for new midi track")) @@ -1971,7 +1971,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod track->set_control_outs (cports); } - track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes_proxy)); + track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); add_route (track); @@ -2016,7 +2016,7 @@ Session::new_audio_route (int input_channels, int output_channels) } while (n < (UINT_MAX-1)); try { - shared_ptr bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::AUDIO)); + shared_ptr bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), AUDIO)); if (bus->ensure_io (input_channels, output_channels, false, this)) { error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"), @@ -2487,7 +2487,6 @@ Session::diskstream_by_name (string name) { Glib::RWLock::ReaderLock lm (diskstream_lock); - // FIXME: duh for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->name() == name) { return* i; @@ -2502,7 +2501,6 @@ Session::diskstream_by_id (const PBD::ID& id) { Glib::RWLock::ReaderLock lm (diskstream_lock); - // FIXME: duh for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { if ((*i)->id() == id) { return *i; @@ -3259,11 +3257,14 @@ Session::audition_playlist () } void -Session::audition_region (AudioRegion& r) +Session::audition_region (Region& r) { - Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0); - ev->set_ptr (&r); - queue_event (ev); + AudioRegion* ar = dynamic_cast(&r); + if (ar) { + Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0); + ev->set_ptr (ar); + queue_event (ev); + } } void @@ -3360,18 +3361,6 @@ Session::n_diskstreams () const } return n; } -/* -void -Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void)) -{ - Glib::RWLock::ReaderLock lm (diskstream_lock); - for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { - if (!(*i)->hidden()) { - ((*i)->*func)(); - } - } -} -*/ void Session::graph_reordered () diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 0809aae6eb..f5bf0cc173 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -1742,15 +1743,15 @@ Session::XMLRouteFactory (const XMLNode& node) bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0); - Buffer::Type type = Buffer::AUDIO; + DataType type = AUDIO; const XMLProperty* prop = node.property("default-type"); if (prop) type = Buffer::type_from_string(prop->value()); - assert(type != Buffer::NIL); + assert(type != NIL); if (has_diskstream) { - if (type == Buffer::AUDIO) { + if (type == AUDIO) { boost::shared_ptr ret (new AudioTrack (*this, node)); return ret; } else { diff --git a/libs/ardour/smpte.cc b/libs/ardour/smpte.cc deleted file mode 100644 index 9ee582b802..0000000000 --- a/libs/ardour/smpte.cc +++ /dev/null @@ -1,405 +0,0 @@ -/* Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define SMPTE_IS_AROUND_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours) -#define SMPTE_IS_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours && !(sm.subframes)) - -#include - -namespace SMPTE { - -FPS Time::default_rate = MTC_30_FPS; - - -/** Increment @a smpte by exactly one frame (keep subframes value). - * Realtime safe. - * @return true if seconds wrap. - */ -Wrap -increment( Time& smpte ) -{ - Wrap wrap = NONE; - - if (smpte.negative) { - if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) { - // We have a zero transition involving only subframes - smpte.subframes = 80 - smpte.subframes; - smpte.negative = false; - return SECONDS; - } - - smpte.negative = false; - wrap = decrement( smpte ); - if (!SMPTE_IS_ZERO( smpte )) { - smpte.negative = true; - } - return wrap; - } - - switch (smpte.rate) { - case MTC_24_FPS: - if (smpte.frames == 23) { - smpte.frames = 0; - wrap = SECONDS; - } - break; - case MTC_25_FPS: - if (smpte.frames == 24) { - smpte.frames = 0; - wrap = SECONDS; - } - break; - case MTC_30_FPS_DROP: - if (smpte.frames == 29) { - if ( ((smpte.minutes + 1) % 10) && (smpte.seconds == 59) ) { - smpte.frames = 2; - } - else { - smpte.frames = 0; - } - wrap = SECONDS; - } - break; - case MTC_30_FPS: - if (smpte.frames == 29) { - smpte.frames = 0; - wrap = SECONDS; - } - break; - } - - if (wrap == SECONDS) { - if (smpte.seconds == 59) { - smpte.seconds = 0; - wrap = MINUTES; - if (smpte.minutes == 59) { - smpte.minutes = 0; - wrap = HOURS; - smpte.hours++; - } else { - smpte.minutes++; - } - } else { - smpte.seconds++; - } - } else { - smpte.frames++; - } - - return wrap; -} - - -/** Decrement @a smpte by exactly one frame (keep subframes value) - * Realtime safe. - * @return true if seconds wrap. */ -Wrap -decrement( Time& smpte ) -{ - Wrap wrap = NONE; - - - if (smpte.negative || SMPTE_IS_ZERO(smpte)) { - smpte.negative = false; - wrap = increment( smpte ); - smpte.negative = true; - return wrap; - } else if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) { - // We have a zero transition involving only subframes - smpte.subframes = 80 - smpte.subframes; - smpte.negative = true; - return SECONDS; - } - - switch (smpte.rate) { - case MTC_24_FPS: - if (smpte.frames == 0) { - smpte.frames = 23; - wrap = SECONDS; - } - break; - case MTC_25_FPS: - if (smpte.frames == 0) { - smpte.frames = 24; - wrap = SECONDS; - } - break; - case MTC_30_FPS_DROP: - if ((smpte.minutes % 10) && (smpte.seconds == 0)) { - if (smpte.frames <= 2) { - smpte.frames = 29; - wrap = SECONDS; - } - } else if (smpte.frames == 0) { - smpte.frames = 29; - wrap = SECONDS; - } - break; - case MTC_30_FPS: - if (smpte.frames == 0) { - smpte.frames = 29; - wrap = SECONDS; - } - break; - } - - if (wrap == SECONDS) { - if (smpte.seconds == 0) { - smpte.seconds = 59; - wrap = MINUTES; - if (smpte.minutes == 0) { - smpte.minutes = 59; - wrap = HOURS; - smpte.hours--; - } - else { - smpte.minutes--; - } - } else { - smpte.seconds--; - } - } else { - smpte.frames--; - } - - if (SMPTE_IS_ZERO( smpte )) { - smpte.negative = false; - } - - return wrap; -} - - -/** Go to lowest absolute subframe value in this frame (set to 0 :-) ) */ -void -frames_floor( Time& smpte ) -{ - smpte.subframes = 0; - if (SMPTE_IS_ZERO(smpte)) { - smpte.negative = false; - } -} - - -/** Increment @a smpte by one subframe */ -Wrap -increment_subframes( Time& smpte ) -{ - Wrap wrap = NONE; - - if (smpte.negative) { - smpte.negative = false; - wrap = decrement_subframes( smpte ); - if (!SMPTE_IS_ZERO(smpte)) { - smpte.negative = true; - } - return wrap; - } - - smpte.subframes++; - if (smpte.subframes >= 80) { - smpte.subframes = 0; - increment( smpte ); - return FRAMES; - } - return NONE; -} - - -/** Decrement @a smpte by one subframe */ -Wrap -decrement_subframes( Time& smpte ) -{ - Wrap wrap = NONE; - - if (smpte.negative) { - smpte.negative = false; - wrap = increment_subframes( smpte ); - smpte.negative = true; - return wrap; - } - - if (smpte.subframes <= 0) { - smpte.subframes = 0; - if (SMPTE_IS_ZERO(smpte)) { - smpte.negative = true; - smpte.subframes = 1; - return FRAMES; - } else { - decrement( smpte ); - smpte.subframes = 79; - return FRAMES; - } - } else { - smpte.subframes--; - if (SMPTE_IS_ZERO(smpte)) { - smpte.negative = false; - } - return NONE; - } -} - - -/** Go to next whole second (frames == 0 or frames == 2) */ -Wrap -increment_seconds( Time& smpte ) -{ - Wrap wrap = NONE; - - // Clear subframes - frames_floor( smpte ); - - if (smpte.negative) { - // Wrap second if on second boundary - wrap = increment(smpte); - // Go to lowest absolute frame value - seconds_floor( smpte ); - if (SMPTE_IS_ZERO(smpte)) { - smpte.negative = false; - } - } else { - // Go to highest possible frame in this second - switch (smpte.rate) { - case MTC_24_FPS: - smpte.frames = 23; - break; - case MTC_25_FPS: - smpte.frames = 24; - break; - case MTC_30_FPS_DROP: - case MTC_30_FPS: - smpte.frames = 29; - break; - } - - // Increment by one frame - wrap = increment( smpte ); - } - - return wrap; -} - - -/** Go to lowest (absolute) frame value in this second - * Doesn't care about positive/negative */ -void -seconds_floor( Time& smpte ) -{ - // Clear subframes - frames_floor( smpte ); - - // Go to lowest possible frame in this second - switch (smpte.rate) { - case MTC_24_FPS: - case MTC_25_FPS: - case MTC_30_FPS: - smpte.frames = 0; - break; - case MTC_30_FPS_DROP: - if ((smpte.minutes % 10) && (smpte.seconds == 0)) { - smpte.frames = 2; - } else { - smpte.frames = 0; - } - break; - } - - if (SMPTE_IS_ZERO(smpte)) { - smpte.negative = false; - } -} - - -/** Go to next whole minute (seconds == 0, frames == 0 or frames == 2) */ -Wrap -increment_minutes( Time& smpte ) -{ - Wrap wrap = NONE; - - // Clear subframes - frames_floor( smpte ); - - if (smpte.negative) { - // Wrap if on minute boundary - wrap = increment_seconds( smpte ); - // Go to lowest possible value in this minute - minutes_floor( smpte ); - } else { - // Go to highest possible second - smpte.seconds = 59; - // Wrap minute by incrementing second - wrap = increment_seconds( smpte ); - } - - return wrap; -} - - -/** Go to lowest absolute value in this minute */ -void -minutes_floor( Time& smpte ) -{ - // Go to lowest possible second - smpte.seconds = 0; - // Go to lowest possible frame - seconds_floor( smpte ); - - if (SMPTE_IS_ZERO(smpte)) { - smpte.negative = false; - } -} - - -/** Go to next whole hour (minute = 0, second = 0, frame = 0) */ -Wrap -increment_hours( Time& smpte ) -{ - Wrap wrap = NONE; - - // Clear subframes - frames_floor(smpte); - - if (smpte.negative) { - // Wrap if on hour boundary - wrap = increment_minutes( smpte ); - // Go to lowest possible value in this hour - hours_floor( smpte ); - } else { - smpte.minutes = 59; - wrap = increment_minutes( smpte ); - } - - return wrap; -} - - -/** Go to lowest absolute value in this hour */ -void -hours_floor( Time& smpte ) -{ - smpte.minutes = 0; - smpte.seconds = 0; - smpte.frames = 0; - smpte.subframes = 0; - - if (SMPTE_IS_ZERO(smpte)) { - smpte.negative = false; - } -} - - -} // namespace SMPTE diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index f3a177323c..3b3b705a87 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -20,8 +20,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -38,7 +38,7 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Buffer::Type default_type) +Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type) : Route (sess, name, 1, -1, -1, -1, flag, default_type) , _diskstream (0) , _rec_enable_control (*this) @@ -49,7 +49,7 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Buff _mode = mode; } -Track::Track (Session& sess, const XMLNode& node, Buffer::Type default_type) +Track::Track (Session& sess, const XMLNode& node, DataType default_type) : Route (sess, "to be renamed", 0, 0, -1, -1, Route::Flag(0), default_type) , _diskstream (0) , _rec_enable_control (*this) @@ -59,6 +59,13 @@ Track::Track (Session& sess, const XMLNode& node, Buffer::Type default_type) _saved_meter_point = _meter_point; } +Track::~Track () +{ + if (_diskstream) { + _diskstream->unref(); + } +} + void Track::set_meter_point (MeterPoint p, void *src) { @@ -134,3 +141,79 @@ Track::RecEnableControllable::get_value (void) const return 0.0f; } +bool +Track::record_enabled () const +{ + return _diskstream->record_enabled (); +} + +void +Track::set_record_enable (bool yn, void *src) +{ + if (_freeze_record.state == Frozen) { + return; + } + + if (_mix_group && src != _mix_group && _mix_group->is_active()) { + _mix_group->apply (&Track::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); + + if (_diskstream->record_enabled()) { + set_meter_point (MeterInput, this); + } else { + set_meter_point (_saved_meter_point, this); + } + + _rec_enable_control.Changed (); +} + +void +Track::set_mode (TrackMode m) +{ + if (_diskstream) { + if (_mode != m) { + _mode = m; + _diskstream->set_destructive (m == Destructive); + ModeChanged(); + } + } +} + +int +Track::set_name (string str, void *src) +{ + int ret; + + if (record_enabled() && _session.actively_recording()) { + /* this messes things up if done while recording */ + return -1; + } + + if (_diskstream->set_name (str)) { + return -1; + } + + /* save state so that the statefile fully reflects any filename changes */ + + if ((ret = IO::set_name (str, src)) == 0) { + _session.save_state (""); + } + return ret; +} + +void +Track::set_latency_delay (jack_nframes_t longest_session_latency) +{ + Route::set_latency_delay (longest_session_latency); + _diskstream->set_roll_delay (_roll_delay); +} + -- cgit v1.2.3