#include "utils.h"
#include "color.h"
+#include "i18n.h"
+
using namespace ARDOUR;
using namespace PBD;
using namespace Editing;
: StreamView (tv)
{
crossfades_visible = true;
-
+ _waveform_scale = LinearWaveform;
+ _waveform_shape = Traditional;
+
if (tv.is_audio_track())
stream_base_color = color_map[cAudioTrackBase];
else
void
AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves)
{
+ AudioRegionView *region_view = 0;
+
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_region_view), r));
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r);
return;
}
- AudioRegionView *region_view;
- list<RegionView *>::iterator i;
-
- for (i = region_views.begin(); i != region_views.end(); ++i) {
+ for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
if ((*i)->region() == r) {
/* great. we already have a AudioRegionView for this Region. use it again. */
-
+
(*i)->set_valid (true);
+
+ // this might not be necessary
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+ if (arv) {
+ arv->set_waveform_scale (_waveform_scale);
+ arv->set_waveform_shape (_waveform_shape);
+ }
+
return;
}
}
-
+
switch (_trackview.audio_track()->mode()) {
case Normal:
region_view = new AudioRegionView (canvas_group, _trackview, region,
region_view = new TapeAudioRegionView (canvas_group, _trackview, region,
_samples_per_unit, region_color);
break;
+ default:
+ fatal << string_compose (_("programming error: %1"), "illegal track mode in ::add_region_view_internal") << endmsg;
+ /*NOTREACHED*/
+
}
region_view->init (region_color, wait_for_waves);
region_view->set_amplitude_above_axis(_amplitude_above_axis);
region_views.push_front (region_view);
+
+
+ /* if its the special single-sample length that we use for rec-regions, make it
+ insensitive to events
+ */
+
+ if (region->length() == 1) {
+ region_view->set_sensitive (false);
+ }
+
+ /* if this was the first one, then lets query the waveform scale and shape.
+ otherwise, we set it to the current value */
+
+ if (region_views.size() == 1) {
+ if (region_view->waveform_logscaled()) {
+ _waveform_scale = LogWaveform;
+ } else {
+ _waveform_scale = LinearWaveform;
+ }
+
+ if (region_view->waveform_rectified()) {
+ _waveform_shape = Rectified;
+ } else {
+ _waveform_shape = Traditional;
+ }
+ }
+ else {
+ region_view->set_waveform_scale(_waveform_scale);
+ region_view->set_waveform_shape(_waveform_shape);
+ }
/* follow global waveform setting */
region_view->set_waveform_visible(_trackview.editor.show_waveforms());
/* catch regionview going away */
+ region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), boost::weak_ptr<Region> (r)));
- region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), region));
-
RegionViewAdded (region_view);
}
void
-AudioStreamView::remove_region_view (boost::shared_ptr<Region> r)
+AudioStreamView::remove_region_view (boost::weak_ptr<Region> weak_r)
{
- ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_region_view), r));
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_region_view), weak_r));
- for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
- list<CrossfadeView*>::iterator tmp;
-
- tmp = i;
- ++tmp;
-
- boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
- if (ar && (*i)->crossfade.involves (ar)) {
- delete *i;
- crossfade_views.erase (i);
+ boost::shared_ptr<Region> r (weak_r.lock());
+
+ if (!r) {
+ return;
+ }
+
+ if (!_trackview.session().deletion_in_progress()) {
+
+ for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
+ list<CrossfadeView*>::iterator tmp;
+
+ tmp = i;
+ ++tmp;
+
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
+ if (ar && (*i)->crossfade->involves (ar)) {
+ delete *i;
+ crossfade_views.erase (i);
+ }
+
+ i = tmp;
}
-
- i = tmp;
}
+
StreamView::remove_region_view(r);
}
StreamView::playlist_modified();
- /* if the playlist is modified, make sure xfades are on top and all the regionviews are stacked
- correctly.
- */
+ /* make sure xfades are on top and all the regionviews are stacked correctly. */
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
(*i)->get_canvas_group()->raise_to_top();
StreamView::playlist_changed(ds);
- AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(ds->playlist());
+ boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(ds->playlist());
if (apl)
playlist_connections.push_back (apl->NewCrossfade.connect (mem_fun (*this, &AudioStreamView::add_crossfade)));
}
void
-AudioStreamView::add_crossfade (Crossfade *crossfade)
+AudioStreamView::add_crossfade (boost::shared_ptr<Crossfade> crossfade)
{
AudioRegionView* lview = 0;
AudioRegionView* rview = 0;
-
+
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_crossfade), crossfade));
/* first see if we already have a CrossfadeView for this Crossfade */
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- if (&(*i)->crossfade == crossfade) {
+ if ((*i)->crossfade == crossfade) {
if (!crossfades_visible) {
(*i)->hide();
} else {
CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display,
_trackview,
- *crossfade,
+ crossfade,
_samples_per_unit,
region_color,
*lview, *rview);
crossfade->Invalidated.connect (mem_fun (*this, &AudioStreamView::remove_crossfade));
crossfade_views.push_back (cv);
- if (!crossfades_visible) {
+ if (!Config->get_xfades_visible() || !crossfades_visible) {
cv->hide ();
}
}
void
-AudioStreamView::remove_crossfade (Crossfade *xfade)
+AudioStreamView::remove_crossfade (boost::shared_ptr<Crossfade> xfade)
{
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_crossfade), xfade));
for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- if (&(*i)->crossfade == xfade) {
+ if ((*i)->crossfade == xfade) {
delete *i;
crossfade_views.erase (i);
break;
list<RegionView *>::iterator i, tmp;
list<CrossfadeView*>::iterator xi, tmpx;
-
for (i = region_views.begin(); i != region_views.end(); ++i) {
(*i)->set_valid (false);
}
if (_trackview.is_audio_track()) {
_trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view);
- AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(_trackview.get_diskstream()->playlist());
+
+ boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_trackview.get_diskstream()->playlist());
if (apl)
apl->foreach_crossfade (this, &AudioStreamView::add_crossfade);
}
/* now fix layering */
- playlist_modified ();
+ for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ region_layered (*i);
+ }
}
void
if (arv)
arv->set_waveform_shape (shape);
}
+ _waveform_shape = shape;
}
-
+
+void
+AudioStreamView::set_waveform_scale (WaveformScale scale)
+{
+ for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+ if (arv)
+ arv->set_waveform_scale (scale);
+ }
+ _waveform_scale = scale;
+}
+
void
AudioStreamView::setup_rec_box ()
{
boost::shared_ptr<AudioFileSource> src = boost::static_pointer_cast<AudioFileSource> (ads->write_source (n));
if (src) {
sources.push_back (src);
- peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), src)));
+ peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), boost::weak_ptr<Source>(src))));
}
}
// handle multi
- jack_nframes_t start = 0;
+ nframes_t start = 0;
if (rec_regions.size() > 0) {
start = rec_regions.back()->start() + _trackview.get_diskstream()->get_captured_frames(rec_regions.size()-1);
}
boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion>
(RegionFactory::create (sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false)));
region->set_position (_trackview.session().transport_frame(), this);
- rec_regions.push_back (region);
- /* catch it if it goes away */
- region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_rec_region), region));
- /* we add the region later */
+ rec_regions.push_back (region);
}
/* start a new rec box */
at = _trackview.audio_track(); /* we know what it is already */
boost::shared_ptr<AudioDiskstream> ds = at->audio_diskstream();
- jack_nframes_t frame_pos = ds->current_capture_start ();
+ nframes_t frame_pos = ds->current_capture_start ();
gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
gdouble xend;
uint32_t fill_color;
last_rec_peak_frame = 0;
/* remove temp regions */
-
+
+ for (list<boost::shared_ptr<Region> >::iterator iter = rec_regions.begin(); iter != rec_regions.end(); ) {
+ list<boost::shared_ptr<Region> >::iterator tmp;
+
+ tmp = iter;
+ ++tmp;
+
+ (*iter)->drop_references ();
+
+ iter = tmp;
+ }
+
rec_regions.clear();
// cerr << "\tclear " << rec_rects.size() << " rec rects\n";
}
void
-AudioStreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, boost::shared_ptr<Source> src)
+AudioStreamView::rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::weak_ptr<Source> weak_src)
{
- // this is called from the peak building thread
+ ENSURE_GUI_THREAD(bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), start, cnt, weak_src));
+
+ boost::shared_ptr<Source> src (weak_src.lock());
+
+ if (!src) {
+ return;
+ }
- ENSURE_GUI_THREAD(bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), start, cnt, src));
+ // this is called from the peak building thread
if (rec_peak_ready_map.size() == 0 || start+cnt > last_rec_peak_frame) {
last_rec_peak_frame = start + cnt;
}
-
+
rec_peak_ready_map[src] = true;
-
+
if (rec_peak_ready_map.size() == _trackview.get_diskstream()->n_channels()) {
this->update_rec_regions ();
rec_peak_ready_map.clear();
continue;
}
- // FIXME
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion>(*iter);
- assert(region);
+ if (!region) {
+ continue;
+ }
- jack_nframes_t origlen = region->length();
+ nframes_t origlen = region->length();
if (region == rec_regions.back() && rec_active) {
if (last_rec_peak_frame > region->start()) {
- jack_nframes_t nlen = last_rec_peak_frame - region->start();
+ nframes_t nlen = last_rec_peak_frame - region->start();
if (nlen != region->length()) {
} else {
- jack_nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n);
+ nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n);
if (nlen != region->length()) {
AudioStreamView::hide_xfades_involving (AudioRegionView& rv)
{
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- if ((*i)->crossfade.involves (rv.audio_region())) {
+ if ((*i)->crossfade->involves (rv.audio_region())) {
(*i)->fake_hide ();
}
}
AudioStreamView::reveal_xfades_involving (AudioRegionView& rv)
{
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- if ((*i)->crossfade.involves (rv.audio_region()) && (*i)->visible()) {
+ if ((*i)->crossfade->involves (rv.audio_region()) && (*i)->visible()) {
(*i)->show ();
}
}