summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-08-29 00:23:45 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-08-29 00:23:45 +0000
commit6535cd1b1dbab7cc59a356c81d92dbc2cf25333b (patch)
tree90002ec1819c61db4b0981405d27535af3a79f70
parentc871ca6d9833ebda3bf286462b96146550b49cef (diff)
used shared_ptr<Source>, somewhat successfully
git-svn-id: svn://localhost/ardour2/trunk@861 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/ardour_ui.cc6
-rw-r--r--gtk2_ardour/ardour_ui.h2
-rw-r--r--gtk2_ardour/audio_region_view.cc2
-rw-r--r--gtk2_ardour/audio_streamview.cc8
-rw-r--r--gtk2_ardour/audio_streamview.h4
-rw-r--r--gtk2_ardour/crossfade_edit.cc2
-rw-r--r--gtk2_ardour/editor_audio_import.cc5
-rw-r--r--gtk2_ardour/editor_export_audio.cc27
-rw-r--r--gtk2_ardour/editor_region_list.cc16
-rw-r--r--gtk2_ardour/sfdb_ui.cc7
-rw-r--r--gtk2_ardour/tape_region_view.cc2
-rw-r--r--libs/ardour/SConscript1
-rw-r--r--libs/ardour/ardour/audio_diskstream.h12
-rw-r--r--libs/ardour/ardour/audiofilesource.h10
-rw-r--r--libs/ardour/ardour/audioregion.h13
-rw-r--r--libs/ardour/ardour/audiosource.h4
-rw-r--r--libs/ardour/ardour/auditioner.h2
-rw-r--r--libs/ardour/ardour/diskstream.h2
-rw-r--r--libs/ardour/ardour/region_factory.h5
-rw-r--r--libs/ardour/ardour/session.h30
-rw-r--r--libs/ardour/ardour/source.h8
-rw-r--r--libs/ardour/ardour/source_factory.h29
-rw-r--r--libs/ardour/ardour/types.h3
-rw-r--r--libs/ardour/audio_diskstream.cc45
-rw-r--r--libs/ardour/audio_playlist.cc7
-rw-r--r--libs/ardour/audio_track.cc6
-rw-r--r--libs/ardour/audiofilesource.cc82
-rw-r--r--libs/ardour/audiofilter.cc8
-rw-r--r--libs/ardour/audioregion.cc74
-rw-r--r--libs/ardour/audiosource.cc15
-rw-r--r--libs/ardour/auditioner.cc12
-rw-r--r--libs/ardour/destructive_filesource.cc2
-rw-r--r--libs/ardour/diskstream.cc2
-rw-r--r--libs/ardour/import.cc27
-rw-r--r--libs/ardour/playlist.cc1
-rw-r--r--libs/ardour/region_factory.cc18
-rw-r--r--libs/ardour/reverse.cc3
-rw-r--r--libs/ardour/session.cc205
-rw-r--r--libs/ardour/session_butler.cc2
-rw-r--r--libs/ardour/session_events.cc2
-rw-r--r--libs/ardour/session_state.cc45
-rw-r--r--libs/ardour/session_timefx.cc12
-rw-r--r--libs/ardour/sndfilesource.cc10
-rw-r--r--libs/ardour/source.cc15
-rw-r--r--libs/ardour/source_factory.cc155
45 files changed, 490 insertions, 458 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 66374ff417..f2ab470c3d 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -2156,12 +2156,12 @@ ARDOUR_UI::halt_on_xrun_message ()
}
void
-ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
+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<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
- delete *i;
+ for (list<boost::shared_ptr<Source> >::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
+ (*i)->drop_references ();
}
delete deletion_list;
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index cafa335bf2..5a9b7c4ae4 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -638,7 +638,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
struct timeval last_peak_grab;
struct timeval last_shuttle_request;
- void delete_sources_in_the_right_thread (list<ARDOUR::Source*>*);
+ void delete_sources_in_the_right_thread (list<boost::shared_ptr<ARDOUR::Source> >*);
void editor_display_control_changed (Editing::DisplayControl c);
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index 19c8702e89..86786b801f 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -761,7 +761,7 @@ AudioRegionView::create_waves ()
wave_caches.push_back (WaveView::create_cache ());
if (wait_for_data) {
- if (audio_region()->source(n).peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) {
+ if (audio_region()->source(n)->peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) {
create_one_wave (n, true);
} else {
create_zero_line = false;
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index c0b3ba4c39..beb8cb8d2e 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -25,7 +25,7 @@
#include <ardour/audioplaylist.h>
#include <ardour/audioregion.h>
-#include <ardour/audiosource.h>
+#include <ardour/audiofilesource.h>
#include <ardour/audio_diskstream.h>
#include <ardour/audio_track.h>
#include <ardour/playlist_templates.h>
@@ -404,7 +404,7 @@ AudioStreamView::setup_rec_box ()
assert(ads);
for (uint32_t n=0; n < ads->n_channels(); ++n) {
- AudioSource *src = (AudioSource *) ads->write_source (n);
+ 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)));
@@ -530,7 +530,7 @@ AudioStreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void))
}
void
-AudioStreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * src)
+AudioStreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, boost::shared_ptr<Source> src)
{
// this is called from the peak building thread
@@ -605,7 +605,7 @@ AudioStreamView::update_rec_regions ()
if (nlen != region->length()) {
- if (region->source(0).length() >= region->start() + nlen) {
+ if (region->source(0)->length() >= region->start() + nlen) {
region->freeze ();
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h
index 8d5ab4117c..13b042eec8 100644
--- a/gtk2_ardour/audio_streamview.h
+++ b/gtk2_ardour/audio_streamview.h
@@ -76,7 +76,7 @@ class AudioStreamView : public StreamView
private:
void setup_rec_box ();
- void rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, ARDOUR::Source* src);
+ void rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, boost::shared_ptr<ARDOUR::Source> src);
void update_rec_regions ();
void add_region_view_internal (boost::shared_ptr<ARDOUR::Region>, bool wait_for_waves);
@@ -103,7 +103,7 @@ class AudioStreamView : public StreamView
list<sigc::connection> peak_ready_connections;
jack_nframes_t last_rec_peak_frame;
- map<ARDOUR::Source*, bool> rec_peak_ready_map;
+ map<boost::shared_ptr<ARDOUR::Source>, bool> rec_peak_ready_map;
};
diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc
index a89d4462ae..1d275d5e3b 100644
--- a/gtk2_ardour/crossfade_edit.cc
+++ b/gtk2_ardour/crossfade_edit.cc
@@ -1036,7 +1036,7 @@ CrossfadeEditor::make_waves (boost::shared_ptr<AudioRegion> region, WhichFade wh
gdouble yoff = n * ht;
- if (region->source(n).peaks_ready (bind (mem_fun(*this, &CrossfadeEditor::peaks_ready), region, which), peaks_ready_connection)) {
+ if (region->source(n)->peaks_ready (bind (mem_fun(*this, &CrossfadeEditor::peaks_ready), region, which), peaks_ready_connection)) {
WaveView* waveview = new WaveView (*(canvas->root()));
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index ebff933514..fffad2e2eb 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -32,6 +32,7 @@
#include <ardour/audioplaylist.h>
#include <ardour/audiofilesource.h>
#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
#include <pbd/memento_command.h>
#include "ardour_ui.h"
@@ -189,7 +190,7 @@ int
Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode,
AudioTrack* track, jack_nframes_t& pos, bool prompt)
{
- AudioFileSource *source = 0; /* keep g++ quiet */
+ boost::shared_ptr<AudioFileSource> source;
SourceList sources;
boost::shared_ptr<AudioRegion> region;
string idspec;
@@ -269,7 +270,7 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
idspec += string_compose(":%1", n);
try {
- source = AudioFileSource::create (idspec.c_str(), (mode == ImportAsTrack ? AudioFileSource::Destructive : AudioFileSource::Flag (0)));
+ source = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (idspec, (mode == ImportAsTrack ? AudioFileSource::Destructive : AudioFileSource::Flag (0))));
sources.push_back(source);
}
diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc
index 6eeff78d84..dc7fadb470 100644
--- a/gtk2_ardour/editor_export_audio.cc
+++ b/gtk2_ardour/editor_export_audio.cc
@@ -41,6 +41,8 @@
#include <ardour/audio_diskstream.h>
#include <ardour/audioregion.h>
#include <ardour/audioplaylist.h>
+#include <ardour/source_factory.h>
+#include <ardour/audiofilesource.h>
#include "i18n.h"
@@ -157,7 +159,7 @@ Editor::bounce_region_selection ()
bool
Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
{
- AudioFileSource* fs;
+ boost::shared_ptr<AudioFileSource> fs;
const jack_nframes_t chunk_size = 4096;
jack_nframes_t to_read;
Sample buf[chunk_size];
@@ -165,14 +167,14 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
jack_nframes_t pos;
char s[PATH_MAX+1];
uint32_t cnt;
- vector<AudioFileSource *> sources;
+ vector<boost::shared_ptr<AudioFileSource> > sources;
uint32_t nchans;
nchans = region->n_channels();
/* don't do duplicate of the entire source if that's what is going on here */
- if (region->start() == 0 && region->length() == region->source().length()) {
+ if (region->start() == 0 && region->length() == region->source()->length()) {
/* XXX should link(2) to create a new inode with "path" */
return true;
}
@@ -206,7 +208,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
try {
- fs = AudioFileSource::create (path);
+ fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (path, AudioFileSource::Flag (0)));
}
catch (failed_constructor& err) {
@@ -229,7 +231,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
this_time = min (to_read, chunk_size);
- for (vector<AudioFileSource *>::iterator src=sources.begin(); src != sources.end(); ++src) {
+ for (vector<boost::shared_ptr<AudioFileSource> >::iterator src=sources.begin(); src != sources.end(); ++src) {
fs = (*src);
@@ -252,7 +254,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
time (&tnow);
now = localtime (&tnow);
- for (vector<AudioFileSource *>::iterator src = sources.begin(); src != sources.end(); ++src) {
+ for (vector<boost::shared_ptr<AudioFileSource> >::iterator src = sources.begin(); src != sources.end(); ++src) {
(*src)->update_header (0, *now, tnow);
}
@@ -260,10 +262,8 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
error_out:
- for (vector<AudioFileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {
-
+ for (vector<boost::shared_ptr<AudioFileSource> >::iterator i = sources.begin(); i != sources.end(); ++i) {
(*i)->mark_for_remove ();
- delete (*i);
}
return 0;
@@ -303,7 +303,7 @@ Editor::write_audio_selection (TimeSelection& ts)
bool
Editor::write_audio_range (AudioPlaylist& playlist, uint32_t channels, list<AudioRange>& range)
{
- AudioFileSource* fs;
+ boost::shared_ptr<AudioFileSource> fs;
const jack_nframes_t chunk_size = 4096;
jack_nframes_t nframes;
Sample buf[chunk_size];
@@ -312,7 +312,7 @@ Editor::write_audio_range (AudioPlaylist& playlist, uint32_t channels, list<Audi
char s[PATH_MAX+1];
uint32_t cnt;
string path;
- vector<AudioFileSource *> sources;
+ vector<boost::shared_ptr<AudioFileSource> > sources;
for (uint32_t n=0; n < channels; ++n) {
@@ -339,7 +339,7 @@ Editor::write_audio_range (AudioPlaylist& playlist, uint32_t channels, list<Audi
path = s;
try {
- fs = AudioFileSource::create (path);
+ fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (path, AudioFileSource::Flag (0)));
}
catch (failed_constructor& err) {
@@ -422,9 +422,8 @@ Editor::write_audio_range (AudioPlaylist& playlist, uint32_t channels, list<Audi
error_out:
/* unref created files */
- for (vector<AudioFileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {
+ for (vector<boost::shared_ptr<AudioFileSource> >::iterator i = sources.begin(); i != sources.end(); ++i) {
(*i)->mark_for_remove ();
- delete *i;
}
return false;
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index 09a56e9af5..a84e53c749 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -120,11 +120,11 @@ Editor::add_audio_region_to_region_display (boost::shared_ptr<AudioRegion> regio
set_color(c, rgba_from_style ("RegionListWholeFile", 0xff, 0, 0, 0, "fg", Gtk::STATE_NORMAL, false ));
row[region_list_columns.color_] = c;
- if (region->source().name()[0] == '/') { // external file
+ if (region->source()->name()[0] == '/') { // external file
if (region->whole_file()) {
str = ".../";
- str += PBD::basename_nosuffix (region->source().name());
+ str += PBD::basename_nosuffix (region->source()->name());
} else {
str = region->name();
@@ -467,7 +467,7 @@ Editor::region_list_sorter (TreeModel::iterator a, TreeModel::iterator b)
break;
case ByTimestamp:
- cmp = region1->source().timestamp() - region2->source().timestamp();
+ cmp = region1->source()->timestamp() - region2->source()->timestamp();
break;
case ByStartInFile:
@@ -479,22 +479,22 @@ Editor::region_list_sorter (TreeModel::iterator a, TreeModel::iterator b)
break;
case BySourceFileName:
- cmp = strcasecmp (region1->source().name().c_str(), region2->source().name().c_str());
+ cmp = strcasecmp (region1->source()->name().c_str(), region2->source()->name().c_str());
break;
case BySourceFileLength:
- cmp = region1->source().length() - region2->source().length();
+ cmp = region1->source()->length() - region2->source()->length();
break;
case BySourceFileCreationDate:
- cmp = region1->source().timestamp() - region2->source().timestamp();
+ cmp = region1->source()->timestamp() - region2->source()->timestamp();
break;
case BySourceFileFS:
- if (region1->source().name() == region2->source().name()) {
+ if (region1->source()->name() == region2->source()->name()) {
cmp = strcasecmp (region1->name().c_str(), region2->name().c_str());
} else {
- cmp = strcasecmp (region1->source().name().c_str(), region2->source().name().c_str());
+ cmp = strcasecmp (region1->source()->name().c_str(), region2->source()->name().c_str());
}
break;
}
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc
index 34dcf56ec3..cfede6d863 100644
--- a/gtk2_ardour/sfdb_ui.cc
+++ b/gtk2_ardour/sfdb_ui.cc
@@ -33,6 +33,7 @@
#include <ardour/audioregion.h>
#include <ardour/audiofilesource.h>
#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
#include "ardour_ui.h"
#include "gui_thread.h"
@@ -192,11 +193,11 @@ SoundFileBox::play_btn_clicked ()
if (region_cache.find (path) == region_cache.end()) {
SourceList srclist;
- AudioFileSource* afs;
-
+ boost::shared_ptr<AudioFileSource> afs;
+
for (int n = 0; n < sf_info.channels; ++n) {
try {
- afs = AudioFileSource::create (path+":"+string_compose("%1", n));
+ afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (path+":"+string_compose("%1", n), AudioFileSource::Flag (0)));
srclist.push_back(afs);
} catch (failed_constructor& err) {
diff --git a/gtk2_ardour/tape_region_view.cc b/gtk2_ardour/tape_region_view.cc
index e71429ed3a..0cf50b87e6 100644
--- a/gtk2_ardour/tape_region_view.cc
+++ b/gtk2_ardour/tape_region_view.cc
@@ -68,7 +68,7 @@ TapeAudioRegionView::init (Gdk::Color& basic_color, bool wfw)
/* every time the wave data changes and peaks are ready, redraw */
for (uint32_t n = 0; n < audio_region()->n_channels(); ++n) {
- audio_region()->source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n));
+ audio_region()->source(n)->PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n));
}
}
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 09fd5e9b8e..55acb865d1 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -90,6 +90,7 @@ session_transport.cc
sndfile_helpers.cc
sndfilesource.cc
source.cc
+source_factory.cc
state_manager.cc
tempo.cc
utils.cc
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index eaa69e00d8..44fb6e59a4 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -108,10 +108,10 @@ class AudioDiskstream : public Diskstream
return 0;
}
- AudioFileSource *write_source (uint32_t n=0) {
+ boost::shared_ptr<AudioFileSource> write_source (uint32_t n=0) {
if (n < channels.size())
return channels[n].write_source;
- return 0;
+ return boost::shared_ptr<AudioFileSource>();
}
int add_channel ();
@@ -179,9 +179,9 @@ class AudioDiskstream : public Diskstream
Sample *speed_buffer;
float peak_power;
-
- AudioFileSource *fades_source;
- AudioFileSource *write_source;
+
+ boost::shared_ptr<AudioFileSource> fades_source;
+ boost::shared_ptr<AudioFileSource> write_source;
Port *source;
Sample *current_capture_buffer;
@@ -249,7 +249,7 @@ class AudioDiskstream : public Diskstream
int _do_refill (Sample *mixdown_buffer, float *gain_buffer);
- std::vector<AudioFileSource*> capturing_sources;
+ std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources;
typedef vector<ChannelInfo> ChannelList;
ChannelList channels;
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h
index eb3fd750d4..b0aa9bac58 100644
--- a/libs/ardour/ardour/audiofilesource.h
+++ b/libs/ardour/ardour/audiofilesource.h
@@ -56,16 +56,6 @@ class AudioFileSource : public AudioSource {
static void set_peak_dir (string dir) { peak_dir = dir; }
- /* factory for an existing but not-used-in-session audio file. this exists
- because there maybe multiple back-end derivations of AudioFileSource,
- some of which can handle formats that cannot be handled by others.
- For example, CoreAudioFileSource can handle MP3 files, which SndFileSource
- cannot.
- */
-
- static AudioFileSource* create (const string& path_plus_channel, Flag flags = Flag (0));
- static AudioFileSource* create (const XMLNode&);
-
static bool get_soundfile_info (string path, SoundFileInfo& _info, string& error);
void set_allow_remove_if_empty (bool yn);
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index ad8672a269..36c6256d50 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -71,9 +71,7 @@ class AudioRegion : public Region
bool speed_mismatch (float) const;
- void lock_sources ();
- void unlock_sources ();
- AudioSource& source (uint32_t n=0) const { if (n < sources.size()) return *sources[n]; else return *sources[0]; }
+ boost::shared_ptr<AudioSource> source (uint32_t n=0) const { if (n < sources.size()) return sources[n]; else return sources[0]; }
void set_scale_amplitude (gain_t);
gain_t scale_amplitude() const { return _scale_amplitude; }
@@ -155,12 +153,12 @@ class AudioRegion : public Region
private:
friend class RegionFactory;
- AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length);
- AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (boost::shared_ptr<AudioSource>, jack_nframes_t start, jack_nframes_t length);
+ AudioRegion (boost::shared_ptr<AudioSource>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (boost::shared_ptr<const AudioRegion>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (boost::shared_ptr<const AudioRegion>);
- AudioRegion (AudioSource&, const XMLNode&);
+ AudioRegion (boost::shared_ptr<AudioSource>, const XMLNode&);
AudioRegion (SourceList &, const XMLNode&);
private:
@@ -190,8 +188,7 @@ class AudioRegion : public Region
void envelope_changed (Change);
- void source_deleted (Source*);
-
+ void source_deleted (boost::shared_ptr<Source>);
SourceList sources;
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index 786423d9f8..45fe8e5c9f 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -84,8 +84,6 @@ class AudioSource : public Source
int build_peaks ();
bool peaks_ready (sigc::slot<void>, sigc::connection&) const;
- static sigc::signal<void,AudioSource*> AudioSourceCreated;
-
mutable sigc::signal<void> PeaksReady;
mutable sigc::signal<void,jack_nframes_t,jack_nframes_t> PeakRangeReady;
@@ -147,7 +145,7 @@ class AudioSource : public Source
static vector<AudioSource*> pending_peak_sources;
static Glib::Mutex* pending_peak_sources_lock;
- static void queue_for_peaks (AudioSource&);
+ static void queue_for_peaks (AudioSource*);
static void clear_queue_for_peaks ();
struct PeakBuildRecord {
diff --git a/libs/ardour/ardour/auditioner.h b/libs/ardour/ardour/auditioner.h
index c693589864..424ede0009 100644
--- a/libs/ardour/ardour/auditioner.h
+++ b/libs/ardour/ardour/auditioner.h
@@ -40,7 +40,7 @@ class Auditioner : public AudioTrack
Auditioner (Session&);
~Auditioner ();
- void audition_region (boost::shared_ptr<AudioRegion>);
+ void audition_region (boost::shared_ptr<Region>);
ARDOUR::AudioPlaylist& prepare_playlist ();
void audition_current_playlist ();
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index f9463a3320..3c2154896c 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -148,7 +148,7 @@ class IO;
static sigc::signal<void> DiskOverrun;
static sigc::signal<void> DiskUnderrun;
- static sigc::signal<void,list<Source*>*> DeleteSources;
+ static sigc::signal<void,std::list<boost::shared_ptr<Source> >*> DeleteSources;
protected:
friend class Session;
diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h
index d4033680ee..3bf1b6005e 100644
--- a/libs/ardour/ardour/region_factory.h
+++ b/libs/ardour/ardour/region_factory.h
@@ -26,7 +26,10 @@ class RegionFactory {
static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, jack_nframes_t start,
jack_nframes_t length, std::string name,
layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- static boost::shared_ptr<Region> create (Source&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (boost::shared_ptr<AudioRegion>, jack_nframes_t start,
+ jack_nframes_t length, std::string name,
+ layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Source>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
static boost::shared_ptr<Region> create (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
static boost::shared_ptr<Region> create (boost::shared_ptr<Region>);
static boost::shared_ptr<Region> create (Session&, XMLNode&, bool);
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index c299358268..ec7deccc31 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -21,12 +21,16 @@
#ifndef __ardour_session_h__
#define __ardour_session_h__
+
#include <string>
#include <list>
#include <map>
#include <vector>
#include <set>
#include <stack>
+
+#include <boost/weak_ptr.hpp>
+
#include <stdint.h>
#include <sndfile.h>
@@ -172,6 +176,8 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
Route* route;
};
+ boost::shared_ptr<Region> region;
+
list<AudioRange> audio_range;
list<MusicRange> music_range;
@@ -654,9 +660,9 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
int start_audio_export (ARDOUR::AudioExportSpecification&);
int stop_audio_export (ARDOUR::AudioExportSpecification&);
- void add_audio_source (AudioSource *);
- void remove_source (Source *);
- int cleanup_audio_file_source (AudioFileSource&);
+ void add_source (boost::shared_ptr<Source>);
+ void remove_source (boost::weak_ptr<Source>);
+ int cleanup_audio_file_source (boost::shared_ptr<AudioFileSource>);
struct cleanup_report {
vector<string> paths;
@@ -685,12 +691,12 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
static sigc::signal<int> AskAboutPendingState;
- sigc::signal<void,Source *> SourceAdded;
- sigc::signal<void,Source *> SourceRemoved;
+ sigc::signal<void,boost::shared_ptr<Source> > SourceAdded;
+ sigc::signal<void,boost::shared_ptr<Source> > SourceRemoved;
- AudioFileSource *create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
+ boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
- Source *source_by_id (const PBD::ID&);
+ boost::shared_ptr<Source> source_by_id (const PBD::ID&);
/* playlist management */
@@ -735,7 +741,7 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
/* flattening stuff */
- int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<AudioSource*>&,
+ int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<boost::shared_ptr<AudioSource> >&,
InterThreadInfo& wot);
int freeze (InterThreadInfo&);
@@ -1555,14 +1561,14 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
/* SOURCES */
mutable Glib::Mutex audio_source_lock;
- typedef std::map<PBD::ID,AudioSource *> AudioSourceList;
+ typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
AudioSourceList audio_sources;
int load_sources (const XMLNode& node);
XMLNode& get_sources_as_xml ();
- Source *XMLSourceFactory (const XMLNode&);
+ boost::shared_ptr<Source> XMLSourceFactory (const XMLNode&);
/* PLAYLISTS */
@@ -1605,9 +1611,9 @@ class Session : public sigc::trackable, public PBD::StatefulDestructible
/* AUDITIONING */
boost::shared_ptr<Auditioner> auditioner;
- void set_audition (boost::shared_ptr<AudioRegion>);
+ void set_audition (boost::shared_ptr<Region>);
void non_realtime_set_audition ();
- boost::shared_ptr<AudioRegion> pending_audition_region;
+ boost::shared_ptr<Region> pending_audition_region;
/* EXPORT */
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index dee75a2300..20a8190bd4 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -24,6 +24,7 @@
#include <string>
#include <sigc++/signal.h>
+#include <boost/enable_shared_from_this.hpp>
#include <pbd/statefuldestructible.h>
@@ -31,7 +32,7 @@
namespace ARDOUR {
-class Source : public PBD::StatefulDestructible, public sigc::trackable
+class Source : public PBD::StatefulDestructible, public sigc::trackable, public boost::enable_shared_from_this<Source>
{
public:
Source (std::string name);
@@ -43,10 +44,6 @@ class Source : public PBD::StatefulDestructible, public sigc::trackable
const PBD::ID& id() const { return _id; }
- uint32_t use_cnt() const { return _use_cnt; }
- void use ();
- void release ();
-
time_t timestamp() const { return _timestamp; }
void stamp (time_t when) { _timestamp = when; }
@@ -56,7 +53,6 @@ class Source : public PBD::StatefulDestructible, public sigc::trackable
protected:
string _name;
- uint32_t _use_cnt;
time_t _timestamp;
private:
diff --git a/libs/ardour/ardour/source_factory.h b/libs/ardour/ardour/source_factory.h
new file mode 100644
index 0000000000..92ed0415c8
--- /dev/null
+++ b/libs/ardour/ardour/source_factory.h
@@ -0,0 +1,29 @@
+#ifndef __ardour_source_factory_h__
+#define __ardour_source_factory_h__
+
+#include <string>
+#include <stdint.h>
+#include <sigc++/sigc++.h>
+#include <boost/shared_ptr.hpp>
+
+#include <ardour/source.h>
+#include <ardour/audiofilesource.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class SourceFactory {
+ public:
+ static sigc::signal<void,boost::shared_ptr<Source> > SourceCreated;
+
+ static boost::shared_ptr<Source> create (const XMLNode& node);
+
+ // MIDI sources will have to be hacked in here somehow
+ static boost::shared_ptr<Source> createReadable (std::string idstr, AudioFileSource::Flag flags, bool announce = true);
+ static boost::shared_ptr<Source> createWritable (std::string name, bool destructive, jack_nframes_t rate, bool announce = true);
+};
+
+}
+
+#endif /* __ardour_source_factory_h__ */
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 9c92b49ed0..39c06b6dcc 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -27,6 +27,7 @@
#include <istream>
#include <vector>
+#include <boost/shared_ptr.hpp>
#include <inttypes.h>
#include <jack/types.h>
@@ -252,7 +253,7 @@ namespace ARDOUR {
VST
};
- typedef std::vector<AudioSource *> SourceList;
+ typedef std::vector<boost::shared_ptr<AudioSource> > SourceList;
} // namespace ARDOUR
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 24363e3594..57271068dc 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -48,6 +48,7 @@
#include <ardour/audioplaylist.h>
#include <ardour/cycle_timer.h>
#include <ardour/audioregion.h>
+#include <ardour/source_factory.h>
#include "i18n.h"
#include <locale.h>
@@ -100,7 +101,6 @@ AudioDiskstream::init_channel (ChannelInfo &chan)
chan.capture_wrap_buffer = 0;
chan.speed_buffer = 0;
chan.peak_power = 0.0f;
- chan.write_source = 0;
chan.source = 0;
chan.current_capture_buffer = 0;
chan.current_playback_buffer = 0;
@@ -143,8 +143,7 @@ void
AudioDiskstream::destroy_channel (ChannelInfo &chan)
{
if (chan.write_source) {
- chan.write_source->release ();
- chan.write_source = 0;
+ chan.write_source.reset ();
}
if (chan.speed_buffer) {
@@ -406,7 +405,7 @@ AudioDiskstream::use_destructive_playlist ()
ChannelList::iterator chan;
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
- (*chan).write_source = dynamic_cast<AudioFileSource*>(&region->source (n));
+ (*chan).write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
assert((*chan).write_source);
(*chan).write_source->set_allow_remove_if_empty (false);
}
@@ -1489,18 +1488,17 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
ChannelList::iterator chan;
- list<Source*>* deletion_list = new list<Source*>;
+ list<boost::shared_ptr<Source> >* deletion_list = new list<boost::shared_ptr<Source> >;
for ( chan = channels.begin(); chan != channels.end(); ++chan) {
if ((*chan).write_source) {
(*chan).write_source->mark_for_remove ();
- (*chan).write_source->release ();
deletion_list->push_back ((*chan).write_source);
- (*chan).write_source = 0;
+ (*chan).write_source.reset ();
}
/* new source set up in "out" below */
@@ -1523,19 +1521,11 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
- AudioFileSource* s = (*chan).write_source;
+ boost::shared_ptr<AudioFileSource> s = (*chan).write_source;
if (s) {
-
- AudioFileSource* fsrc;
-
srcs.push_back (s);
-
- if ((fsrc = dynamic_cast<AudioFileSource *>(s)) != 0) {
- cerr << "updating source after capture\n";
- fsrc->update_header (capture_info.front()->start, when, twhen);
- }
-
+ s->update_header (capture_info.front()->start, when, twhen);
s->set_captured_for (_name);
}
@@ -1779,7 +1769,7 @@ AudioDiskstream::get_state ()
XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
XMLNode* cs_grandchild;
- for (vector<AudioFileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
+ for (vector<boost::shared_ptr<AudioFileSource> >::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
cs_grandchild = new XMLNode (X_("file"));
cs_grandchild->add_property (X_("path"), (*i)->path());
cs_child->add_child_nocopy (*cs_grandchild);
@@ -1948,11 +1938,9 @@ AudioDiskstream::use_new_write_source (uint32_t n)
if (AudioFileSource::is_empty (chan.write_source->path())) {
chan.write_source->mark_for_remove ();
- chan.write_source->release();
- delete chan.write_source;
+ chan.write_source.reset ();
} else {
- chan.write_source->release();
- chan.write_source = 0;
+ chan.write_source.reset ();
}
}
@@ -1964,12 +1952,10 @@ AudioDiskstream::use_new_write_source (uint32_t n)
catch (failed_constructor &err) {
error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
- chan.write_source = 0;
+ chan.write_source.reset ();
return -1;
}
- chan.write_source->use ();
-
/* do not remove destructive files even if they are empty */
chan.write_source->set_allow_remove_if_empty (!destructive());
@@ -2166,8 +2152,8 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
const XMLProperty* prop;
XMLNodeList nlist = node.children();
XMLNodeIterator niter;
- AudioFileSource* fs;
- AudioFileSource* first_fs = 0;
+ boost::shared_ptr<AudioFileSource> fs;
+ boost::shared_ptr<AudioFileSource> first_fs;
SourceList pending_sources;
jack_nframes_t position;
@@ -2187,10 +2173,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
}
try {
- fs = new SndFileSource (prop->value(),
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- _session.frame_rate());
+ fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (prop->value(), false, _session.frame_rate()));
}
catch (failed_constructor& err) {
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 1136476358..d9902c8b59 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -608,12 +608,6 @@ AudioPlaylist::drop_all_states ()
}
}
- /* delete every region that is left - these are all things that are part of our "history" */
-
- for (set<boost::shared_ptr<Region> >::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
- (*ar)->unlock_sources ();
- }
-
/* delete every crossfade that is left (ditto as per regions) */
for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
@@ -764,7 +758,6 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
++tmp;
if ((*i) == region) {
- (*i)->unlock_sources ();
regions.erase (i);
changed = true;
}
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 60400a046c..18a13f5f3f 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -728,7 +728,7 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes
void
AudioTrack::bounce (InterThreadInfo& itt)
{
- vector<AudioSource*> srcs;
+ vector<boost::shared_ptr<AudioSource> > srcs;
_session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
}
@@ -736,14 +736,14 @@ AudioTrack::bounce (InterThreadInfo& itt)
void
AudioTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt)
{
- vector<AudioSource*> srcs;
+ vector<boost::shared_ptr<AudioSource> > srcs;
_session.write_one_audio_track (*this, start, end, false, srcs, itt);
}
void
AudioTrack::freeze (InterThreadInfo& itt)
{
- vector<AudioSource*> srcs;
+ vector<boost::shared_ptr<AudioSource> > srcs;
string new_playlist_name;
Playlist* new_playlist;
string dir;
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index ee35f3068a..66bf3ed561 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -38,6 +38,7 @@
#include <ardour/sndfilesource.h>
#include <ardour/destructive_filesource.h>
#include <ardour/session.h>
+#include <ardour/source_factory.h>
// if these headers come before sigc++ is included
// the parser throws ObjC++ errors. (nil is a keyword)
@@ -108,8 +109,7 @@ AudioFileSource::~AudioFileSource ()
bool
AudioFileSource::removable () const
{
- return (_flags & Removable) && ((_flags & RemoveAtDestroy) ||
- ((_flags & RemovableIfEmpty) && is_empty (_path)));
+ return (_flags & Removable) && ((_flags & RemoveAtDestroy) || ((_flags & RemovableIfEmpty) && is_empty (_path)));
}
int
@@ -164,80 +164,6 @@ AudioFileSource::old_peak_path (string audio_path)
return res;
}
-#ifdef HAVE_COREAUDIO
-
-AudioFileSource*
-AudioFileSource::create (const XMLNode& node)
-{
- AudioFileSource* es = 0;
-
- if (node.property (X_("destructive")) != 0) {
-
- es = new DestructiveFileSource (node);
-
- } else {
-
- try {
- es = new CoreAudioSource (node);
- }
-
-
- catch (failed_constructor& err) {
- es = new SndFileSource (node);
- }
- }
-
- return es;
-}
-
-#else
-
-AudioFileSource*
-AudioFileSource::create (const XMLNode& node)
-{
- if (node.property (X_("destructive")) != 0) {
-
- return new DestructiveFileSource (node);
-
- } else {
-
- return new SndFileSource (node);
- }
-}
-
-#endif // HAVE_COREAUDIO
-
-#ifdef HAVE_COREAUDIO
-AudioFileSource*
-AudioFileSource::create (const string& idstr, Flag flags)
-{
- AudioFileSource* es = 0;
-
- if (flags & Destructive) {
- return new DestructiveFileSource (idstr, flags);
- }
-
- try {
- es = new CoreAudioSource (idstr, flags);
- }
-
- catch (failed_constructor& err) {
- es = new SndFileSource (idstr, flags);
- }
-
- return es;
-}
-
-#else
-
-AudioFileSource*
-AudioFileSource::create (const string& idstr, Flag flags)
-{
- return new SndFileSource (idstr, flags);
-}
-
-#endif // HAVE_COREAUDIO
-
bool
AudioFileSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
{
@@ -579,7 +505,6 @@ void
AudioFileSource::set_header_position_offset (jack_nframes_t offset)
{
header_position_offset = offset;
- cerr << "hpo set to " << offset << endl;
HeaderPositionOffsetChanged ();
}
@@ -630,11 +555,10 @@ bool
AudioFileSource::is_empty (string path)
{
bool ret = false;
- AudioFileSource* afs = create (path, NoPeakFile);
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (path, NoPeakFile, false));
if (afs) {
ret = (afs->length() == 0);
- delete afs;
}
return ret;
diff --git a/libs/ardour/audiofilter.cc b/libs/ardour/audiofilter.cc
index 3e9c36ddd2..dab32cc330 100644
--- a/libs/ardour/audiofilter.cc
+++ b/libs/ardour/audiofilter.cc
@@ -27,6 +27,7 @@
#include <ardour/audioregion.h>
#include <ardour/audiofilter.h>
#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
#include "i18n.h"
@@ -49,10 +50,7 @@ AudioFilter::make_new_sources (boost::shared_ptr<AudioRegion> region, SourceList
}
try {
- nsrcs.push_back (new SndFileSource (path,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- session.frame_rate()));
+ nsrcs.push_back (boost::dynamic_pointer_cast<AudioSource> (SourceFactory::createWritable (path, false, session.frame_rate())));
}
catch (failed_constructor& err) {
@@ -78,7 +76,7 @@ AudioFilter::finish (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs)
now = localtime (&xnow);
for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*si);
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*si);
if (afs) {
afs->update_header (region->position(), *now, xnow);
}
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 5cedb246ba..5c45fa51b2 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -64,17 +64,17 @@ AudioRegionState::AudioRegionState (string why)
{
}
-AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length)
- : Region (start, length, PBD::basename_nosuffix(src.name()), 0, Region::Flag(Region::DefaultFlags|Region::External)),
+AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, jack_nframes_t start, jack_nframes_t length)
+ : Region (start, length, PBD::basename_nosuffix(src->name()), 0, Region::Flag(Region::DefaultFlags|Region::External)),
_fade_in (0.0, 2.0, 1.0, false),
_fade_out (0.0, 2.0, 1.0, false),
_envelope (0.0, 2.0, 1.0, false)
{
/* basic AudioRegion constructor */
- sources.push_back (&src);
- master_sources.push_back (&src);
- src.GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), &src));
+ sources.push_back (src);
+ master_sources.push_back (src);
+ src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src));
_scale_amplitude = 1.0;
@@ -86,7 +86,7 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
}
-AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
+AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (start, length, name, layer, flags),
_fade_in (0.0, 2.0, 1.0, false),
_fade_out (0.0, 2.0, 1.0, false),
@@ -94,9 +94,9 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
{
/* basic AudioRegion constructor */
- sources.push_back (&src);
- master_sources.push_back (&src);
- src.GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), &src));
+ sources.push_back (src);
+ master_sources.push_back (src);
+ src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src));
_scale_amplitude = 1.0;
@@ -139,7 +139,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, jack_nfram
{
/* create a new AudioRegion, that is part of an existing one */
- set<AudioSource*> unique_srcs;
+ set<boost::shared_ptr<AudioSource> > unique_srcs;
for (SourceList::const_iterator i= other->sources.begin(); i != other->sources.end(); ++i) {
sources.push_back (*i);
@@ -194,7 +194,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
{
/* Pure copy constructor */
- set<AudioSource*> unique_srcs;
+ set<boost::shared_ptr<AudioSource> > unique_srcs;
for (SourceList::const_iterator i = other->sources.begin(); i != other->sources.end(); ++i) {
sources.push_back (*i);
@@ -222,15 +222,15 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
/* NOTE: no CheckNewRegion signal emitted here. This is the copy constructor */
}
-AudioRegion::AudioRegion (AudioSource& src, const XMLNode& node)
+AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
: Region (node),
_fade_in (0.0, 2.0, 1.0, false),
_fade_out (0.0, 2.0, 1.0, false),
_envelope (0.0, 2.0, 1.0, false)
{
- sources.push_back (&src);
- master_sources.push_back (&src);
- src.GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), &src));
+ sources.push_back (src);
+ master_sources.push_back (src);
+ src->GoingAway.connect (bind (mem_fun (*this, &AudioRegion::source_deleted), src));
set_default_fades ();
@@ -249,7 +249,7 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
_fade_out (0.0, 2.0, 1.0, false),
_envelope (0.0, 2.0, 1.0, false)
{
- set<AudioSource*> unique_srcs;
+ set<boost::shared_ptr<AudioSource> > unique_srcs;
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
sources.push_back (*i);
@@ -1058,47 +1058,11 @@ AudioRegion::separate_by_channel (Session& session, vector<AudioRegion*>& v) con
}
void
-AudioRegion::source_deleted (Source* ignored)
+AudioRegion::source_deleted (boost::shared_ptr<Source> ignored)
{
delete this;
}
-void
-AudioRegion::lock_sources ()
-{
- SourceList::iterator i;
- set<AudioSource*> unique_srcs;
-
- for (i = sources.begin(); i != sources.end(); ++i) {
- unique_srcs.insert (*i);
- (*i)->use ();
- }
-
- for (i = master_sources.begin(); i != master_sources.end(); ++i) {
- if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->use ();
- }
- }
-}
-
-void
-AudioRegion::unlock_sources ()
-{
- SourceList::iterator i;
- set<AudioSource*> unique_srcs;
-
- for (i = sources.begin(); i != sources.end(); ++i) {
- unique_srcs.insert (*i);
- (*i)->release ();
- }
-
- for (i = master_sources.begin(); i != master_sources.end(); ++i) {
- if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->release ();
- }
- }
-}
-
vector<string>
AudioRegion::master_source_names ()
{
@@ -1269,7 +1233,7 @@ AudioRegion::normalize_to (float target_dB)
/* read it in */
- if (source (n).read (buf, fpos, to_read) != to_read) {
+ if (source (n)->read (buf, fpos, to_read) != to_read) {
return;
}
@@ -1377,7 +1341,7 @@ uint32_t region_length_from_c (void *arg)
uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
{
- return ( (AudioRegion *) arg)->source().available_peaks (zoom_factor) ;
+ return ( (AudioRegion *) arg)->source()->available_peaks (zoom_factor) ;
}
} /* extern "C" */
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index ab5ac437c3..19f6de5c64 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -28,6 +28,7 @@
#include <cmath>
#include <iomanip>
#include <algorithm>
+#include <vector>
#include <pbd/xml++.h>
#include <pbd/pthread_utils.h>
@@ -40,7 +41,6 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-sigc::signal<void,AudioSource *> AudioSource::AudioSourceCreated;
pthread_t AudioSource::peak_thread;
bool AudioSource::have_peak_thread = false;
vector<AudioSource*> AudioSource::pending_peak_sources;
@@ -66,6 +66,7 @@ AudioSource::AudioSource (string name)
AudioSource::AudioSource (const XMLNode& node)
: Source (node)
{
+ cerr << "audiosource from XML\n";
if (pending_peak_sources_lock == 0) {
pending_peak_sources_lock = new Glib::Mutex;
}
@@ -250,18 +251,18 @@ AudioSource::stop_peak_thread ()
}
void
-AudioSource::queue_for_peaks (AudioSource& source)
+AudioSource::queue_for_peaks (AudioSource* source)
{
if (have_peak_thread) {
-
+
Glib::Mutex::Lock lm (*pending_peak_sources_lock);
- source.next_peak_clear_should_notify = true;
+ source->next_peak_clear_should_notify = true;
if (find (pending_peak_sources.begin(),
pending_peak_sources.end(),
- &source) == pending_peak_sources.end()) {
- pending_peak_sources.push_back (&source);
+ source) == pending_peak_sources.end()) {
+ pending_peak_sources.push_back (source);
}
char c = (char) PeakRequest::Build;
@@ -830,7 +831,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 (this);
}
bool
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index 91ed4d7efc..addb92bbca 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -20,6 +20,8 @@
#include <glibmm/thread.h>
+#include <pbd/error.h>
+
#include <ardour/audio_diskstream.h>
#include <ardour/audioregion.h>
#include <ardour/route.h>
@@ -32,6 +34,9 @@
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
+
+#include "i18n.h"
Auditioner::Auditioner (Session& s)
: AudioTrack (s, "auditioner", Route::Hidden)
@@ -100,7 +105,7 @@ Auditioner::audition_current_playlist ()
}
void
-Auditioner::audition_region (boost::shared_ptr<AudioRegion> region)
+Auditioner::audition_region (boost::shared_ptr<Region> region)
{
if (g_atomic_int_get (&_active)) {
/* don't go via session for this, because we are going
@@ -109,6 +114,11 @@ Auditioner::audition_region (boost::shared_ptr<AudioRegion> region)
cancel_audition ();
}
+ if (boost::dynamic_pointer_cast<AudioRegion>(region) == 0) {
+ error << _("Auditioning of non-audio regions not yet supported") << endmsg;
+ return;
+ }
+
Glib::Mutex::Lock lm (lock);
/* copy it */
diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc
index 65ca8dae67..7bf47e84a0 100644
--- a/libs/ardour/destructive_filesource.cc
+++ b/libs/ardour/destructive_filesource.cc
@@ -376,7 +376,7 @@ DestructiveFileSource::write_unlocked (Sample* data, jack_nframes_t cnt)
}
if (_build_peakfiles) {
- queue_for_peaks (*this);
+ queue_for_peaks (this);
}
return cnt;
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index ea532d226a..3f89af312e 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -65,7 +65,7 @@ using namespace PBD;
*/
jack_nframes_t Diskstream::disk_io_chunk_frames = 1024 * 256;
-sigc::signal<void,list<Source*>*> Diskstream::DeleteSources;
+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/import.cc b/libs/ardour/import.cc
index 6c44185fce..dc9819af8e 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -41,6 +41,8 @@
#include <ardour/sndfile_helpers.h>
#include <ardour/audioregion.h>
#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
+
#include "i18n.h"
@@ -53,7 +55,7 @@ int
Session::import_audiofile (import_status& status)
{
SNDFILE *in;
- AudioFileSource **newfiles = 0;
+ vector<boost::shared_ptr<AudioFileSource> > newfiles;
SourceList sources;
SF_INFO info;
float *data = 0;
@@ -95,11 +97,10 @@ Session::import_audiofile (import_status& status)
}
}
- newfiles = new AudioFileSource *[info.channels];
for (n = 0; n < info.channels; ++n) {
- newfiles[n] = 0;
+ newfiles.push_back (boost::shared_ptr<AudioFileSource>());
}
-
+
sounds_dir = discover_best_sound_dir ();
basepath = PBD::basename_nosuffix (status.pathname);
@@ -136,12 +137,8 @@ Session::import_audiofile (import_status& status)
} while ( !goodfile);
-
try {
- newfiles[n] = new SndFileSource (buf,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate ());
+ newfiles[n] = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (buf, false, frame_rate()));
}
catch (failed_constructor& err) {
@@ -234,10 +231,10 @@ Session::import_audiofile (import_status& status)
did not bother to create whole-file AudioRegions for them. Do it now.
*/
- boost::shared_ptr<AudioRegion> r (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (*newfiles[n], 0, newfiles[n]->length(), region_name_from_path (Glib::path_get_basename (newfiles[n]->name())),
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile | AudioRegion::Import))));
-
- status.new_regions.push_back (r);
+ status.new_regions.push_back (boost::dynamic_pointer_cast<AudioRegion>
+ (RegionFactory::create (boost::static_pointer_cast<Source> (newfiles[n]), 0, newfiles[n]->length(),
+ region_name_from_path (Glib::path_get_basename (newfiles[n]->name())),
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile | AudioRegion::Import))));
}
}
@@ -271,10 +268,6 @@ Session::import_audiofile (import_status& status)
}
}
- if (newfiles) {
- delete [] newfiles;
- }
-
if (tmp_convert_file.length()) {
unlink(tmp_convert_file.c_str());
}
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index b8a7a44f58..eca7b67e38 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -511,7 +511,6 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, jack_nframes_t
region->set_playlist (this);
region->set_position (position, this);
- region->lock_sources ();
timestamp_layer_op (region);
diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc
index ffb4441d3e..101b33e811 100644
--- a/libs/ardour/region_factory.cc
+++ b/libs/ardour/region_factory.cc
@@ -39,7 +39,7 @@ RegionFactory::create (boost::shared_ptr<Region> region, jack_nframes_t start,
jack_nframes_t length, std::string name,
layer_t layer, Region::Flag flags, bool announce)
{
- boost::shared_ptr<AudioRegion> other;
+ boost::shared_ptr<const AudioRegion> other;
if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
AudioRegion* ar = new AudioRegion (other, start, length, name, layer, flags);
@@ -75,6 +75,14 @@ RegionFactory::create (boost::shared_ptr<Region> region)
}
boost::shared_ptr<Region>
+RegionFactory::create (boost::shared_ptr<AudioRegion> region, jack_nframes_t start,
+ jack_nframes_t length, std::string name,
+ layer_t layer, Region::Flag flags, bool announce)
+{
+ return create (boost::static_pointer_cast<Region> (region), start, length, name, layer, flags, announce);
+}
+
+boost::shared_ptr<Region>
RegionFactory::create (Session& session, XMLNode& node, bool yn)
{
boost::shared_ptr<Region> r = session.XMLRegionFactory (node, yn);
@@ -107,12 +115,12 @@ RegionFactory::create (SourceList& srcs, const XMLNode& node)
}
boost::shared_ptr<Region>
-RegionFactory::create (Source& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce)
+RegionFactory::create (boost::shared_ptr<Source> src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce)
{
- AudioSource* as;
+ boost::shared_ptr<AudioSource> as;
- if ((as = dynamic_cast<AudioSource*>(&src)) != 0) {
- boost::shared_ptr<Region> ret (new AudioRegion (*as, start, length, name, layer, flags));
+ if ((as = boost::dynamic_pointer_cast<AudioSource>(src)) != 0) {
+ boost::shared_ptr<Region> ret (new AudioRegion (as, start, length, name, layer, flags));
if (announce) {
CheckNewRegion (ret);
}
diff --git a/libs/ardour/reverse.cc b/libs/ardour/reverse.cc
index 4d8dd22aa4..e62821d5e6 100644
--- a/libs/ardour/reverse.cc
+++ b/libs/ardour/reverse.cc
@@ -82,7 +82,7 @@ Reverse::run (boost::shared_ptr<AudioRegion> region)
/* read it in */
- if (region->source (n).read (buf, fpos, to_read) != to_read) {
+ if (region->source (n)->read (buf, fpos, to_read) != to_read) {
goto out;
}
@@ -117,7 +117,6 @@ Reverse::run (boost::shared_ptr<AudioRegion> region)
if (ret) {
for (si = nsrcs.begin(); si != nsrcs.end(); ++si) {
(*si)->mark_for_remove ();
- delete *si;
}
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 21b0cf5fa7..9b8397e467 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -65,6 +65,7 @@
#include <ardour/playlist.h>
#include <ardour/click.h>
#include <ardour/data_type.h>
+#include <ardour/source_factory.h>
#ifdef HAVE_LIBLO
#include <ardour/osc.h>
@@ -272,10 +273,12 @@ Session::Session (AudioEngine &eng,
first_stage_init (fullpath, snapshot_name);
if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
+ cerr << "create failed\n";
throw failed_constructor ();
}
if (second_stage_init (new_session)) {
+ cerr << "2nd state failed\n";
throw failed_constructor ();
}
@@ -475,15 +478,8 @@ Session::~Session ()
{
RCUWriter<DiskstreamList> dwriter (diskstreams);
boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ) {
- DiskstreamList::iterator tmp;
-
- tmp = i;
- ++tmp;
-
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->drop_references ();
-
- i = tmp;
}
dsl->clear ();
}
@@ -498,11 +494,13 @@ Session::~Session ()
tmp = i;
++tmp;
- delete i->second;
+ i->second->drop_references ();
i = tmp;
}
+ audio_sources.clear ();
+
#ifdef TRACK_DESTRUCTION
cerr << "delete mix groups\n";
#endif /* TRACK_DESTRUCTION */
@@ -2649,25 +2647,27 @@ Session::destroy_region (boost::shared_ptr<Region> region)
if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
return 0;
}
-
+
if (aregion->playlist()) {
aregion->playlist()->destroy_region (region);
}
- vector<Source*> srcs;
+ vector<boost::shared_ptr<Source> > srcs;
for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
- srcs.push_back (&aregion->source (n));
+ srcs.push_back (aregion->source (n));
}
- for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
+ for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
- if ((*i)->use_cnt() == 0) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
+ if ((*i).use_count() == 1) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
+
if (afs) {
(afs)->mark_for_remove ();
}
- delete *i;
+
+ (*i)->drop_references ();
}
}
@@ -2713,54 +2713,76 @@ Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
/* Source Management */
void
-Session::add_audio_source (AudioSource* source)
+Session::add_source (boost::shared_ptr<Source> source)
{
- pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
+ boost::shared_ptr<AudioFileSource> afs;
+
+ cerr << "add new source " << source->name() << endl;
+
+ if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
+
+ pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
+ pair<AudioSourceList::iterator,bool> result;
- {
- Glib::Mutex::Lock lm (audio_source_lock);
entry.first = source->id();
- entry.second = source;
- audio_sources.insert (entry);
- }
-
- source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), source));
- set_dirty();
-
- SourceAdded (source); /* EMIT SIGNAL */
+ entry.second = afs;
+
+ {
+ Glib::Mutex::Lock lm (audio_source_lock);
+ result = audio_sources.insert (entry);
+ }
+
+ if (!result.second) {
+ cerr << "\tNOT inserted ? " << result.second << endl;
+ }
+
+ source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
+ set_dirty();
+
+ SourceAdded (source); /* EMIT SIGNAL */
+ } else {
+ cerr << "\tNOT AUDIO FILE\n";
+ }
}
void
-Session::remove_source (Source* source)
+Session::remove_source (boost::weak_ptr<Source> src)
{
AudioSourceList::iterator i;
+ boost::shared_ptr<Source> source = src.lock();
- {
- Glib::Mutex::Lock lm (audio_source_lock);
-
- if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
- audio_sources.erase (i);
- }
- }
-
- if (!_state_of_the_state & InCleanup) {
-
- /* save state so we don't end up with a session file
- referring to non-existent sources.
- */
+ if (!source) {
+ cerr << "removing a source DEAD\n";
+ } else {
+ cerr << "removing a source " << source->name () << endl;
- save_state (_current_snapshot_name);
+ {
+ Glib::Mutex::Lock lm (audio_source_lock);
+
+ if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
+ audio_sources.erase (i);
+ }
+ }
+
+ 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);
+ }
+
+ SourceRemoved(source); /* EMIT SIGNAL */
}
-
- SourceRemoved(source); /* EMIT SIGNAL */
}
-Source *
+boost::shared_ptr<Source>
Session::source_by_id (const PBD::ID& id)
{
Glib::Mutex::Lock lm (audio_source_lock);
AudioSourceList::iterator i;
- Source* source = 0;
+ boost::shared_ptr<Source> source;
if ((i = audio_sources.find (id)) != audio_sources.end()) {
source = i->second;
@@ -3006,24 +3028,11 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
return spath;
}
-AudioFileSource *
+boost::shared_ptr<AudioFileSource>
Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
{
string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
-
- /* this might throw failed_constructor(), which is OK */
-
- if (destructive) {
- return new DestructiveFileSource (spath,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate());
- } else {
- return new SndFileSource (spath,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate());
- }
+ return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (spath, destructive, frame_rate()));
}
/* Playlist management */
@@ -3129,7 +3138,7 @@ Session::remove_playlist (Playlist* playlist)
}
void
-Session::set_audition (boost::shared_ptr<AudioRegion> r)
+Session::set_audition (boost::shared_ptr<Region> r)
{
pending_audition_region = r;
post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
@@ -3137,42 +3146,39 @@ Session::set_audition (boost::shared_ptr<AudioRegion> r)
}
void
+Session::audition_playlist ()
+{
+ Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
+ ev->region.reset ();
+ queue_event (ev);
+}
+
+void
Session::non_realtime_set_audition ()
{
- if (pending_audition_region.get() == (AudioRegion*) 0xfeedface) {
+ if (!pending_audition_region) {
auditioner->audition_current_playlist ();
- } else if (pending_audition_region) {
+ } else {
auditioner->audition_region (pending_audition_region);
+ pending_audition_region.reset ();
}
- pending_audition_region.reset ((AudioRegion*) 0);
AuditionActive (true); /* EMIT SIGNAL */
}
void
-Session::audition_playlist ()
+Session::audition_region (boost::shared_ptr<Region> r)
{
Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
- ev->set_ptr ((void*) 0xfeedface);
+ ev->region = r;
queue_event (ev);
}
void
-Session::audition_region (boost::shared_ptr<Region> r)
-{
- boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
- if (ar) {
- Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
- // ev->set_ptr (ar); // AUDFIX
- queue_event (ev);
- }
-}
-
-void
Session::cancel_audition ()
{
if (auditioner->active()) {
auditioner->cancel_audition ();
- AuditionActive (false); /* EMIT SIGNAL */
+ AuditionActive (false); /* EMIT SIGNAL */
}
}
@@ -3583,9 +3589,9 @@ Session::route_name_unique (string n) const
}
int
-Session::cleanup_audio_file_source (AudioFileSource& fs)
+Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
{
- return fs.move_to_trash (dead_sound_dir_name);
+ return fs->move_to_trash (dead_sound_dir_name);
}
uint32_t
@@ -3652,11 +3658,11 @@ Session::freeze (InterThreadInfo& itt)
int
Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
- bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
+ bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
{
int ret = -1;
Playlist* playlist;
- AudioFileSource* fsource;
+ boost::shared_ptr<AudioFileSource> fsource;
uint32_t x;
char buf[PATH_MAX+1];
string dir;
@@ -3702,11 +3708,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
}
try {
- fsource = new SndFileSource (buf,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate());
-
+ fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (buf, false, frame_rate()));
}
catch (failed_constructor& err) {
@@ -3714,7 +3716,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
goto out;
}
- srcs.push_back(fsource);
+ srcs.push_back (fsource);
}
/* XXX need to flush all redirects */
@@ -3743,9 +3745,9 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
}
uint32_t n = 0;
- for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
-
+ for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
+
if (afs) {
if (afs->write (buffers[n], this_chunk) != this_chunk) {
goto out;
@@ -3767,8 +3769,9 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
time (&now);
xnow = localtime (&now);
- for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+ for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
+
if (afs) {
afs->update_header (position, *xnow, now);
}
@@ -3776,8 +3779,8 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
/* build peakfile for new source */
- for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+ for (vector<boost::shared_ptr<AudioSource> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
if (afs) {
afs->build_peaks ();
}
@@ -3788,12 +3791,14 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
out:
if (ret) {
- for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+ for (vector<boost::shared_ptr<AudioSource> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
+
if (afs) {
afs->mark_for_remove ();
}
- delete *src;
+
+ (*src)->drop_references ();
}
}
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index 5d691a7425..832284901c 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -187,7 +187,7 @@ Session::butler_thread_work ()
}
if (pfd[0].revents & ~POLLIN) {
- error << _("Error on butler thread request pipe") << endmsg;
+ error << string_compose (_("Error on butler thread request pipe: fd=%1 err=%2"), pfd[0].fd, pfd[0].revents) << endmsg;
break;
}
diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc
index 1e7a2a41ba..371b570069 100644
--- a/libs/ardour/session_events.cc
+++ b/libs/ardour/session_events.cc
@@ -401,7 +401,7 @@ Session::process_event (Event* ev)
break;
case Event::Audition:
- // set_audition (static_cast<AudioRegion*> (ev->ptr)); AUDFIX
+ set_audition (ev->region);
break;
case Event::InputConfigurationChange:
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 3df43157ea..48f6796165 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -82,6 +82,7 @@
#include <ardour/crossfade.h>
#include <ardour/control_protocol_manager.h>
#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
#include "i18n.h"
#include <locale.h>
@@ -262,7 +263,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
/* These are all static "per-class" signals */
RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
- AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
+ SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
@@ -288,6 +289,7 @@ Session::second_stage_init (bool new_session)
if (!new_session) {
if (load_state (_current_snapshot_name)) {
+ cerr << "load state failed\n";
return -1;
}
remove_empty_sounds ();
@@ -1349,10 +1351,10 @@ Session::state(bool full_state)
/* Don't save information about AudioFileSources that are empty */
- AudioFileSource* fs;
+ boost::shared_ptr<AudioFileSource> fs;
- if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) {
- DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
+ if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
+ boost::shared_ptr<DestructiveFileSource> dfs = boost::dynamic_pointer_cast<DestructiveFileSource> (fs);
/* destructive file sources are OK if they are empty, because
we will re-use them every time.
@@ -1771,8 +1773,8 @@ boost::shared_ptr<AudioRegion>
Session::XMLRegionFactory (const XMLNode& node, bool full)
{
const XMLProperty* prop;
- Source* source;
- AudioSource* as;
+ boost::shared_ptr<Source> source;
+ boost::shared_ptr<AudioSource> as;
SourceList sources;
uint32_t nchans = 1;
char buf[128];
@@ -1799,8 +1801,8 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
return boost::shared_ptr<AudioRegion>();
}
-
- as = dynamic_cast<AudioSource*>(source);
+
+ as = boost::dynamic_pointer_cast<AudioSource>(source);
if (!as) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
return boost::shared_ptr<AudioRegion>();
@@ -1821,7 +1823,7 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
return boost::shared_ptr<AudioRegion>();
}
- as = dynamic_cast<AudioSource*>(source);
+ as = boost::dynamic_pointer_cast<AudioSource>(source);
if (!as) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
return boost::shared_ptr<AudioRegion>();
@@ -1885,7 +1887,7 @@ Session::load_sources (const XMLNode& node)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
- Source* source;
+ boost::shared_ptr<Source> source;
nlist = node.children();
@@ -1901,25 +1903,22 @@ Session::load_sources (const XMLNode& node)
return 0;
}
-Source *
+boost::shared_ptr<Source>
Session::XMLSourceFactory (const XMLNode& node)
{
- Source *src = 0;
if (node.name() != "Source") {
- return 0;
+ return boost::shared_ptr<Source>();
}
try {
- src = AudioFileSource::create (node);
+ return SourceFactory::create (node);
}
catch (failed_constructor& err) {
error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
- return 0;
+ return boost::shared_ptr<Source>();
}
-
- return src;
}
int
@@ -2886,7 +2885,7 @@ Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_th
int
Session::cleanup_sources (Session::cleanup_report& rep)
{
- vector<Source*> dead_sources;
+ vector<boost::shared_ptr<Source> > dead_sources;
vector<Playlist*> playlists_tbd;
PathScanner scanner;
string sound_path;
@@ -2958,7 +2957,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
capture files.
*/
- if (i->second->use_cnt() == 0 && i->second->length() > 0) {
+ if (i->second.use_count() == 1 && i->second->length() > 0) {
dead_sources.push_back (i->second);
/* remove this source from our own list to avoid us
@@ -2976,7 +2975,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
other snapshots).
*/
- for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
+ for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
AudioRegionList::iterator tmp;
@@ -2988,7 +2987,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
ar = r->second;
for (uint32_t n = 0; n < ar->n_channels(); ++n) {
- if (&ar->source (n) == (*i)) {
+ if (ar->source (n) == (*i)) {
/* this region is dead */
remove_region (ar);
}
@@ -3036,9 +3035,9 @@ Session::cleanup_sources (Session::cleanup_report& rep)
*/
for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
- AudioFileSource* fs;
+ boost::shared_ptr<AudioFileSource> fs;
- if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
+ if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
all_sources.insert (fs->path());
}
}
diff --git a/libs/ardour/session_timefx.cc b/libs/ardour/session_timefx.cc
index 2b6b45dad0..dc00cf499c 100644
--- a/libs/ardour/session_timefx.cc
+++ b/libs/ardour/session_timefx.cc
@@ -29,6 +29,7 @@
#include <ardour/audioregion.h>
#include <ardour/sndfilesource.h>
#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
#include "i18n.h"
@@ -81,10 +82,8 @@ Session::tempoize_region (TimeStretchRequest& tsr)
}
try {
- sources.push_back (new SndFileSource (path,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate()));
+ sources.push_back (boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (path, false, frame_rate())));
+
} catch (failed_constructor& err) {
error << string_compose (_("tempoize: error creating new audio file %1 (%2)"), path, strerror (errno)) << endmsg;
goto out;
@@ -153,7 +152,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
xnow = localtime (&now);
for (it = sources.begin(); it != sources.end(); ++it) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*it);
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*it);
if (afs) {
afs->update_header (tsr.region->position(), *xnow, now);
}
@@ -175,9 +174,10 @@ Session::tempoize_region (TimeStretchRequest& tsr)
if ((!r || !tsr.running)) {
for (it = sources.begin(); it != sources.end(); ++it) {
(*it)->mark_for_remove ();
- delete *it;
}
}
+
+ sources.clear ();
}
/* if the process was cancelled, delete the region */
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index f67d61472f..699522c2ad 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -50,8 +50,6 @@ SndFileSource::SndFileSource (const XMLNode& node)
throw failed_constructor ();
}
}
-
- AudioSourceCreated (this); /* EMIT SIGNAL */
}
SndFileSource::SndFileSource (string idstr, Flag flags)
@@ -71,9 +69,6 @@ SndFileSource::SndFileSource (string idstr, Flag flags)
throw failed_constructor ();
}
}
-
-
- AudioSourceCreated (this); /* EMIT SIGNAL */
}
SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, jack_nframes_t rate, Flag flags)
@@ -183,9 +178,6 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf,
throw failed_constructor ();
}
}
-
- AudioSourceCreated (this); /* EMIT SIGNAL */
-
}
void
@@ -413,7 +405,7 @@ SndFileSource::write_unlocked (Sample *data, jack_nframes_t cnt)
if (_build_peakfiles) {
- queue_for_peaks (*this);
+ queue_for_peaks (this);
}
_write_data_count = cnt;
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index eebc64d463..ad0d0f8a13 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -45,13 +45,11 @@ using namespace ARDOUR;
Source::Source (string name)
{
_name = name;
- _use_cnt = 0;
_timestamp = 0;
}
Source::Source (const XMLNode& node)
{
- _use_cnt = 0;
_timestamp = 0;
if (set_state (node)) {
@@ -61,6 +59,7 @@ Source::Source (const XMLNode& node)
Source::~Source ()
{
+ notify_callbacks ();
}
XMLNode&
@@ -105,15 +104,3 @@ Source::set_state (const XMLNode& node)
return 0;
}
-void
-Source::use ()
-{
- _use_cnt++;
-}
-
-void
-Source::release ()
-{
- if (_use_cnt) --_use_cnt;
-}
-
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
new file mode 100644
index 0000000000..8432bcbd6f
--- /dev/null
+++ b/libs/ardour/source_factory.cc
@@ -0,0 +1,155 @@
+/*
+ Copyright (C) 2000-2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#include <ardour/source_factory.h>
+#include <ardour/sndfilesource.h>
+#include <ardour/destructive_filesource.h>
+#include <ardour/configuration.h>
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace std;
+
+sigc::signal<void,boost::shared_ptr<Source> > SourceFactory::SourceCreated;
+
+#ifdef HAVE_COREAUDIO
+
+
+boost::shared_ptr<Source>
+SourceFactory::create (const XMLNode& node)
+{
+ if (node.property (X_("destructive")) != 0) {
+
+ boost::shared_ptr<Source> ret (new DestructiveFileSource (node));
+ SourceCreated (ret);
+ return ret;
+
+ } else {
+
+ try {
+ boost::shared_ptr<Source> ret (new CoreAudioSource (node));
+ SourceCreated (ret);
+ return ret;
+ }
+
+
+ catch (failed_constructor& err) {
+ boost::shared_ptr<Source> ret (new SndFileSource (node));
+ SourceCreated (ret);
+ return ret;
+ }
+ }
+
+ return boost::shared_ptr<Source>();
+}
+
+#else
+
+boost::shared_ptr<Source>
+SourceFactory::create (const XMLNode& node)
+{
+ if (node.property (X_("destructive")) != 0) {
+
+ boost::shared_ptr<Source> ret (new DestructiveFileSource (node));
+ SourceCreated (ret);
+ return ret;
+
+ } else {
+
+ boost::shared_ptr<Source> ret (new SndFileSource (node));
+ SourceCreated (ret);
+ return ret;
+ }
+}
+
+#endif // HAVE_COREAUDIO
+
+#ifdef HAVE_COREAUDIO
+boost::shared_ptr<Source>
+SourceFactory::createReadable (string idstr, AudioFileSource::Flag flags, bool announce)
+{
+ if (flags & Destructive) {
+ boost::shared_ptr<Source> ret (new DestructiveFileSource (idstr, flags));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+ }
+
+ try {
+ boost::shared_ptr<Source> ret (new CoreAudioSource (idstr, flags));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+ }
+
+ catch (failed_constructor& err) {
+ boost::shared_ptr<Source> ret (new SndFileSource (idstr, flags));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+ }
+
+ return boost::shared_ptr<Source>();
+}
+
+#else
+
+boost::shared_ptr<Source>
+SourceFactory::createReadable (string idstr, AudioFileSource::Flag flags, bool announce)
+{
+ boost::shared_ptr<Source> ret (new SndFileSource (idstr, flags));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+}
+
+#endif // HAVE_COREAUDIO
+
+boost::shared_ptr<Source>
+SourceFactory::createWritable (std::string path, bool destructive, jack_nframes_t rate, bool announce)
+{
+ /* this might throw failed_constructor(), which is OK */
+
+ if (destructive) {
+ boost::shared_ptr<Source> ret (new DestructiveFileSource (path,
+ Config->get_native_file_data_format(),
+ Config->get_native_file_header_format(),
+ rate));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+
+ } else {
+ boost::shared_ptr<Source> ret (new SndFileSource (path,
+ Config->get_native_file_data_format(),
+ Config->get_native_file_header_format(),
+ rate));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+ }
+}