2 Copyright (C) 2001-2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 $Id: regionview.cc 682 2006-07-14 03:43:32Z drobilla $
27 #include <gtkmm2ext/gtk_ui.h>
29 #include <ardour/playlist.h>
30 #include <ardour/audioregion.h>
31 #include <ardour/audiosource.h>
32 #include <ardour/audio_diskstream.h>
34 #include "streamview.h"
35 #include "audio_regionview.h"
36 #include "audio_time_axis.h"
37 #include "simplerect.h"
38 #include "simpleline.h"
40 #include "public_editor.h"
41 #include "audio_region_editor.h"
42 #include "region_gain_line.h"
43 #include "ghostregion.h"
44 #include "audio_time_axis.h"
46 #include "rgb_macros.h"
47 #include "gui_thread.h"
52 using namespace ARDOUR;
54 using namespace Editing;
55 using namespace ArdourCanvas;
57 static const int32_t sync_mark_width = 9;
59 AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu,
60 Gdk::Color& basic_color)
61 : RegionView (parent, tv, r, spu, basic_color)
65 AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu,
66 Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility)
67 : RegionView (parent, tv, r, spu, basic_color, visibility)
72 AudioRegionView::init (Gdk::Color& basic_color, bool wfd)
74 // FIXME: Some redundancy here with RegionView::init. Need to figure out
75 // where order is important and where it isn't...
77 RegionView::init(basic_color, wfd);
81 _amplitude_above_axis = 1.0;
85 if ((node = _region.extra_xml ("GUI")) != 0) {
88 _flags = WaveformVisible;
92 if (trackview.editor.new_regionviews_display_gain()) {
93 _flags |= EnvelopeVisible;
96 compute_colors (basic_color);
100 fade_in_shape = new ArdourCanvas::Polygon (*group);
101 fade_in_shape->property_fill_color_rgba() = fade_color;
102 fade_in_shape->set_data ("regionview", this);
104 fade_out_shape = new ArdourCanvas::Polygon (*group);
105 fade_out_shape->property_fill_color_rgba() = fade_color;
106 fade_out_shape->set_data ("regionview", this);
111 UINT_TO_RGBA(fill_color,&r,&g,&b,&a);
114 fade_in_handle = new ArdourCanvas::SimpleRect (*group);
115 fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
116 fade_in_handle->property_outline_pixels() = 0;
117 fade_in_handle->property_y1() = 2.0;
118 fade_in_handle->property_y2() = 7.0;
120 fade_in_handle->set_data ("regionview", this);
122 fade_out_handle = new ArdourCanvas::SimpleRect (*group);
123 fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
124 fade_out_handle->property_outline_pixels() = 0;
125 fade_out_handle->property_y1() = 2.0;
126 fade_out_handle->property_y2() = 7.0;
128 fade_out_handle->set_data ("regionview", this);
131 string foo = _region.name();
135 gain_line = new AudioRegionGainLine (foo, trackview.session(), *this, *group, audio_region().envelope());
137 if (!(_flags & EnvelopeVisible)) {
143 reset_width_dependent_items ((double) _region.length() / samples_per_unit);
147 set_height (trackview.height);
150 region_sync_changed ();
151 region_resized (BoundsChanged);
152 set_waveview_data_src();
154 envelope_active_changed ();
155 fade_in_active_changed ();
156 fade_out_active_changed ();
158 _region.StateChanged.connect (mem_fun(*this, &AudioRegionView::region_changed));
160 fade_in_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_event), fade_in_shape, this));
161 fade_in_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_handle_event), fade_in_handle, this));
162 fade_out_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_event), fade_out_shape, this));
163 fade_out_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_handle_event), fade_out_handle, this));
167 /* XXX sync mark drag? */
170 AudioRegionView::~AudioRegionView ()
172 in_destructor = true;
174 RegionViewGoingAway (this); /* EMIT_SIGNAL */
176 for (vector<GnomeCanvasWaveViewCache *>::iterator cache = wave_caches.begin(); cache != wave_caches.end() ; ++cache) {
177 gnome_canvas_waveview_cache_destroy (*cache);
180 /* all waveviews etc will be destroyed when the group is destroyed */
188 AudioRegionView::audio_region() const
190 // "Guaranteed" to succeed...
191 return dynamic_cast<AudioRegion&>(_region);
195 AudioRegionView::region_changed (Change what_changed)
197 ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioRegionView::region_changed), what_changed));
199 RegionView::region_changed(what_changed);
201 if (what_changed & AudioRegion::ScaleAmplitudeChanged) {
202 region_scale_amplitude_changed ();
204 if (what_changed & AudioRegion::FadeInChanged) {
207 if (what_changed & AudioRegion::FadeOutChanged) {
210 if (what_changed & AudioRegion::FadeInActiveChanged) {
211 fade_in_active_changed ();
213 if (what_changed & AudioRegion::FadeOutActiveChanged) {
214 fade_out_active_changed ();
216 if (what_changed & AudioRegion::EnvelopeActiveChanged) {
217 envelope_active_changed ();
222 AudioRegionView::fade_in_changed ()
224 reset_fade_in_shape ();
228 AudioRegionView::fade_out_changed ()
230 reset_fade_out_shape ();
234 AudioRegionView::set_fade_in_active (bool yn)
236 audio_region().set_fade_in_active (yn);
240 AudioRegionView::set_fade_out_active (bool yn)
242 audio_region().set_fade_out_active (yn);
246 AudioRegionView::fade_in_active_changed ()
250 UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
252 if (audio_region().fade_in_active()) {
253 col = RGBA_TO_UINT(r,g,b,120);
254 fade_in_shape->property_fill_color_rgba() = col;
255 fade_in_shape->property_width_pixels() = 0;
256 fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0);
258 col = RGBA_TO_UINT(r,g,b,0);
259 fade_in_shape->property_fill_color_rgba() = col;
260 fade_in_shape->property_width_pixels() = 1;
261 fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255);
266 AudioRegionView::fade_out_active_changed ()
270 UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
272 if (audio_region().fade_out_active()) {
273 col = RGBA_TO_UINT(r,g,b,120);
274 fade_out_shape->property_fill_color_rgba() = col;
275 fade_out_shape->property_width_pixels() = 0;
276 fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0);
278 col = RGBA_TO_UINT(r,g,b,0);
279 fade_out_shape->property_fill_color_rgba() = col;
280 fade_out_shape->property_width_pixels() = 1;
281 fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255);
287 AudioRegionView::region_scale_amplitude_changed ()
289 ENSURE_GUI_THREAD (mem_fun(*this, &AudioRegionView::region_scale_amplitude_changed));
291 for (uint32_t n = 0; n < waves.size(); ++n) {
292 // force a reload of the cache
293 waves[n]->property_data_src() = &_region;
298 AudioRegionView::region_resized (Change what_changed)
300 RegionView::region_resized(what_changed);
302 if (what_changed & Change (StartChanged|LengthChanged)) {
304 for (uint32_t n = 0; n < waves.size(); ++n) {
305 waves[n]->property_region_start() = _region.start();
308 for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
310 for (vector<WaveView*>::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) {
311 (*w)->property_region_start() = _region.start();
318 AudioRegionView::reset_width_dependent_items (double pixel_width)
320 RegionView::reset_width_dependent_items(pixel_width);
321 assert(_pixel_width == pixel_width);
324 zero_line->property_x2() = pixel_width - 1.0;
327 if (fade_in_handle) {
328 if (pixel_width <= 6.0) {
329 fade_in_handle->hide();
330 fade_out_handle->hide();
333 fade_in_handle->hide();
334 fade_out_handle->hide();
336 fade_in_handle->show();
337 fade_out_handle->show();
342 reset_fade_shapes ();
346 AudioRegionView::region_muted ()
348 RegionView::region_muted();
350 for (uint32_t n=0; n < waves.size(); ++n) {
351 if (_region.muted()) {
352 waves[n]->property_wave_color() = color_map[cMutedWaveForm];
354 waves[n]->property_wave_color() = color_map[cWaveForm];
361 AudioRegionView::set_height (gdouble height)
363 uint32_t wcnt = waves.size();
366 TimeAxisViewItem::set_height (height - 2);
370 for (uint32_t n=0; n < wcnt; ++n) {
373 if ((height) <= NAME_HIGHLIGHT_THRESH) {
374 ht = ((height-2*wcnt) / (double) wcnt);
376 ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
379 gdouble yoff = n * (ht+1);
381 waves[n]->property_height() = ht;
382 waves[n]->property_y() = yoff + 2;
386 if ((height/wcnt) < NAME_HIGHLIGHT_SIZE) {
389 if (_flags & EnvelopeVisible) {
393 gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE));
397 reset_fade_shapes ();
400 name_text->raise_to_top();
405 AudioRegionView::manage_zero_line ()
411 if (_height >= 100) {
412 gdouble wave_midpoint = (_height - NAME_HIGHLIGHT_SIZE) / 2.0;
413 zero_line->property_y1() = wave_midpoint;
414 zero_line->property_y2() = wave_midpoint;
422 AudioRegionView::reset_fade_shapes ()
424 reset_fade_in_shape ();
425 reset_fade_out_shape ();
429 AudioRegionView::reset_fade_in_shape ()
431 reset_fade_in_shape_width ((jack_nframes_t) audio_region().fade_in().back()->when);
435 AudioRegionView::reset_fade_in_shape_width (jack_nframes_t width)
437 if (fade_in_handle == 0) {
441 /* smallest size for a fade is 64 frames */
443 width = std::max ((jack_nframes_t) 64, width);
446 double pwidth = width / samples_per_unit;
447 uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth);
451 fade_in_shape->hide();
452 fade_in_handle->hide();
456 double handle_center;
457 handle_center = pwidth;
459 if (handle_center > 7.0) {
460 handle_center -= 3.0;
465 fade_in_handle->property_x1() = handle_center - 3.0;
466 fade_in_handle->property_x2() = handle_center + 3.0;
469 fade_in_shape->hide();
473 fade_in_shape->show();
475 float curve[npoints];
476 audio_region().fade_in().get_vector (0, audio_region().fade_in().back()->when, curve, npoints);
478 points = get_canvas_points ("fade in shape", npoints+3);
480 if (_height > NAME_HIGHLIGHT_THRESH) {
481 h = _height - NAME_HIGHLIGHT_SIZE;
486 /* points *MUST* be in anti-clockwise order */
489 double xdelta = pwidth/npoints;
491 for (pi = 0, pc = 0; pc < npoints; ++pc) {
492 (*points)[pi].set_x(1 + (pc * xdelta));
493 (*points)[pi++].set_y(2 + (h - (curve[pc] * h)));
498 (*points)[pi].set_x(pwidth);
499 (*points)[pi++].set_y(2);
501 (*points)[pi].set_x(1);
502 (*points)[pi++].set_y(2);
504 /* connect the dots ... */
506 (*points)[pi] = (*points)[0];
508 fade_in_shape->property_points() = *points;
513 AudioRegionView::reset_fade_out_shape ()
515 reset_fade_out_shape_width ((jack_nframes_t) audio_region().fade_out().back()->when);
519 AudioRegionView::reset_fade_out_shape_width (jack_nframes_t width)
521 if (fade_out_handle == 0) {
525 /* smallest size for a fade is 64 frames */
527 width = std::max ((jack_nframes_t) 64, width);
530 double pwidth = width / samples_per_unit;
531 uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth);
535 fade_out_shape->hide();
536 fade_out_handle->hide();
540 double handle_center;
541 handle_center = (_region.length() - width) / samples_per_unit;
543 if (handle_center > 7.0) {
544 handle_center -= 3.0;
549 fade_out_handle->property_x1() = handle_center - 3.0;
550 fade_out_handle->property_x2() = handle_center + 3.0;
552 /* don't show shape if its too small */
555 fade_out_shape->hide();
559 fade_out_shape->show();
561 float curve[npoints];
562 audio_region().fade_out().get_vector (0, audio_region().fade_out().back()->when, curve, npoints);
564 if (_height > NAME_HIGHLIGHT_THRESH) {
565 h = _height - NAME_HIGHLIGHT_SIZE;
570 /* points *MUST* be in anti-clockwise order */
572 points = get_canvas_points ("fade out shape", npoints+3);
575 double xdelta = pwidth/npoints;
577 for (pi = 0, pc = 0; pc < npoints; ++pc) {
578 (*points)[pi].set_x(_pixel_width - 1 - pwidth + (pc*xdelta));
579 (*points)[pi++].set_y(2 + (h - (curve[pc] * h)));
584 (*points)[pi].set_x(_pixel_width);
585 (*points)[pi++].set_y(h);
587 (*points)[pi].set_x(_pixel_width);
588 (*points)[pi++].set_y(2);
590 /* connect the dots ... */
592 (*points)[pi] = (*points)[0];
594 fade_out_shape->property_points() = *points;
599 AudioRegionView::set_samples_per_unit (gdouble spu)
601 RegionView::set_samples_per_unit (spu);
603 for (uint32_t n=0; n < waves.size(); ++n) {
604 waves[n]->property_samples_per_unit() = spu;
610 reset_fade_shapes ();
614 AudioRegionView::set_amplitude_above_axis (gdouble spp)
616 for (uint32_t n=0; n < waves.size(); ++n) {
617 waves[n]->property_amplitude_above_axis() = spp;
622 AudioRegionView::compute_colors (Gdk::Color& basic_color)
624 RegionView::compute_colors(basic_color);
628 /* gain color computed in envelope_active_changed() */
630 UINT_TO_RGBA (fill_color, &r, &g, &b, &a);
631 fade_color = RGBA_TO_UINT(r,g,b,120);
635 AudioRegionView::set_colors ()
637 RegionView::set_colors();
640 gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]);
643 for (uint32_t n=0; n < waves.size(); ++n) {
644 if (_region.muted()) {
645 waves[n]->property_wave_color() = color_map[cMutedWaveForm];
647 waves[n]->property_wave_color() = color_map[cWaveForm];
653 AudioRegionView::show_region_editor ()
656 editor = new AudioRegionEditor (trackview.session(), audio_region(), *this);
657 // GTK2FIX : how to ensure float without realizing
658 // editor->realize ();
659 // trackview.editor.ensure_float (*editor);
663 editor->get_window()->raise();
667 AudioRegionView::set_waveform_visible (bool yn)
669 if (((_flags & WaveformVisible) != yn)) {
671 for (uint32_t n=0; n < waves.size(); ++n) {
674 _flags |= WaveformVisible;
676 for (uint32_t n=0; n < waves.size(); ++n) {
679 _flags &= ~WaveformVisible;
686 AudioRegionView::temporarily_hide_envelope ()
694 AudioRegionView::unhide_envelope ()
696 if (gain_line && (_flags & EnvelopeVisible)) {
702 AudioRegionView::set_envelope_visible (bool yn)
704 if (gain_line && ((_flags & EnvelopeVisible) != yn)) {
707 _flags |= EnvelopeVisible;
710 _flags &= ~EnvelopeVisible;
717 AudioRegionView::create_waves ()
719 bool create_zero_line = true;
721 RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick
723 if (!atv.get_diskstream()) {
727 uint32_t nchans = atv.get_diskstream()->n_channels();
729 /* in tmp_waves, set up null pointers for each channel so the vector is allocated */
730 for (uint32_t n = 0; n < nchans; ++n) {
731 tmp_waves.push_back (0);
734 for (uint32_t n = 0; n < nchans; ++n) {
736 if (n >= audio_region().n_channels()) {
740 wave_caches.push_back (WaveView::create_cache ());
743 if (audio_region().source(n).peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) {
744 create_one_wave (n, true);
746 create_zero_line = false;
749 create_one_wave (n, true);
753 if (create_zero_line) {
754 zero_line = new ArdourCanvas::SimpleLine (*group);
755 zero_line->property_x1() = (gdouble) 1.0;
756 zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0;
757 zero_line->property_color_rgba() = (guint) color_map[cZeroLine];
763 AudioRegionView::create_one_wave (uint32_t which, bool direct)
765 RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick
766 uint32_t nchans = atv.get_diskstream()->n_channels();
768 uint32_t nwaves = std::min (nchans, audio_region().n_channels());
771 if (trackview.height < NAME_HIGHLIGHT_SIZE) {
772 ht = ((trackview.height) / (double) nchans);
774 ht = ((trackview.height - NAME_HIGHLIGHT_SIZE) / (double) nchans);
777 gdouble yoff = which * ht;
779 WaveView *wave = new WaveView(*group);
781 wave->property_data_src() = (gpointer) &_region;
782 wave->property_cache() = wave_caches[which];
783 wave->property_cache_updater() = true;
784 wave->property_channel() = which;
785 wave->property_length_function() = (gpointer) region_length_from_c;
786 wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c;
787 wave->property_peak_function() = (gpointer) region_read_peaks_from_c;
788 wave->property_x() = 0.0;
789 wave->property_y() = yoff;
790 wave->property_height() = (double) ht;
791 wave->property_samples_per_unit() = samples_per_unit;
792 wave->property_amplitude_above_axis() = _amplitude_above_axis;
793 wave->property_wave_color() = _region.muted() ? color_map[cMutedWaveForm] : color_map[cWaveForm];
794 wave->property_region_start() = _region.start();
796 if (!(_flags & WaveformVisible)) {
800 /* note: calling this function is serialized by the lock
801 held in the peak building thread that signals that
802 peaks are ready for use *or* by the fact that it is
803 called one by one from the GUI thread.
806 if (which < nchans) {
807 tmp_waves[which] = wave;
809 /* n-channel track, >n-channel source */
812 /* see if we're all ready */
814 for (n = 0; n < nchans; ++n) {
815 if (tmp_waves[n] == 0) {
820 if (n == nwaves && waves.empty()) {
821 /* all waves are ready */
822 tmp_waves.resize(nwaves);
828 zero_line = new ArdourCanvas::SimpleLine (*group);
829 zero_line->property_x1() = (gdouble) 1.0;
830 zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0;
831 zero_line->property_color_rgba() = (guint) color_map[cZeroLine];
838 AudioRegionView::peaks_ready_handler (uint32_t which)
840 Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &AudioRegionView::create_one_wave), which, false));
842 if (!waves.empty()) {
843 /* all waves created, don't hook into peaks ready anymore */
844 data_ready_connection.disconnect ();
849 AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
851 if (gain_line == 0) {
857 /* don't create points that can't be seen */
859 set_envelope_visible (true);
866 jack_nframes_t fx = trackview.editor.pixel_to_frame (x);
868 if (fx > _region.length()) {
872 /* compute vertical fractional position */
874 y = 1.0 - (y / (trackview.height - NAME_HIGHLIGHT_SIZE));
876 /* map using gain line */
878 gain_line->view_to_model_y (y);
880 trackview.session().begin_reversible_command (_("add gain control point"));
881 trackview.session().add_undo (audio_region().envelope().get_memento());
884 if (!audio_region().envelope_active()) {
885 trackview.session().add_undo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), false) );
886 audio_region().set_envelope_active(true);
887 trackview.session().add_redo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), true) );
890 audio_region().envelope().add (fx, y);
892 trackview.session().add_redo_no_execute (audio_region().envelope().get_memento());
893 trackview.session().commit_reversible_command ();
897 AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
899 ControlPoint *cp = reinterpret_cast<ControlPoint *> (item->get_data ("control_point"));
900 audio_region().envelope().erase (cp->model);
904 AudioRegionView::store_flags()
906 XMLNode *node = new XMLNode ("GUI");
908 node->add_property ("waveform-visible", (_flags & WaveformVisible) ? "yes" : "no");
909 node->add_property ("envelope-visible", (_flags & EnvelopeVisible) ? "yes" : "no");
911 _region.add_extra_xml (*node);
915 AudioRegionView::set_flags (XMLNode* node)
919 if ((prop = node->property ("waveform-visible")) != 0) {
920 if (prop->value() == "yes") {
921 _flags |= WaveformVisible;
925 if ((prop = node->property ("envelope-visible")) != 0) {
926 if (prop->value() == "yes") {
927 _flags |= EnvelopeVisible;
933 AudioRegionView::set_waveform_shape (WaveformShape shape)
937 /* this slightly odd approach is to leave the door open to
938 other "shapes" such as spectral displays, etc.
951 if (yn != (bool) (_flags & WaveformRectified)) {
952 for (vector<WaveView *>::iterator wave = waves.begin(); wave != waves.end() ; ++wave) {
953 (*wave)->property_rectified() = yn;
965 _flags |= WaveformRectified;
967 _flags &= ~WaveformRectified;
973 AudioRegionView::add_ghost (AutomationTimeAxisView& atv)
975 RouteTimeAxisView& myatv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick
976 double unit_position = _region.position () / samples_per_unit;
977 GhostRegion* ghost = new GhostRegion (atv, unit_position);
980 nchans = myatv.get_diskstream()->n_channels();
982 for (uint32_t n = 0; n < nchans; ++n) {
984 if (n >= audio_region().n_channels()) {
988 WaveView *wave = new WaveView(*ghost->group);
990 wave->property_data_src() = &_region;
991 wave->property_cache() = wave_caches[n];
992 wave->property_cache_updater() = false;
993 wave->property_channel() = n;
994 wave->property_length_function() = (gpointer)region_length_from_c;
995 wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c;
996 wave->property_peak_function() = (gpointer) region_read_peaks_from_c;
997 wave->property_x() = 0.0;
998 wave->property_samples_per_unit() = samples_per_unit;
999 wave->property_amplitude_above_axis() = _amplitude_above_axis;
1000 wave->property_wave_color() = color_map[cGhostTrackWave];
1001 wave->property_region_start() = _region.start();
1003 ghost->waves.push_back(wave);
1006 ghost->set_height ();
1007 ghost->set_duration (_region.length() / samples_per_unit);
1008 ghosts.push_back (ghost);
1010 ghost->GoingAway.connect (mem_fun(*this, &AudioRegionView::remove_ghost));
1016 AudioRegionView::entered ()
1018 if (gain_line && _flags & EnvelopeVisible) {
1019 gain_line->show_all_control_points ();
1023 UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
1026 if (fade_in_handle) {
1027 fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
1028 fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
1033 AudioRegionView::exited ()
1036 gain_line->hide_all_but_selected_control_points ();
1040 UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
1043 if (fade_in_handle) {
1044 fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
1045 fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
1050 AudioRegionView::envelope_active_changed ()
1053 gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]);
1058 AudioRegionView::set_waveview_data_src()
1061 double unit_length= _region.length() / samples_per_unit;
1063 for (uint32_t n = 0; n < waves.size(); ++n) {
1064 // TODO: something else to let it know the channel
1065 waves[n]->property_data_src() = &_region;
1068 for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
1070 (*i)->set_duration (unit_length);
1072 for (vector<WaveView*>::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) {
1073 (*w)->property_data_src() = &_region;
1080 AudioRegionView::color_handler (ColorID id, uint32_t val)
1083 case cMutedWaveForm:
1088 case cGainLineInactive:
1090 envelope_active_changed();
1095 zero_line->property_color_rgba() = (guint) color_map[cZeroLine];
1099 case cGhostTrackWave: