summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-10-09 15:50:44 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-10-09 15:50:44 +0000
commit0d0f71ee92fb7ce53fbcb8c7b0cd93b1cdf3529f (patch)
treeae37075200040cbbd430b98ee3cbce59eaef51ca
parent8011cbf5f8e4181ac39e4140e681fcad531f4a7c (diff)
fix abort-capture path, including many subtle issues with shared_ptr<>; remove old automation feedback code; make new automation feedback code slightly configurable ; fix zoom focus options for playhead + edit cursor ; prevent zoom < 2 samples per pixel to avoid crashes ; peak building now uses shared_ptr<Source> not Source*
git-svn-id: svn://localhost/ardour2/trunk@959 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/ardour_ui.cc16
-rw-r--r--gtk2_ardour/ardour_ui.h2
-rw-r--r--gtk2_ardour/audio_streamview.cc56
-rw-r--r--gtk2_ardour/audio_streamview.h7
-rw-r--r--gtk2_ardour/editor.cc12
-rw-r--r--gtk2_ardour/streamview.cc27
-rw-r--r--gtk2_ardour/streamview.h2
-rw-r--r--libs/ardour/ardour/audiofilesource.h3
-rw-r--r--libs/ardour/ardour/audioregion.h2
-rw-r--r--libs/ardour/ardour/audiosource.h13
-rw-r--r--libs/ardour/ardour/diskstream.h1
-rw-r--r--libs/ardour/ardour/insert.h1
-rw-r--r--libs/ardour/ardour/io.h16
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/ardour/source_factory.h3
-rw-r--r--libs/ardour/audio_diskstream.cc31
-rw-r--r--libs/ardour/audio_track.cc9
-rw-r--r--libs/ardour/audiofilesource.cc27
-rw-r--r--libs/ardour/audioregion.cc25
-rw-r--r--libs/ardour/audiosource.cc12
-rw-r--r--libs/ardour/coreaudiosource.cc5
-rw-r--r--libs/ardour/destructive_filesource.cc2
-rw-r--r--libs/ardour/diskstream.cc1
-rw-r--r--libs/ardour/insert.cc18
-rw-r--r--libs/ardour/io.cc19
-rw-r--r--libs/ardour/playlist.cc15
-rw-r--r--libs/ardour/route.cc23
-rw-r--r--libs/ardour/session.cc45
-rw-r--r--libs/ardour/session_state.cc1
-rw-r--r--libs/ardour/session_transport.cc33
-rw-r--r--libs/ardour/sndfilesource.cc32
-rw-r--r--libs/ardour/source_factory.cc52
-rw-r--r--libs/pbd/pbd/stacktrace.h2
-rw-r--r--libs/pbd/stacktrace.cc6
-rw-r--r--libs/surfaces/control_protocol/control_protocol/control_protocol.h4
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc43
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.h5
37 files changed, 284 insertions, 289 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 55370e7557..b2da3fdc4c 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -178,7 +178,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
gettimeofday (&last_peak_grab, 0);
gettimeofday (&last_shuttle_request, 0);
- ARDOUR::AudioDiskstream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
@@ -1041,8 +1040,7 @@ ARDOUR_UI::transport_record ()
switch (session->record_status()) {
case Session::Disabled:
if (session->ntracks() == 0) {
- string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
- MessageDialog msg (*editor, txt);
+ MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
msg.run ();
return;
}
@@ -2197,18 +2195,6 @@ ARDOUR_UI::halt_on_xrun_message ()
msg.run ();
}
-void
-ARDOUR_UI::delete_sources_in_the_right_thread (list<boost::shared_ptr<ARDOUR::Source> >* deletion_list)
-{
- ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
-
- for (list<boost::shared_ptr<Source> >::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
- (*i)->drop_references ();
- }
-
- delete deletion_list;
-}
-
void
ARDOUR_UI::disk_overrun_handler ()
{
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index cf6cda526a..69f2cd0492 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -624,8 +624,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
struct timeval last_peak_grab;
struct timeval last_shuttle_request;
- void delete_sources_in_the_right_thread (list<boost::shared_ptr<ARDOUR::Source> >*);
-
void editor_display_control_changed (Editing::DisplayControl c);
bool have_disk_overrun_displayed;
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index 085f429f99..222c920709 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -128,6 +128,8 @@ AudioStreamView::set_amplitude_above_axis (gdouble app)
void
AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves)
{
+ AudioRegionView *region_view;
+
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_region_view), r));
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r);
@@ -136,19 +138,16 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
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);
return;
}
}
-
+
switch (_trackview.audio_track()->mode()) {
case Normal:
region_view = new AudioRegionView (canvas_group, _trackview, region,
@@ -170,15 +169,21 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
/* catch regionview going away */
- region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), region));
-
+ region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), boost::weak_ptr<Region> (r)));
+
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));
+
+ boost::shared_ptr<Region> r (weak_r.lock());
+
+ if (!r) {
+ return;
+ }
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
list<CrossfadeView*>::iterator tmp;
@@ -406,7 +411,7 @@ 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))));
}
}
@@ -420,11 +425,8 @@ AudioStreamView::setup_rec_box ()
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);
-
- // rec regions are destroyed in setup_rec_box
- /* we add the region later */
+ rec_regions.push_back (region);
}
/* start a new rec box */
@@ -503,13 +505,9 @@ AudioStreamView::setup_rec_box ()
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;
+
+ for (list<boost::shared_ptr<Region> >::iterator iter = rec_regions.begin(); iter != rec_regions.end(); ++iter) {
(*iter)->drop_references ();
- iter = tmp;
}
rec_regions.clear();
@@ -537,18 +535,24 @@ AudioStreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void))
}
void
-AudioStreamView::rec_peak_range_ready (nframes_t start, 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());
- ENSURE_GUI_THREAD(bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), start, cnt, src));
+ if (!src) {
+ return;
+ }
+
+ // 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();
diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h
index b61101f788..c6db40f336 100644
--- a/gtk2_ardour/audio_streamview.h
+++ b/gtk2_ardour/audio_streamview.h
@@ -23,6 +23,8 @@
#include <map>
#include <cmath>
+#include <boost/weak_ptr.hpp>
+
#include <ardour/location.h>
#include "enums.h"
#include "simplerect.h"
@@ -76,13 +78,12 @@ class AudioStreamView : public StreamView
private:
void setup_rec_box ();
- void rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::shared_ptr<ARDOUR::Source> src);
+ void rec_peak_range_ready (nframes_t start, nframes_t cnt, boost::weak_ptr<ARDOUR::Source> src);
void update_rec_regions ();
void add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves);
- void remove_region_view (boost::shared_ptr<ARDOUR::Region> );
+ void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
void remove_audio_region_view (boost::shared_ptr<ARDOUR::AudioRegion> );
- void remove_audio_rec_region (boost::shared_ptr<ARDOUR::AudioRegion>);
void undisplay_diskstream ();
void redisplay_diskstream ();
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index f1fe88cd7a..fb0d0782dc 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -132,8 +132,8 @@ static const gchar *zoom_focus_strings[] = {
N_("Focus Left"),
N_("Focus Right"),
N_("Focus Center"),
- N_("Focus Play"),
- N_("Focus Edit"),
+ N_("Focus Playhead"),
+ N_("Focus Edit Cursor"),
0
};
@@ -801,8 +801,8 @@ Editor::set_frames_per_unit (double fpu)
return;
}
- if (fpu < 1.0) {
- fpu = 1.0;
+ if (fpu < 2.0) {
+ fpu = 2.0;
}
// convert fpu to frame count
@@ -817,6 +817,10 @@ Editor::set_frames_per_unit (double fpu)
return;
}
+ if (fpu == frames_per_unit) {
+ return;
+ }
+
frames_per_unit = fpu;
if (frames != zoom_range_clock.current_duration()) {
diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc
index 097e581cdf..0a35709538 100644
--- a/gtk2_ardour/streamview.cc
+++ b/gtk2_ardour/streamview.cc
@@ -164,9 +164,11 @@ StreamView::add_region_view (boost::shared_ptr<Region> r)
}
void
-StreamView::remove_region_view (boost::shared_ptr<Region> r)
+StreamView::remove_region_view (boost::weak_ptr<Region> weak_r)
{
- ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_region_view), r));
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_region_view), weak_r));
+
+ boost::shared_ptr<Region> r (weak_r.lock());
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
if (((*i)->region()) == r) {
@@ -177,27 +179,6 @@ StreamView::remove_region_view (boost::shared_ptr<Region> r)
}
}
-#if 0
-(unused)
-void
-StreamView::remove_rec_region (boost::shared_ptr<Region> r)
-{
- ENSURE_GUI_THREAD(bind (mem_fun (*this, &StreamView::remove_rec_region), r));
-
- if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {
- fatal << "region deleted from non-GUI thread!" << endmsg;
- /*NOTREACHED*/
- }
-
- for (list<boost::shared_ptr<Region> >::iterator i = rec_regions.begin(); i != rec_regions.end(); ++i) {
- if (*i == r) {
- rec_regions.erase (i);
- break;
- }
- }
-}
-#endif
-
void
StreamView::undisplay_diskstream ()
{
diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h
index b1fd3c1b29..cc5f9cb414 100644
--- a/gtk2_ardour/streamview.h
+++ b/gtk2_ardour/streamview.h
@@ -108,7 +108,7 @@ protected:
virtual void update_rec_regions () = 0;
virtual void add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves) = 0;
- virtual void remove_region_view (boost::shared_ptr<ARDOUR::Region> );
+ virtual void remove_region_view (boost::weak_ptr<ARDOUR::Region> );
//void remove_rec_region (boost::shared_ptr<ARDOUR::Region>); (unused)
void display_diskstream (boost::shared_ptr<ARDOUR::Diskstream>);
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h
index fb32d892d2..de12cb05e5 100644
--- a/libs/ardour/ardour/audiofilesource.h
+++ b/libs/ardour/ardour/audiofilesource.h
@@ -88,6 +88,8 @@ class AudioFileSource : public AudioSource {
static void set_search_path (string);
static void set_header_position_offset (nframes_t offset );
+ int setup_peakfile ();
+
static sigc::signal<void> HeaderPositionOffsetChanged;
XMLNode& get_state ();
@@ -122,6 +124,7 @@ class AudioFileSource : public AudioSource {
Flag _flags;
string _take_id;
uint64_t timeline_position;
+ bool file_is_new;
static string peak_dir;
static string search_path;
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index d1d7c6e5fb..c9cb2b8152 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -189,7 +189,7 @@ class AudioRegion : public Region
void envelope_changed (Change);
void source_offset_changed ();
- void source_deleted (boost::shared_ptr<Source>);
+ void source_deleted ();
SourceList sources;
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index d2d23bcfab..7bdc0f5d7d 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -25,6 +25,9 @@
#include <vector>
#include <string>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
#include <time.h>
#include <glibmm/thread.h>
@@ -44,7 +47,7 @@ namespace ARDOUR {
const nframes_t frames_per_peak = 256;
-class AudioSource : public Source
+ class AudioSource : public Source, public boost::enable_shared_from_this<ARDOUR::AudioSource>
{
public:
AudioSource (Session&, string name);
@@ -104,13 +107,15 @@ class AudioSource : public Source
_build_peakfiles = yn;
}
+ virtual int setup_peakfile () { return 0; }
+
protected:
static bool _build_missing_peakfiles;
static bool _build_peakfiles;
bool _peaks_built;
mutable Glib::Mutex _lock;
- nframes_t _length;
+ nframes_t _length;
bool next_peak_clear_should_notify;
string peakpath;
string _captured_for;
@@ -143,10 +148,10 @@ class AudioSource : public Source
};
};
- static vector<AudioSource*> pending_peak_sources;
+ static vector<boost::shared_ptr<AudioSource> > pending_peak_sources;
static Glib::Mutex* pending_peak_sources_lock;
- static void queue_for_peaks (AudioSource*);
+ static void queue_for_peaks (boost::shared_ptr<AudioSource>);
static void clear_queue_for_peaks ();
struct PeakBuildRecord {
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index d3b5d6dce4..cffe02e859 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -147,7 +147,6 @@ class IO;
static sigc::signal<void> DiskOverrun;
static sigc::signal<void> DiskUnderrun;
- static sigc::signal<void,std::list<boost::shared_ptr<Source> >*> DeleteSources;
protected:
friend class Session;
diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h
index ee07b7ebd3..30378139ab 100644
--- a/libs/ardour/ardour/insert.h
+++ b/libs/ardour/ardour/insert.h
@@ -157,7 +157,6 @@ class PluginInsert : public Insert
nframes_t latency();
void transport_stopped (nframes_t now);
- void automation_snapshot (nframes_t now);
protected:
void store_state (PluginInsertState&) const;
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index c32ef31de8..e59ec6c23d 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -234,16 +234,7 @@ public:
AutoStyle gain_automation_style () const { return _gain_automation_curve.automation_style(); }
sigc::signal<void> gain_automation_style_changed;
- static void set_automation_interval (nframes_t frames) {
- _automation_interval = frames;
- }
-
- static nframes_t automation_interval() {
- return _automation_interval;
- }
-
virtual void transport_stopped (nframes_t now);
- virtual void automation_snapshot (nframes_t now);
ARDOUR::Curve& gain_automation_curve () { return _gain_automation_curve; }
@@ -310,12 +301,7 @@ public:
Change restore_state (State&);
StateManager::State* state_factory (std::string why) const;
- /* automation */
-
- nframes_t last_automation_snapshot;
- static nframes_t _automation_interval;
-
- AutoState _gain_automation_state;
+ AutoState _gain_automation_state;
AutoStyle _gain_automation_style;
bool apply_gain_automation;
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index b3ac609880..af104bb6ea 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -238,8 +238,6 @@ class Route : public IO
return _mute_control;
}
- void automation_snapshot (nframes_t now);
-
void protect_automation ();
void set_remote_control_id (uint32_t id);
diff --git a/libs/ardour/ardour/source_factory.h b/libs/ardour/ardour/source_factory.h
index 815b825b8d..6cb262a299 100644
--- a/libs/ardour/ardour/source_factory.h
+++ b/libs/ardour/ardour/source_factory.h
@@ -24,6 +24,9 @@ class SourceFactory {
// MIDI sources will have to be hacked in here somehow
static boost::shared_ptr<Source> createReadable (Session&, std::string idstr, AudioFileSource::Flag flags, bool announce = true);
static boost::shared_ptr<Source> createWritable (Session&, std::string name, bool destructive, nframes_t rate, bool announce = true);
+
+ private:
+ static int setup_peakfile (boost::shared_ptr<Source>);
};
}
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 1374589608..9bd690c23a 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -1484,29 +1484,21 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
if (abort_capture) {
- ChannelList::iterator chan;
-
- list<boost::shared_ptr<Source> >* deletion_list = new list<boost::shared_ptr<Source> >;
+ if (destructive()) {
+ goto outout;
+ }
- for ( chan = channels.begin(); chan != channels.end(); ++chan) {
+ for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
if ((*chan).write_source) {
(*chan).write_source->mark_for_remove ();
-
- deletion_list->push_back ((*chan).write_source);
-
+ (*chan).write_source->drop_references ();
(*chan).write_source.reset ();
}
/* new source set up in "out" below */
}
-
- if (!deletion_list->empty()) {
- DeleteSources (deletion_list);
- } else {
- delete deletion_list;
- }
goto out;
}
@@ -1606,9 +1598,11 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
mark_write_completed = true;
+ out:
reset_write_sources (mark_write_completed);
- out:
+ outout:
+
for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
delete *ci;
}
@@ -1933,13 +1927,8 @@ AudioDiskstream::use_new_write_source (uint32_t n)
ChannelInfo &chan = channels[n];
if (chan.write_source) {
-
- if (AudioFileSource::is_empty (_session, chan.write_source->path())) {
- chan.write_source->mark_for_remove ();
- chan.write_source.reset ();
- } else {
- chan.write_source.reset ();
- }
+ chan.write_source->set_allow_remove_if_empty (true);
+ chan.write_source.reset ();
}
try {
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 171f2d7c6b..677c9a0497 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -507,15 +507,6 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
nframes_t transport_frame;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
- {
- Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
- if (lm.locked()) {
- // automation snapshot can also be called from the non-rt context
- // and it uses the redirect list, so we take the lock out here
- automation_snapshot (start_frame);
- }
- }
-
if (n_outputs() == 0 && _redirects.empty()) {
return 0;
}
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index 9564fff53b..0eb416e905 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -59,8 +59,11 @@ string AudioFileSource::search_path;
sigc::signal<void> AudioFileSource::HeaderPositionOffsetChanged;
uint64_t AudioFileSource::header_position_offset = 0;
+/* XXX turn this into a Config option */
char AudioFileSource::bwf_country_code[3] = "US";
+/* XXX turn this into a Config option */
char AudioFileSource::bwf_organization_code[4] = "LAS";
+/* XXX maybe this too */
char AudioFileSource::bwf_serial_number[13] = "000000000000";
AudioFileSource::AudioFileSource (Session& s, string idstr, Flag flags)
@@ -120,7 +123,9 @@ AudioFileSource::init (string pathstr, bool must_exist)
_length = 0;
timeline_position = 0;
next_peak_clear_should_notify = false;
-
+ _peaks_built = false;
+ file_is_new = false;
+
if (!find (pathstr, must_exist, is_new)) {
return -1;
}
@@ -285,7 +290,8 @@ AudioFileSource::mark_for_remove ()
if (!writable()) {
return;
}
- _flags = Flag (_flags | RemoveAtDestroy);
+
+ _flags = Flag (_flags | Removable | RemoveAtDestroy);
}
void
@@ -518,8 +524,14 @@ AudioFileSource::set_timeline_position (nframes_t pos)
void
AudioFileSource::set_allow_remove_if_empty (bool yn)
{
- if (writable()) {
+ if (!writable()) {
+ return;
+ }
+
+ if (yn) {
_flags = Flag (_flags | RemovableIfEmpty);
+ } else {
+ _flags = Flag (_flags & ~RemovableIfEmpty);
}
}
@@ -565,3 +577,12 @@ AudioFileSource::is_empty (Session& s, string path)
return ret;
}
+int
+AudioFileSource::setup_peakfile ()
+{
+ if (!(_flags & NoPeakFile)) {
+ return initialize_peakfile (file_is_new, _path);
+ } else {
+ return 0;
+ }
+}
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 07da0039ce..787b408ace 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -75,7 +75,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n
sources.push_back (src);
master_sources.push_back (src);
- src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src));
+ src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
if (afs) {
@@ -102,7 +102,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, n
sources.push_back (src);
master_sources.push_back (src);
- src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src));
+ src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
if (afs) {
@@ -129,7 +129,7 @@ AudioRegion::AudioRegion (SourceList& srcs, nframes_t start, nframes_t length, c
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
sources.push_back (*i);
master_sources.push_back (*i);
- (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), (*i)));
+ (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i));
if (afs) {
@@ -159,7 +159,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t
for (SourceList::const_iterator i= other->sources.begin(); i != other->sources.end(); ++i) {
sources.push_back (*i);
- (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
+ (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
@@ -175,7 +175,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t
for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) {
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
+ (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
}
master_sources.push_back (*i);
}
@@ -224,7 +224,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
for (SourceList::const_iterator i = other->sources.begin(); i != other->sources.end(); ++i) {
sources.push_back (*i);
- (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
+ (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
result = unique_srcs.insert (*i);
@@ -240,7 +240,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
for (SourceList::const_iterator i = other->master_sources.begin(); i != other->master_sources.end(); ++i) {
master_sources.push_back (*i);
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
+ (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
}
}
@@ -263,7 +263,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& nod
{
sources.push_back (src);
master_sources.push_back (src);
- src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src));
+ src->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
if (afs) {
@@ -291,7 +291,7 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
sources.push_back (*i);
- (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
+ (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
pair<set<boost::shared_ptr<AudioSource> >::iterator,bool> result;
result = unique_srcs.insert (*i);
@@ -307,7 +307,7 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
for (SourceList::iterator i = srcs.begin(); i != srcs.end(); ++i) {
master_sources.push_back (*i);
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), *i));
+ (*i)->GoingAway.connect (mem_fun (*this, &AudioRegion::source_deleted));
}
}
@@ -1117,9 +1117,10 @@ AudioRegion::separate_by_channel (Session& session, vector<AudioRegion*>& v) con
}
void
-AudioRegion::source_deleted (boost::shared_ptr<Source> ignored)
+AudioRegion::source_deleted ()
{
- delete this;
+ sources.clear ();
+ drop_references ();
}
vector<string>
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index 9aee818588..cd8c192d13 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -44,7 +44,7 @@ using namespace PBD;
pthread_t AudioSource::peak_thread;
bool AudioSource::have_peak_thread = false;
-vector<AudioSource*> AudioSource::pending_peak_sources;
+vector<boost::shared_ptr<AudioSource> > AudioSource::pending_peak_sources;
Glib::Mutex* AudioSource::pending_peak_sources_lock = 0;
int AudioSource::peak_request_pipe[2];
@@ -191,7 +191,7 @@ AudioSource::peak_thread_work (void* arg)
while (!pending_peak_sources.empty()) {
- AudioSource* s = pending_peak_sources.front();
+ boost::shared_ptr<AudioSource> s = pending_peak_sources.front();
pending_peak_sources.erase (pending_peak_sources.begin());
pending_peak_sources_lock->unlock ();
@@ -251,7 +251,7 @@ AudioSource::stop_peak_thread ()
}
void
-AudioSource::queue_for_peaks (AudioSource* source)
+AudioSource::queue_for_peaks (boost::shared_ptr<AudioSource> source)
{
if (have_peak_thread) {
@@ -387,11 +387,11 @@ AudioSource::initialize_peakfile (bool newfile, string audio_path)
}
}
}
-
+
if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
build_peaks_from_scratch ();
}
-
+
return 0;
}
@@ -847,7 +847,7 @@ AudioSource::build_peaks_from_scratch ()
next_peak_clear_should_notify = true;
pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
- queue_for_peaks (this);
+ queue_for_peaks (shared_from_this());
}
bool
diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc
index 448e9c0b32..c8cbb7a40d 100644
--- a/libs/ardour/coreaudiosource.cc
+++ b/libs/ardour/coreaudiosource.cc
@@ -86,10 +86,7 @@ CoreAudioSource::init (const string& idstr)
}
if (_build_peakfiles) {
- if (initialize_peakfile (false, _path)) {
- error << string_compose("CoreAudioSource: initialize peakfile failed (%1)", name()) << endmsg;
- throw failed_constructor ();
- }
+ _need_peakfile = true;
}
}
diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc
index 3cd6586799..e160ffd608 100644
--- a/libs/ardour/destructive_filesource.cc
+++ b/libs/ardour/destructive_filesource.cc
@@ -376,7 +376,7 @@ DestructiveFileSource::write_unlocked (Sample* data, nframes_t cnt)
}
if (_build_peakfiles) {
- queue_for_peaks (this);
+ queue_for_peaks (shared_from_this ());
}
return cnt;
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index 4f6515d076..f9fb540099 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -65,7 +65,6 @@ using namespace PBD;
*/
nframes_t Diskstream::disk_io_chunk_frames = 1024 * 256;
-sigc::signal<void,list<boost::shared_ptr<Source> >*> Diskstream::DeleteSources;
sigc::signal<void> Diskstream::DiskOverrun;
sigc::signal<void> Diskstream::DiskUnderrun;
diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc
index d955588c44..d64cce36f9 100644
--- a/libs/ardour/insert.cc
+++ b/libs/ardour/insert.cc
@@ -317,23 +317,6 @@ PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, nframes_t
}
void
-PluginInsert::automation_snapshot (nframes_t now)
-{
- map<uint32_t,AutomationList*>::iterator li;
-
- for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
-
- AutomationList *alist = ((*li).second);
- if (alist != 0 && alist->automation_write ()) {
-
- float val = _plugins[0]->get_parameter ((*li).first);
- alist->rt_add (now, val);
- last_automation_snapshot = now;
- }
- }
-}
-
-void
PluginInsert::transport_stopped (nframes_t now)
{
map<uint32_t,AutomationList*>::iterator li;
@@ -468,7 +451,6 @@ PluginInsert::set_port_automation_state (uint32_t port, AutoState s)
if (s != al.automation_state()) {
al.set_automation_state (s);
- last_automation_snapshot = 0;
_session.set_dirty ();
}
}
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 34070f3dff..b6c3648cda 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -61,7 +61,6 @@ using namespace PBD;
static float current_automation_version_number = 1.0;
-nframes_t IO::_automation_interval = 0;
const string IO::state_node_name = "IO";
bool IO::connecting_legal = false;
bool IO::ports_legal = false;
@@ -127,8 +126,6 @@ IO::IO (Session& s, string name,
apply_gain_automation = false;
- last_automation_snapshot = 0;
-
_gain_automation_state = Off;
_gain_automation_style = Absolute;
@@ -2513,7 +2510,6 @@ IO::set_gain_automation_state (AutoState state)
if (state != _gain_automation_curve.automation_state()) {
changed = true;
- last_automation_snapshot = 0;
_gain_automation_curve.set_automation_state (state);
if (state != Off) {
@@ -2612,21 +2608,6 @@ IO::end_pan_touch (uint32_t which)
}
void
-IO::automation_snapshot (nframes_t now)
-{
- if (last_automation_snapshot > now || (now - last_automation_snapshot) > _automation_interval) {
-
- if (gain_automation_recording()) {
- _gain_automation_curve.rt_add (now, gain());
- }
-
- _panner->snapshot (now);
-
- last_automation_snapshot = now;
- }
-}
-
-void
IO::transport_stopped (nframes_t frame)
{
_gain_automation_curve.reposition_for_rt_add (frame);
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 6d6a07da95..38c7e387f8 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -1373,10 +1373,21 @@ Playlist::set_state (const XMLNode& node)
if (child->name() == "Region") {
- if ((region = RegionFactory::create (_session, *child, true)) == 0) {
- error << _("Playlist: cannot create region from state file") << endmsg;
+#if 0
+ if ((prop = child->property ("id")) == 0) {
+ error << _("region state node has no ID, ignored") << endmsg;
continue;
}
+
+ ID id = prop->value ();
+
+ if ((region = region_by_id (id)) == 0) {
+#endif
+ if ((region = RegionFactory::create (_session, *child, true)) == 0) {
+ error << _("Playlist: cannot create region from state file") << endmsg;
+ continue;
+ }
+// }
add_region (region, region->position(), 1.0, false);
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 15b148ffb3..318989bb60 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -1959,10 +1959,6 @@ Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_f
{
Glib::RWLock::ReaderLock lm (redirect_lock);
- if (!did_locate) {
- automation_snapshot (now);
- }
-
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
if (Config->get_plugins_stop_with_transport() && can_flush_redirects) {
@@ -2075,15 +2071,6 @@ int
Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
bool can_record, bool rec_monitors_input)
{
- {
- Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
- if (lm.locked()) {
- // automation snapshot can also be called from the non-rt context
- // and it uses the redirect list, so we take the lock out here
- automation_snapshot (_session.transport_frame());
- }
- }
-
if ((n_outputs() == 0 && _redirects.empty()) || n_inputs() == 0 || !_active) {
silence (nframes, offset);
return 0;
@@ -2220,16 +2207,6 @@ Route::set_latency_delay (nframes_t longest_session_latency)
}
}
-void
-Route::automation_snapshot (nframes_t now)
-{
- IO::automation_snapshot (now);
-
- for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
- (*i)->automation_snapshot (now);
- }
-}
-
Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp)
: Controllable (name), route (s), type(tp)
{
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 3bcaaf3aca..8474eab523 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1220,8 +1220,8 @@ Session::maybe_enable_record ()
{
g_atomic_int_set (&_record_status, Enabled);
- /* XXX this save should really happen in another thread. its needed so that
- pending capture state can be recovered if we crash.
+ /* this function is currently called from somewhere other than an RT thread.
+ this save_state() call therefore doesn't impact anything.
*/
save_state ("", true);
@@ -1310,8 +1310,6 @@ Session::set_frame_rate (nframes_t frames_per_second)
sync_time_vars();
- Route::set_automation_interval ((nframes_t) ceil ((double) frames_per_second * 0.25));
-
// XXX we need some equivalent to this, somehow
// DestructiveFileSource::setup_standard_crossfades (frames_per_second);
@@ -2472,7 +2470,7 @@ Session::remove_region (boost::shared_ptr<Region> region)
AudioRegionList::iterator i;
boost::shared_ptr<AudioRegion> ar;
bool removed = false;
-
+
{
Glib::Mutex::Lock lm (region_lock);
@@ -2480,6 +2478,7 @@ Session::remove_region (boost::shared_ptr<Region> region)
if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
audio_regions.erase (i);
removed = true;
+ cerr << "done\n";
}
} else {
@@ -2642,29 +2641,27 @@ Session::remove_source (boost::weak_ptr<Source> src)
boost::shared_ptr<Source> source = src.lock();
if (!source) {
- cerr << "removing a source DEAD\n";
- } else {
- cerr << "removing a source " << source->name () << endl;
+ return;
+ }
+
+ {
+ Glib::Mutex::Lock lm (audio_source_lock);
- {
- Glib::Mutex::Lock lm (audio_source_lock);
-
- if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
- audio_sources.erase (i);
- }
- }
+ if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
+ audio_sources.erase (i);
+ }
+ }
+
+ if (!_state_of_the_state & InCleanup) {
- if (!_state_of_the_state & InCleanup) {
-
- /* save state so we don't end up with a session file
- referring to non-existent sources.
- */
-
- save_state (_current_snapshot_name);
- }
+ /* save state so we don't end up with a session file
+ referring to non-existent sources.
+ */
- SourceRemoved(source); /* EMIT SIGNAL */
+ save_state (_current_snapshot_name);
}
+
+ SourceRemoved(source); /* EMIT SIGNAL */
}
boost::shared_ptr<Source>
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 159f8a8473..c302633918 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -161,7 +161,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
mmc = 0;
session_send_mmc = false;
session_send_mtc = false;
- session_midi_feedback = false;
post_transport_work = PostTransportWork (0);
g_atomic_int_set (&butler_should_do_transport_work, 0);
g_atomic_int_set (&butler_active, 0);
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 1f2dc3215e..678a03ad4e 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -261,11 +261,13 @@ Session::non_realtime_stop (bool abort)
struct tm* now;
time_t xnow;
bool did_record;
-
+ bool saved;
+
did_record = false;
-
- boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+ saved = false;
+ boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
+
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)->get_captured_frames () != 0) {
did_record = true;
@@ -291,7 +293,7 @@ Session::non_realtime_stop (bool abort)
Location* loc = _locations.end_location();
bool change_end = false;
-
+
if (_transport_frame < loc->end()) {
/* stopped recording before current end */
@@ -332,17 +334,17 @@ Session::non_realtime_stop (bool abort)
(*i)->set_pending_declick (0);
}
}
-
+
if (did_record) {
commit_reversible_command ();
}
-
+
if (_engine.running()) {
update_latency_compensation (true, abort);
}
if (Config->get_auto_return() || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
-
+
if (pending_locate_flush) {
flush_all_redirects ();
}
@@ -370,7 +372,7 @@ Session::non_realtime_stop (bool abort)
}
}
}
-
+
deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
#ifdef LEAVE_TRANSPORT_UNADJUSTED
@@ -389,7 +391,7 @@ Session::non_realtime_stop (bool abort)
when realtime_stop(), which has already executed,
will have done this.
*/
-
+
if (!Config->get_latched_record_enable()) {
g_atomic_int_set (&_record_status, Disabled);
} else {
@@ -401,6 +403,7 @@ Session::non_realtime_stop (bool abort)
if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
/* capture start has been changed, so save pending state */
save_state ("", true);
+ saved = true;
}
/* always try to get rid of this */
@@ -409,7 +412,7 @@ Session::non_realtime_stop (bool abort)
/* save the current state of things if appropriate */
- if (did_record) {
+ if (did_record && !saved) {
save_state (_current_snapshot_name);
}
@@ -421,7 +424,7 @@ Session::non_realtime_stop (bool abort)
_play_range = false;
/* do not turn off autoloop on stop */
-
+
}
PositionChanged (_transport_frame); /* EMIT SIGNAL */
@@ -708,7 +711,7 @@ Session::set_transport_speed (float speed, bool abort)
} else {
stop_transport (abort);
}
-
+
} else if (transport_stopped() && speed == 1.0) {
if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
@@ -789,7 +792,7 @@ Session::stop_transport (bool abort)
if (_transport_speed == 0.0f) {
return;
}
-
+
if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
_worst_output_latency > current_block_size)
{
@@ -812,9 +815,11 @@ Session::stop_transport (bool abort)
return;
}
+
if ((transport_sub_state & PendingDeclickOut) == 0) {
transport_sub_state |= PendingDeclickOut;
/* we'll be called again after the declick */
+ pending_abort = abort;
return;
}
@@ -951,7 +956,7 @@ Session::set_slave_source (SlaveSource src)
case None:
stop_transport ();
break;
-
+
case MTC:
if (_mtc_port) {
try {
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index 340dd1fb08..c30b1af2a4 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -43,14 +43,6 @@ SndFileSource::SndFileSource (Session& s, const XMLNode& node)
if (open()) {
throw failed_constructor ();
}
-
- if (_build_peakfiles) {
- if (initialize_peakfile (false, _path)) {
- sf_close (sf);
- sf = 0;
- throw failed_constructor ();
- }
- }
}
SndFileSource::SndFileSource (Session& s, string idstr, Flag flags)
@@ -62,14 +54,6 @@ SndFileSource::SndFileSource (Session& s, string idstr, Flag flags)
if (open()) {
throw failed_constructor ();
}
-
- if (!(_flags & NoPeakFile) && _build_peakfiles) {
- if (initialize_peakfile (false, _path)) {
- sf_close (sf);
- sf = 0;
- throw failed_constructor ();
- }
- }
}
SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags)
@@ -79,6 +63,12 @@ SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, Heade
init (idstr);
+ /* this constructor is used to construct new files, not open
+ existing ones.
+ */
+
+ file_is_new = true;
+
switch (hf) {
case CAF:
fmt = SF_FORMAT_CAF;
@@ -171,14 +161,6 @@ SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, Heade
}
}
-
- if (!(_flags & NoPeakFile) && _build_peakfiles) {
- if (initialize_peakfile (true, _path)) {
- sf_close (sf);
- sf = 0;
- throw failed_constructor ();
- }
- }
}
void
@@ -413,7 +395,7 @@ SndFileSource::write_unlocked (Sample *data, nframes_t cnt)
if (_build_peakfiles) {
- queue_for_peaks (this);
+ queue_for_peaks (shared_from_this ());
}
_write_data_count = cnt;
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
index 81a96491ce..7e639590c5 100644
--- a/libs/ardour/source_factory.cc
+++ b/libs/ardour/source_factory.cc
@@ -18,6 +18,8 @@
$Id$
*/
+#include <pbd/error.h>
+
#include <ardour/source_factory.h>
#include <ardour/sndfilesource.h>
#include <ardour/destructive_filesource.h>
@@ -31,16 +33,34 @@
using namespace ARDOUR;
using namespace std;
+using namespace PBD;
sigc::signal<void,boost::shared_ptr<Source> > SourceFactory::SourceCreated;
+int
+SourceFactory::setup_peakfile (boost::shared_ptr<Source> s)
+{
+ boost::shared_ptr<AudioSource> as (boost::dynamic_pointer_cast<AudioSource> (s));
+ if (as) {
+ if (as->setup_peakfile ()) {
+ error << string_compose("SourceFactory: could not set up peakfile for %1", as->name()) << endmsg;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
#ifdef HAVE_COREAUDIO
boost::shared_ptr<Source>
SourceFactory::create (Session& s, const XMLNode& node)
{
if (node.property (X_("destructive")) != 0) {
-
+
boost::shared_ptr<Source> ret (new DestructiveFileSource (s, node));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
SourceCreated (ret);
return ret;
@@ -48,6 +68,9 @@ SourceFactory::create (Session& s, const XMLNode& node)
try {
boost::shared_ptr<Source> ret (new CoreAudioSource (s, node));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
SourceCreated (ret);
return ret;
}
@@ -55,6 +78,9 @@ SourceFactory::create (Session& s, const XMLNode& node)
catch (failed_constructor& err) {
boost::shared_ptr<Source> ret (new SndFileSource (s, node));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
SourceCreated (ret);
return ret;
}
@@ -71,12 +97,18 @@ SourceFactory::create (Session& s, const XMLNode& node)
if (node.property (X_("destructive")) != 0) {
boost::shared_ptr<Source> ret (new DestructiveFileSource (s, node));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
SourceCreated (ret);
return ret;
} else {
boost::shared_ptr<Source> ret (new SndFileSource (s, node));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
SourceCreated (ret);
return ret;
}
@@ -90,6 +122,9 @@ SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag f
{
if (flags & Destructive) {
boost::shared_ptr<Source> ret (new DestructiveFileSource (s, idstr, flags));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
if (announce) {
SourceCreated (ret);
}
@@ -98,6 +133,9 @@ SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag f
try {
boost::shared_ptr<Source> ret (new CoreAudioSource (s, idstr, flags));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
if (announce) {
SourceCreated (ret);
}
@@ -106,6 +144,9 @@ SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag f
catch (failed_constructor& err) {
boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
if (announce) {
SourceCreated (ret);
}
@@ -121,6 +162,9 @@ boost::shared_ptr<Source>
SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
{
boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
if (announce) {
SourceCreated (ret);
}
@@ -139,6 +183,9 @@ SourceFactory::createWritable (Session& s, std::string path, bool destructive, n
Config->get_native_file_data_format(),
Config->get_native_file_header_format(),
rate));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
if (announce) {
SourceCreated (ret);
}
@@ -149,6 +196,9 @@ SourceFactory::createWritable (Session& s, std::string path, bool destructive, n
Config->get_native_file_data_format(),
Config->get_native_file_header_format(),
rate));
+ if (setup_peakfile (ret)) {
+ return boost::shared_ptr<Source>();
+ }
if (announce) {
SourceCreated (ret);
}
diff --git a/libs/pbd/pbd/stacktrace.h b/libs/pbd/pbd/stacktrace.h
index d7278bd35a..fa90a07355 100644
--- a/libs/pbd/pbd/stacktrace.h
+++ b/libs/pbd/pbd/stacktrace.h
@@ -4,7 +4,7 @@
#include <ostream>
namespace PBD {
- void stacktrace (std::ostream& out);
+ void stacktrace (std::ostream& out, int levels = 0);
}
#endif /* __libpbd_stacktrace_h__ */
diff --git a/libs/pbd/stacktrace.cc b/libs/pbd/stacktrace.cc
index 1e7dfa08e9..a653fe3033 100644
--- a/libs/pbd/stacktrace.cc
+++ b/libs/pbd/stacktrace.cc
@@ -9,7 +9,7 @@
#include <stdlib.h>
void
-PBD::stacktrace (std::ostream& out)
+PBD::stacktrace (std::ostream& out, int levels)
{
void *array[200];
size_t size;
@@ -23,7 +23,7 @@ PBD::stacktrace (std::ostream& out)
printf ("Obtained %zd stack frames.\n", size);
- for (i = 0; i < size; i++) {
+ for (i = 0; i < size && (levels == 0 || i < levels); i++) {
out << strings[i] << std::endl;
}
@@ -34,7 +34,7 @@ PBD::stacktrace (std::ostream& out)
#else
void
-PBD::stacktrace (std::ostream& out)
+PBD::stacktrace (std::ostream& out, int levels)
{
out << "stack tracing is not enabled on this platform" << std::endl;
}
diff --git a/libs/surfaces/control_protocol/control_protocol/control_protocol.h b/libs/surfaces/control_protocol/control_protocol/control_protocol.h
index 8be652b9df..3635b267ce 100644
--- a/libs/surfaces/control_protocol/control_protocol/control_protocol.h
+++ b/libs/surfaces/control_protocol/control_protocol/control_protocol.h
@@ -45,6 +45,10 @@ class ControlProtocol : public sigc::trackable, public Stateful, public BasicUI
virtual int set_active (bool yn) = 0;
bool get_active() const { return _active; }
+ virtual int set_feedback (bool yn) { return 0; }
+ virtual bool get_feedback () const { return false; }
+ virtual bool supports_feedback () const { return false; }
+
sigc::signal<void> ActiveChanged;
/* signals that a control protocol can emit and other (presumably graphical)
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
index a8a5b6eace..8e8f707bab 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
@@ -54,6 +54,7 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
throw failed_constructor();
}
+ do_feedback = false;
_feedback_interval = 10000; // microseconds
last_feedback_time = 0;
@@ -82,6 +83,10 @@ GenericMidiControlProtocol::set_feedback_interval (microseconds_t ms)
void
GenericMidiControlProtocol::send_feedback ()
{
+ if (!do_feedback) {
+ return;
+ }
+
microseconds_t now = get_microseconds ();
if (last_feedback_time != 0) {
@@ -98,7 +103,7 @@ GenericMidiControlProtocol::send_feedback ()
void
GenericMidiControlProtocol::_send_feedback ()
{
- const int32_t bufsize = 16 * 1024;
+ const int32_t bufsize = 16 * 1024; /* XXX too big */
MIDI::byte buf[bufsize];
int32_t bsize = bufsize;
MIDI::byte* end = buf;
@@ -174,8 +179,12 @@ XMLNode&
GenericMidiControlProtocol::get_state ()
{
XMLNode* node = new XMLNode ("Protocol");
+ char buf[32];
node->add_property (X_("name"), _name);
+ node->add_property (X_("feedback"), do_feedback ? "1" : "0");
+ snprintf (buf, sizeof (buf), "%" PRIu64, _feedback_interval);
+ node->add_property (X_("feedback_interval"), buf);
XMLNode* children = new XMLNode (X_("controls"));
@@ -194,6 +203,22 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
+ const XMLProperty* prop;
+
+ if ((prop = node.property ("feedback")) != 0) {
+ do_feedback = (bool) atoi (prop->value().c_str());
+ } else {
+ do_feedback = false;
+ }
+
+ if ((prop = node.property ("feedback_interval")) != 0) {
+ if (sscanf (prop->value().c_str(), "%" PRIu64, &_feedback_interval) != 1) {
+ _feedback_interval = 10000;
+ }
+ } else {
+ _feedback_interval = 10000;
+ }
+
Controllable* c;
{
@@ -215,8 +240,6 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- XMLProperty* prop;
-
if ((prop = (*niter)->property ("id")) != 0) {
ID id = prop->value ();
@@ -239,3 +262,17 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
return 0;
}
+
+int
+GenericMidiControlProtocol::set_feedback (bool yn)
+{
+ do_feedback = yn;
+ last_feedback_time = 0;
+ return 0;
+}
+
+bool
+GenericMidiControlProtocol::get_feedback () const
+{
+ return do_feedback;
+}
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
index 5f5a470b13..d008744727 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
@@ -32,6 +32,10 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
MIDI::Port* port () const { return _port; }
void set_feedback_interval (ARDOUR::microseconds_t);
+ int set_feedback (bool yn);
+ bool get_feedback () const;
+ bool supports_feedback () const { return true; }
+
XMLNode& get_state ();
int set_state (const XMLNode&);
@@ -40,6 +44,7 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
ARDOUR::microseconds_t _feedback_interval;
ARDOUR::microseconds_t last_feedback_time;
+ bool do_feedback;
void _send_feedback ();
void send_feedback ();