summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-04-22 01:40:33 +0000
committerCarl Hetherington <carl@carlh.net>2010-04-22 01:40:33 +0000
commit9213e9c9094468ce21be378ea017b0da1405bf03 (patch)
tree99424cd6f17fa93a354deae97db76af98b6f06e7
parent5b4b2c04e522f8c71b23359519c19160c886c8b9 (diff)
Allow more than one peaks_ready callback to be pending for an AudioRegionView
at any one time. Prevents problems when there is more than 1 channel for which peaks are not ready; before, the first peaks_ready callback would be forgotten when the second one was requested. Should fix #3074. git-svn-id: svn://localhost/ardour2/branches/3.0@6951 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/audio_region_view.cc21
-rw-r--r--gtk2_ardour/audio_region_view.h5
-rw-r--r--gtk2_ardour/crossfade_edit.cc16
-rw-r--r--gtk2_ardour/crossfade_edit.h2
-rw-r--r--gtk2_ardour/region_view.h3
-rw-r--r--gtk2_ardour/strip_silence_dialog.cc11
-rw-r--r--gtk2_ardour/strip_silence_dialog.h2
-rw-r--r--libs/ardour/ardour/audiosource.h3
-rw-r--r--libs/ardour/ardour/source.h1
-rw-r--r--libs/ardour/audiosource.cc14
10 files changed, 61 insertions, 17 deletions
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 394751b88c..a3aa56d26f 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -110,7 +110,6 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other)
, _amplitude_above_axis(1.0)
, _flags(0)
, fade_color(0)
-
{
Gdk::Color c;
int r,g,b,a;
@@ -132,7 +131,6 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, boost::shared_pt
, _amplitude_above_axis(1.0)
, _flags(0)
, fade_color(0)
-
{
Gdk::Color c;
int r,g,b,a;
@@ -251,6 +249,10 @@ AudioRegionView::~AudioRegionView ()
gnome_canvas_waveview_cache_destroy (*cache);
}
+ for (vector<ScopedConnection*>::iterator i = _data_ready_connections.begin(); i != _data_ready_connections.end(); ++i) {
+ delete *i;
+ }
+
/* all waveviews etc will be destroyed when the group is destroyed */
delete gain_line;
@@ -860,6 +862,16 @@ AudioRegionView::create_waves ()
tmp_waves.push_back (0);
}
+ for (vector<ScopedConnection*>::iterator i = _data_ready_connections.begin(); i != _data_ready_connections.end(); ++i) {
+ delete *i;
+ }
+
+ _data_ready_connections.clear ();
+
+ for (uint32_t i = 0; i < nchans.n_audio(); ++i) {
+ _data_ready_connections.push_back (0);
+ }
+
for (uint32_t n = 0; n < nchans.n_audio(); ++n) {
if (n >= audio_region()->n_channels()) {
@@ -871,7 +883,7 @@ AudioRegionView::create_waves ()
// cerr << "\tchannel " << n << endl;
if (wait_for_data) {
- if (audio_region()->audio_source(n)->peaks_ready (boost::bind (&AudioRegionView::peaks_ready_handler, this, n), data_ready_connection, gui_context())) {
+ if (audio_region()->audio_source(n)->peaks_ready (boost::bind (&AudioRegionView::peaks_ready_handler, this, n), &_data_ready_connections[n], gui_context())) {
// cerr << "\tData is ready\n";
create_one_wave (n, true);
} else {
@@ -967,7 +979,8 @@ AudioRegionView::create_one_wave (uint32_t which, bool /*direct*/)
tmp_waves.clear ();
/* all waves created, don't hook into peaks ready anymore */
- data_ready_connection.disconnect ();
+ delete _data_ready_connections[which];
+ _data_ready_connections[which] = 0;
#if 0
if (!zero_line) {
diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h
index b5fc89d0a9..097c839f6c 100644
--- a/gtk2_ardour/audio_region_view.h
+++ b/gtk2_ardour/audio_region_view.h
@@ -174,6 +174,11 @@ class AudioRegionView : public RegionView
private:
void setup_fade_handle_positions ();
+
+ /** A ScopedConnection for each PeaksReady callback (one per channel). Each member
+ * may be 0 if no connection exists.
+ */
+ std::vector<PBD::ScopedConnection*> _data_ready_connections;
};
#endif /* __gtk_ardour_audio_region_view_h__ */
diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc
index d420e36c46..78d3c74ab6 100644
--- a/gtk2_ardour/crossfade_edit.cc
+++ b/gtk2_ardour/crossfade_edit.cc
@@ -93,7 +93,10 @@ CrossfadeEditor::CrossfadeEditor (Session* s, boost::shared_ptr<Crossfade> xf, d
fade_out_table (3, 3),
select_in_button (_("Fade In")),
- select_out_button (_("Fade Out"))
+ select_out_button (_("Fade Out")),
+
+ _peaks_ready_connection (0)
+
{
set_session (s);
@@ -308,6 +311,8 @@ CrossfadeEditor::~CrossfadeEditor()
for (list<Point*>::iterator i = fade[Out].points.begin(); i != fade[Out].points.end(); ++i) {
delete *i;
}
+
+ delete _peaks_ready_connection;
}
void
@@ -1138,11 +1143,14 @@ CrossfadeEditor::make_waves (boost::shared_ptr<AudioRegion> region, WhichFade wh
ht = canvas->get_allocation().get_height() / (double) nchans;
spu = xfade->length() / (double) effective_width();
+ delete _peaks_ready_connection;
+ _peaks_ready_connection = 0;
+
for (uint32_t n = 0; n < nchans; ++n) {
gdouble yoff = n * ht;
- if (region->audio_source(n)->peaks_ready (boost::bind (&CrossfadeEditor::peaks_ready, this, boost::weak_ptr<AudioRegion>(region), which), peaks_ready_connection, gui_context())) {
+ if (region->audio_source(n)->peaks_ready (boost::bind (&CrossfadeEditor::peaks_ready, this, boost::weak_ptr<AudioRegion>(region), which), &_peaks_ready_connection, gui_context())) {
WaveView* waveview = new WaveView (*(canvas->root()));
waveview->property_data_src() = region.get();
@@ -1188,7 +1196,9 @@ CrossfadeEditor::peaks_ready (boost::weak_ptr<AudioRegion> wr, WhichFade which)
will be ready by the time we want them. but our API forces us
to provide this, so ..
*/
- peaks_ready_connection.disconnect ();
+ delete _peaks_ready_connection;
+ _peaks_ready_connection = 0;
+
make_waves (r, which);
}
diff --git a/gtk2_ardour/crossfade_edit.h b/gtk2_ardour/crossfade_edit.h
index 936ead3895..fab459c54f 100644
--- a/gtk2_ardour/crossfade_edit.h
+++ b/gtk2_ardour/crossfade_edit.h
@@ -183,7 +183,7 @@ class CrossfadeEditor : public ArdourDialog
void set (const ARDOUR::AutomationList& alist, WhichFade);
- PBD::ScopedConnection peaks_ready_connection;
+ PBD::ScopedConnection* _peaks_ready_connection;
PBD::ScopedConnection state_connection;
void make_waves (boost::shared_ptr<ARDOUR::AudioRegion>, WhichFade);
diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h
index d9bf4cd7e0..228fcdab42 100644
--- a/gtk2_ardour/region_view.h
+++ b/gtk2_ardour/region_view.h
@@ -137,8 +137,7 @@ class RegionView : public TimeAxisViewItem
double _pixel_width;
bool in_destructor;
- bool wait_for_data;
- PBD::ScopedConnection data_ready_connection;
+ bool wait_for_data;
std::vector<GhostRegion*> ghosts;
diff --git a/gtk2_ardour/strip_silence_dialog.cc b/gtk2_ardour/strip_silence_dialog.cc
index f5ecdef426..0403d4d188 100644
--- a/gtk2_ardour/strip_silence_dialog.cc
+++ b/gtk2_ardour/strip_silence_dialog.cc
@@ -56,6 +56,7 @@ StripSilenceDialog::StripSilenceDialog (Session* s, std::list<boost::shared_ptr<
, _wave_width (640)
, _wave_height (64)
, restart_queued (false)
+ , _peaks_ready_connection (0)
{
set_session (s);
@@ -148,6 +149,8 @@ StripSilenceDialog::~StripSilenceDialog ()
}
}
+ delete _peaks_ready_connection;
+
delete _canvas;
}
@@ -156,8 +159,11 @@ StripSilenceDialog::create_waves ()
{
int n = 0;
+ delete _peaks_ready_connection;
+ _peaks_ready_connection = 0;
+
for (std::list<Wave>::iterator i = _waves.begin(); i != _waves.end(); ++i) {
- if (i->region->audio_source(0)->peaks_ready (boost::bind (&StripSilenceDialog::peaks_ready, this), _peaks_ready_connection, gui_context())) {
+ if (i->region->audio_source(0)->peaks_ready (boost::bind (&StripSilenceDialog::peaks_ready, this), &_peaks_ready_connection, gui_context())) {
i->view = new WaveView (*(_canvas->root()));
i->view->property_data_src() = static_cast<gpointer>(i->region.get());
i->view->property_cache() = WaveView::create_cache ();
@@ -182,7 +188,8 @@ StripSilenceDialog::create_waves ()
void
StripSilenceDialog::peaks_ready ()
{
- _peaks_ready_connection.disconnect ();
+ delete _peaks_ready_connection;
+ _peaks_ready_connection = 0;
create_waves ();
}
diff --git a/gtk2_ardour/strip_silence_dialog.h b/gtk2_ardour/strip_silence_dialog.h
index c746edc6b5..108bbb4b7b 100644
--- a/gtk2_ardour/strip_silence_dialog.h
+++ b/gtk2_ardour/strip_silence_dialog.h
@@ -85,7 +85,7 @@ private:
ARDOUR::framecnt_t max_silence;
ARDOUR::framecnt_t min_silence;
- PBD::ScopedConnection _peaks_ready_connection;
+ PBD::ScopedConnection* _peaks_ready_connection;
static bool _detection_done (void*);
static void* _detection_thread_work (void*);
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index 9677986449..c4a6e4e475 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -31,6 +31,7 @@
#include "ardour/source.h"
#include "ardour/ardour.h"
+#include "ardour/readable.h"
#include "pbd/stateful.h"
#include "pbd/xml++.h"
@@ -72,7 +73,7 @@ class AudioSource : virtual public Source,
framepos_t start, framecnt_t cnt, double samples_per_visual_peak) const;
int build_peaks ();
- bool peaks_ready (boost::function<void()> callWhenReady, PBD::ScopedConnection& connection_created_if_not_ready, PBD::EventLoop* event_loop) const;
+ bool peaks_ready (boost::function<void()> callWhenReady, PBD::ScopedConnection** connection_created_if_not_ready, PBD::EventLoop* event_loop) const;
mutable PBD::Signal0<void> PeaksReady;
mutable PBD::Signal2<void,framepos_t,framepos_t> PeakRangeReady;
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index 83366bbb78..bf92e5a6e4 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -29,7 +29,6 @@
#include "ardour/ardour.h"
#include "ardour/session_object.h"
#include "ardour/data_type.h"
-#include "ardour/readable.h"
namespace ARDOUR {
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index 60bd5804b3..d8dd58844f 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -148,8 +148,17 @@ AudioSource::update_length (sframes_t pos, sframes_t cnt)
PEAK FILE STUFF
***********************************************************************/
+/** Checks to see if peaks are ready. If so, we return true. If not, we return false, and
+ * things are set up so that doThisWhenReady is called when the peaks are ready.
+ * A new PBD::ScopedConnection is created for the associated connection and written to
+ * *connect_here_if_not.
+ *
+ * @param doThisWhenReady Function to call when peaks are ready (if they are not already).
+ * @param connect_here_if_not Address to write new ScopedConnection to.
+ * @param event_loop Event loop for doThisWhenReady to be called in.
+ */
bool
-AudioSource::peaks_ready (boost::function<void()> doThisWhenReady, ScopedConnection& connect_here_if_not, EventLoop* event_loop) const
+AudioSource::peaks_ready (boost::function<void()> doThisWhenReady, ScopedConnection** connect_here_if_not, EventLoop* event_loop) const
{
bool ret;
Glib::Mutex::Lock lm (_peaks_ready_lock);
@@ -159,7 +168,8 @@ AudioSource::peaks_ready (boost::function<void()> doThisWhenReady, ScopedConnect
*/
if (!(ret = _peaks_built)) {
- PeaksReady.connect (connect_here_if_not, MISSING_INVALIDATOR, doThisWhenReady, event_loop);
+ *connect_here_if_not = new ScopedConnection;
+ PeaksReady.connect (**connect_here_if_not, MISSING_INVALIDATOR, doThisWhenReady, event_loop);
}
return ret;