summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/audiosource.h2
-rw-r--r--libs/ardour/ardour/diskstream.h4
-rw-r--r--libs/ardour/ardour/midi_diskstream.h6
-rw-r--r--libs/ardour/ardour/midi_source.h6
-rw-r--r--libs/ardour/ardour/midi_track.h4
-rw-r--r--libs/ardour/ardour/playlist.h10
-rw-r--r--libs/ardour/ardour/region.h10
-rw-r--r--libs/ardour/ardour/session.h24
-rw-r--r--libs/ardour/ardour/session_region.h4
-rw-r--r--libs/ardour/ardour/smf_source.h10
-rw-r--r--libs/ardour/ardour/source.h5
-rw-r--r--libs/ardour/ardour/track.h2
-rw-r--r--libs/ardour/audio_diskstream.cc3
-rw-r--r--libs/ardour/audio_playlist.cc7
-rw-r--r--libs/ardour/audioregion.cc10
-rw-r--r--libs/ardour/audiosource.cc3
-rw-r--r--libs/ardour/buffer.cc4
-rw-r--r--libs/ardour/coreaudiosource.cc4
-rw-r--r--libs/ardour/import.cc2
-rw-r--r--libs/ardour/midi_diskstream.cc357
-rw-r--r--libs/ardour/midi_playlist.cc23
-rw-r--r--libs/ardour/midi_region.cc12
-rw-r--r--libs/ardour/midi_source.cc2
-rw-r--r--libs/ardour/midi_track.cc144
-rw-r--r--libs/ardour/playlist.cc16
-rw-r--r--libs/ardour/region.cc21
-rw-r--r--libs/ardour/session.cc160
-rw-r--r--libs/ardour/session_state.cc172
-rw-r--r--libs/ardour/smf_source.cc10
-rw-r--r--libs/ardour/sndfilesource.cc6
-rw-r--r--libs/ardour/source.cc14
31 files changed, 714 insertions, 343 deletions
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index 4af857c1d6..c3c2f9bb9a 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -70,8 +70,6 @@ class AudioSource : public Source
int read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_unit) const;
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;
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index c4e85c00ce..fa1126901d 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -238,8 +238,8 @@ class Diskstream : public Stateful, public sigc::trackable
virtual void get_input_sources () = 0;
virtual void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record) = 0;
virtual void set_align_style_from_io() {}
- virtual void setup_destructive_playlist () = 0;
- virtual void use_destructive_playlist () = 0;
+ virtual void setup_destructive_playlist () {}
+ virtual void use_destructive_playlist () {}
static jack_nframes_t disk_io_chunk_frames;
vector<CaptureInfo*> capture_info;
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index a048cf4021..8085e6509a 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -83,6 +83,10 @@ class MidiDiskstream : public Diskstream
void monitor_input (bool);
+ MidiSource* write_source() { return (MidiSource*)_write_source; }
+
+ void set_destructive (bool yn); // doom!
+
protected:
friend class Session;
@@ -138,8 +142,6 @@ class MidiDiskstream : public Diskstream
void get_input_sources ();
void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record);
void set_align_style_from_io();
- void setup_destructive_playlist ();
- void use_destructive_playlist ();
void engage_record_enable ();
void disengage_record_enable ();
diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h
index 1c00289003..d4fec52609 100644
--- a/libs/ardour/ardour/midi_source.h
+++ b/libs/ardour/ardour/midi_source.h
@@ -59,8 +59,10 @@ class MidiSource : public Source
static sigc::signal<void,MidiSource*> MidiSourceCreated;
- mutable sigc::signal<void> PeaksReady;
- mutable sigc::signal<void,jack_nframes_t,jack_nframes_t> PeakRangeReady;
+ // The MIDI equivalent to "peaks"
+ static int start_view_data_thread ();
+ static void stop_view_data_thread ();
+ mutable sigc::signal<void,jack_nframes_t,jack_nframes_t> ViewDataRangeReady;
XMLNode& get_state ();
int set_state (const XMLNode&);
diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h
index 9274cfbcf6..654eb98e30 100644
--- a/libs/ardour/ardour/midi_track.h
+++ b/libs/ardour/ardour/midi_track.h
@@ -53,8 +53,6 @@ public:
jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick,
bool meter);
- void set_record_enable (bool yn, void *src);
-
MidiDiskstream& midi_diskstream() const;
int use_diskstream (string name);
@@ -75,8 +73,6 @@ public:
int set_state(const XMLNode& node);
- bool record_enabled() const;
-
protected:
XMLNode& state (bool full);
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index b389258860..59fd0f8bc5 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -39,6 +39,7 @@
#include <ardour/crossfade_compare.h>
#include <ardour/location.h>
#include <ardour/state_manager.h>
+#include <ardour/data_type.h>
namespace ARDOUR {
@@ -49,8 +50,8 @@ class Playlist : public Stateful, public StateManager {
public:
typedef list<Region*> RegionList;
- Playlist (Session&, const XMLNode&, bool hidden = false);
- Playlist (Session&, string name, bool hidden = false);
+ Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
+ Playlist (Session&, string name, DataType type, bool hidden = false);
Playlist (const Playlist&, string name, bool hidden = false);
Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
@@ -65,6 +66,8 @@ class Playlist : public Stateful, public StateManager {
const string& name() const { return _name; }
void set_name (const string& str);
+ const DataType& data_type() const { return _type; }
+
bool frozen() const { return _frozen; }
void set_frozen (bool yn);
@@ -171,6 +174,7 @@ class Playlist : public Stateful, public StateManager {
RegionList regions;
string _name;
Session& _session;
+ DataType _type;
mutable gint block_notifications;
mutable gint ignore_state_changes;
mutable Glib::Mutex region_lock;
@@ -275,7 +279,7 @@ class Playlist : public Stateful, public StateManager {
void timestamp_layer_op (Region&);
- PBD::ID _id;
+ PBD::ID _id;
};
} /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index c0ff8be607..80504ce044 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -27,6 +27,7 @@
#include <ardour/ardour.h>
#include <ardour/state_manager.h>
+#include <ardour/data_type.h>
class XMLNode;
@@ -94,9 +95,9 @@ class Region : public Stateful, public StateManager
static Change HiddenChanged;
Region (Source& src, jack_nframes_t start, jack_nframes_t length,
- const string& name, layer_t = 0, Flag flags = DefaultFlags);
+ const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length,
- const string& name, layer_t = 0, Flag flags = DefaultFlags);
+ const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
Region (const Region&, jack_nframes_t start, jack_nframes_t length,
const string& name, layer_t = 0, Flag flags = DefaultFlags);
Region (const Region&);
@@ -111,6 +112,8 @@ class Region : public Stateful, public StateManager
string name() const { return _name; }
void set_name (string str);
+ const DataType& data_type() const { return _type; }
+
jack_nframes_t position () const { return _position; }
jack_nframes_t start () const { return _start; }
jack_nframes_t length() const { return _length; }
@@ -251,7 +254,8 @@ class Region : public Stateful, public StateManager
PBD::ID _id;
- string _name;
+ string _name;
+ DataType _type;
Flag _flags;
jack_nframes_t _start;
jack_nframes_t _length;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index a9b8cbf290..2737d86a3f 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -632,8 +632,8 @@ class Session : public sigc::trackable, public Stateful
/* region info */
- sigc::signal<void,AudioRegion *> AudioRegionAdded;
- sigc::signal<void,AudioRegion *> AudioRegionRemoved;
+ sigc::signal<void,Region *> RegionAdded;
+ sigc::signal<void,Region *> RegionRemoved;
int region_name (string& result, string base = string(""), bool newlevel = false) const;
string new_region_name (string);
@@ -642,9 +642,11 @@ class Session : public sigc::trackable, public Stateful
Region* find_whole_file_parent (Region& child);
void find_equivalent_playlist_regions (Region&, std::vector<Region*>& result);
- AudioRegion *XMLRegionFactory (const XMLNode&, bool full);
+ Region* XMLRegionFactory (const XMLNode&, bool full);
+ AudioRegion* XMLAudioRegionFactory (const XMLNode&, bool full);
+ MidiRegion* XMLMidiRegionFactory (const XMLNode&, bool full);
- template<class T> void foreach_audio_region (T *obj, void (T::*func)(AudioRegion *));
+ template<class T> void foreach_region (T *obj, void (T::*func)(Region *));
/* source management */
@@ -658,7 +660,7 @@ class Session : public sigc::trackable, public Stateful
string pathname;
/* result */
- std::vector<AudioRegion*> new_regions;
+ std::vector<Region*> new_regions;
};
@@ -672,7 +674,7 @@ class Session : public sigc::trackable, public Stateful
int start_audio_export (ARDOUR::AudioExportSpecification&);
int stop_audio_export (ARDOUR::AudioExportSpecification&);
- void add_audio_source (AudioSource *);
+ void add_source (Source *);
void remove_source (Source *);
int cleanup_audio_file_source (AudioFileSource&);
@@ -1551,8 +1553,8 @@ class Session : public sigc::trackable, public Stateful
/* REGION MANAGEMENT */
mutable Glib::Mutex region_lock;
- typedef map<PBD::ID,AudioRegion *> AudioRegionList;
- AudioRegionList audio_regions;
+ typedef map<PBD::ID,Region *> RegionList;
+ RegionList regions;
void region_renamed (Region *);
void region_changed (Change, Region *);
@@ -1563,10 +1565,10 @@ class Session : public sigc::trackable, public Stateful
/* SOURCES */
- mutable Glib::Mutex audio_source_lock;
- typedef std::map<PBD::ID,AudioSource *> AudioSourceList;
+ mutable Glib::Mutex source_lock;
+ typedef std::map<PBD::ID,Source *> SourceList;
- AudioSourceList audio_sources;
+ SourceList sources;
int load_sources (const XMLNode& node);
XMLNode& get_sources_as_xml ();
diff --git a/libs/ardour/ardour/session_region.h b/libs/ardour/ardour/session_region.h
index 4f0fb92e3b..fae950baa6 100644
--- a/libs/ardour/ardour/session_region.h
+++ b/libs/ardour/ardour/session_region.h
@@ -6,10 +6,10 @@
namespace ARDOUR {
-template<class T> void Session::foreach_audio_region (T *obj, void (T::*func)(AudioRegion *))
+template<class T> void Session::foreach_region (T *obj, void (T::*func)(Region *))
{
Glib::Mutex::Lock lm (region_lock);
- for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); i++) {
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) {
(obj->*func) (i->second);
}
}
diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h
index 83bc47d7d3..abb52456e3 100644
--- a/libs/ardour/ardour/smf_source.h
+++ b/libs/ardour/ardour/smf_source.h
@@ -48,6 +48,16 @@ class SMFSource : public MidiSource {
virtual ~SMFSource ();
+ /* this block of methods do nothing for regular file sources, but are significant
+ for files used in destructive recording.
+ */
+ // FIXME and thus are useless for MIDI.. but make MidiDiskstream compile easier! :)
+
+ virtual jack_nframes_t last_capture_start_frame() const { return 0; }
+ virtual void mark_capture_start (jack_nframes_t) {}
+ virtual void mark_capture_end () {}
+ virtual void clear_capture_marks() {}
+
int set_name (string newname, bool destructive);
string path() const { return _path; }
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index dc1e93f8f2..a8d0fed20b 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -28,13 +28,14 @@
#include <pbd/stateful.h>
#include <ardour/ardour.h>
+#include <ardour/data_type.h>
namespace ARDOUR {
class Source : public Stateful, public sigc::trackable
{
public:
- Source (std::string name);
+ Source (std::string name, DataType type);
Source (const XMLNode&);
virtual ~Source ();
@@ -60,12 +61,14 @@ class Source : public Stateful, public sigc::trackable
XMLNode& get_state ();
int set_state (const XMLNode&);
+ static sigc::signal<void,Source*> SourceCreated;
sigc::signal<void,Source *> GoingAway;
protected:
void update_length (jack_nframes_t pos, jack_nframes_t cnt);
string _name;
+ DataType _type;
uint32_t _use_cnt;
time_t _timestamp;
jack_nframes_t _length;
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index 4fc7cf4326..15a0a28aab 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -48,7 +48,7 @@ class Track : public Route
void toggle_monitor_input ();
- virtual bool can_record();
+ bool can_record();
Diskstream& diskstream() const { return *_diskstream; }
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 6973ebd877..784a14bb2b 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -280,7 +280,8 @@ AudioDiskstream::get_input_sources ()
chan.source = 0;
} else {
- chan.source = _session.engine().get_port_by_name (connections[0]);
+ chan.source = dynamic_cast<AudioPort*>(
+ _session.engine().get_port_by_name (connections[0]) );
}
if (connections) {
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 328c9b25f5..b621e587e9 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -44,8 +44,11 @@ AudioPlaylist::State::~State ()
}
AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden)
- : Playlist (session, node, hidden)
+ : Playlist (session, node, DataType::AUDIO, hidden)
{
+ const XMLProperty* prop = node.property("type");
+ assert(!prop || DataType(prop->value()) == DataType::AUDIO);
+
in_set_state = true;
set_state (node);
in_set_state = false;
@@ -58,7 +61,7 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden
}
AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
- : Playlist (session, name, hidden)
+ : Playlist (session, name, DataType::AUDIO, hidden)
{
save_state (_("initial state"));
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 6b810c04ec..052049cda7 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -66,7 +66,7 @@ AudioRegionState::AudioRegionState (string why)
/** Basic AudioRegion constructor (one channel) */
AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, bool announce)
- : Region (src, start, length, PBD::basename_nosuffix(src.name()), 0, Region::Flag(Region::DefaultFlags|Region::External))
+ : Region (src, start, length, PBD::basename_nosuffix(src.name()), DataType::AUDIO, 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)
@@ -87,7 +87,7 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
/* Basic AudioRegion constructor (one channel) */
AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
- : Region (src, start, length, name, layer, flags)
+ : Region (src, start, length, name, DataType::AUDIO, layer, flags)
, _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)
@@ -107,7 +107,7 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
/* Basic AudioRegion constructor (many channels) */
AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
- : Region (srcs, start, length, name, layer, flags)
+ : Region (srcs, start, length, name, DataType::AUDIO, layer, flags)
, _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)
@@ -204,6 +204,8 @@ AudioRegion::AudioRegion (AudioSource& src, const XMLNode& node)
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
+ assert(_type == DataType::AUDIO);
+
CheckNewRegion (this); /* EMIT SIGNAL */
}
@@ -224,6 +226,8 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
+ assert(_type == DataType::AUDIO);
+
CheckNewRegion (this); /* EMIT SIGNAL */
}
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index bf97ef848a..9620565ae2 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -40,7 +40,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;
@@ -51,7 +50,7 @@ bool AudioSource::_build_missing_peakfiles = false;
bool AudioSource::_build_peakfiles = false;
AudioSource::AudioSource (string name)
- : Source (name)
+ : Source (name, DataType::AUDIO)
{
if (pending_peak_sources_lock == 0) {
pending_peak_sources_lock = new Glib::Mutex;
diff --git a/libs/ardour/buffer.cc b/libs/ardour/buffer.cc
index 85b9317f78..fa4669cef6 100644
--- a/libs/ardour/buffer.cc
+++ b/libs/ardour/buffer.cc
@@ -101,8 +101,8 @@ MidiBuffer::read_from(const Buffer& src, jack_nframes_t nframes, jack_nframes_t
}
assert(_size == msrc.size());
- if (_size > 0)
- std::cerr << "MidiBuffer wrote " << _size << " events.\n";
+ //if (_size > 0)
+ // std::cerr << "MidiBuffer wrote " << _size << " events.\n";
}
diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc
index f0fcac14e2..d2a9a8c8e6 100644
--- a/libs/ardour/coreaudiosource.cc
+++ b/libs/ardour/coreaudiosource.cc
@@ -32,7 +32,7 @@ CoreAudioSource::CoreAudioSource (const XMLNode& node)
{
init (_name);
- AudioSourceCreated (this); /* EMIT SIGNAL */
+ SourceCreated (this); /* EMIT SIGNAL */
}
CoreAudioSource::CoreAudioSource (const string& idstr, Flag flags)
@@ -40,7 +40,7 @@ CoreAudioSource::CoreAudioSource (const string& idstr, Flag flags)
{
init (idstr);
- AudioSourceCreated (this); /* EMIT SIGNAL */
+ SourceCreated (this); /* EMIT SIGNAL */
}
void
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index c68eb16aae..6d98388941 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -262,7 +262,7 @@ Session::import_audiofile (import_status& status)
}
if (status.cancel) {
- for (vector<AudioRegion *>::iterator i = status.new_regions.begin(); i != status.new_regions.end(); ++i) {
+ for (vector<Region *>::iterator i = status.new_regions.begin(); i != status.new_regions.end(); ++i) {
delete *i;
}
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index 948afd149b..2c88d5daa8 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -35,6 +35,7 @@
#include <pbd/basename.h>
#include <glibmm/thread.h>
#include <pbd/xml++.h>
+#include <pbd/memento_command.h>
#include <ardour/ardour.h>
#include <ardour/audioengine.h>
@@ -77,6 +78,7 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F
in_set_state = false;
+ assert(!destructive());
DiskstreamCreated (this); /* EMIT SIGNAL */
}
@@ -129,6 +131,8 @@ MidiDiskstream::init (Diskstream::Flag f)
_capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
_n_channels = ChanCount(DataType::MIDI, 1);
+
+ assert(recordable());
}
MidiDiskstream::~MidiDiskstream ()
@@ -181,20 +185,18 @@ MidiDiskstream::non_realtime_input_change ()
void
MidiDiskstream::get_input_sources ()
{
-#if 0
- if (_io->n_inputs() == 0) {
- cerr << "MidiDiskstream NO INPUTS?\n";
+ uint32_t ni = _io->n_inputs().get(DataType::MIDI);
+
+ if (ni == 0) {
return;
- } else {
- cerr << "INPUTS!\n";
}
- // FIXME this is weird and really different from AudioDiskstream
-
- assert(_io->n_inputs() == 1);
- assert(_io->midi_input(0));
+ // This is all we do for now at least
+ assert(ni == 1);
+
_source_port = _io->midi_input(0);
+ /* I don't get it....
const char **connections = _io->input(0)->get_connections ();
if (connections == 0 || connections[0] == 0) {
@@ -207,20 +209,12 @@ MidiDiskstream::get_input_sources ()
} else {
_source_port = dynamic_cast<MidiPort*>(
- _session.engine().get_port_by_name (connections[0]));
- assert(_source_port);
- }
-
- if (_source_port) {
- cerr << "SOURCE PORT!\n";
- } else {
- cerr << "NO SOURCE PORT?!\n";
+ _session.engine().get_port_by_name (connections[0]) );
}
if (connections) {
free (connections);
- }
-#endif
+ }*/
}
int
@@ -299,46 +293,13 @@ MidiDiskstream::use_copy_playlist ()
}
}
+/** Overloaded from parent to die horribly
+ */
void
-MidiDiskstream::setup_destructive_playlist ()
+MidiDiskstream::set_destructive (bool yn)
{
- Region::SourceList srcs;
-
- srcs.push_back (_write_source);
- /* a single full-sized region */
-
- cerr << "Setup MIDI DS using " << srcs.front()->natural_position () << endl;
-
- MidiRegion* region = new MidiRegion (srcs, 0, max_frames, _name);
- _playlist->add_region (*region, srcs.front()->natural_position());
-}
-
-void
-MidiDiskstream::use_destructive_playlist ()
-{
- /* use the sources associated with the single full-extent region */
-
- Playlist::RegionList* rl = _playlist->regions_at (0);
-
- if (rl->empty()) {
- reset_write_sources (false, true);
- return;
- }
-
- MidiRegion* region = dynamic_cast<MidiRegion*> (rl->front());
-
- if (region == 0) {
- throw failed_constructor();
- }
-
- delete rl;
-
- assert(region->n_channels() == 1);
- _write_source = dynamic_cast<SMFSource*>(&region->source (0));
- assert(_write_source);
- _write_source->set_allow_remove_if_empty (false);
-
- /* the source list will never be reset for a destructive track */
+ assert( ! destructive());
+ assert( ! yn);
}
void
@@ -587,8 +548,8 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
cerr << "DISKSTREAM GOT EVENT " << i << "!!\n";
}
- if (_source_port->size() == 0)
- cerr << "No events :/ (1)\n";
+ //if (_source_port->size() == 0)
+ // cerr << "No events :/ (1)\n";
} else {
@@ -607,8 +568,8 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
for (size_t i=0; i < _source_port->size(); ++i) {
cerr << "DISKSTREAM GOT EVENT " << i << "!!\n";
}
- if (_source_port->size() == 0)
- cerr << "No events :/ (2)\n";
+ //if (_source_port->size() == 0)
+ // cerr << "No events :/ (2)\n";
RawMidi* buf = NULL; // FIXME FIXME FIXME (make it compile)
assert(false);
jack_nframes_t first = _capture_vector.len[0];
@@ -630,6 +591,10 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
if (rec_nframes) {
+ // FIXME: filthy hack to fool the GUI into thinking we're doing something
+ if (_write_source)
+ _write_source->ViewDataRangeReady (transport_frame, rec_nframes); /* EMIT SIGNAL */
+
/* data will be written to disk */
if (rec_nframes == nframes && rec_offset == 0) {
@@ -687,9 +652,9 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
jack_nframes_t total = _playback_vector.len[0] + _playback_vector.len[1];
if (necessary_samples > total) {
- cerr << "DiskUnderrun\n";
+ //cerr << "DiskUnderrun\n";
//DiskUnderrun (); // FIXME
- goto out;
+ //goto out;
} else {
@@ -758,12 +723,46 @@ MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes,
}
return ret;
+
+ _processed = true;
+
+ return 0;
}
bool
MidiDiskstream::commit (jack_nframes_t nframes)
{
- return 0;
+ bool need_butler = false;
+
+ if (_actual_speed < 0.0) {
+ playback_sample -= playback_distance;
+ } else {
+ playback_sample += playback_distance;
+ }
+
+ _playback_buf->increment_read_ptr (playback_distance);
+
+ if (adjust_capture_position) {
+ _capture_buf->increment_write_ptr (adjust_capture_position);
+ }
+
+ if (adjust_capture_position != 0) {
+ capture_captured += adjust_capture_position;
+ adjust_capture_position = 0;
+ }
+
+ if (_slaved) {
+ need_butler = _playback_buf->write_space() >= _playback_buf->bufsize() / 2;
+ } else {
+ need_butler = _playback_buf->write_space() >= disk_io_chunk_frames
+ || _capture_buf->read_space() >= disk_io_chunk_frames;
+ }
+
+ state_lock.unlock();
+
+ _processed = false;
+
+ return need_butler;
}
void
@@ -786,6 +785,7 @@ MidiDiskstream::overwrite_existing_buffers ()
int
MidiDiskstream::seek (jack_nframes_t frame, bool complete_refill)
{
+ Glib::Mutex::Lock lm (state_lock);
return 0;
}
@@ -810,12 +810,13 @@ MidiDiskstream::read (RawMidi* buf, jack_nframes_t& start, jack_nframes_t cnt, b
int
MidiDiskstream::do_refill_with_alloc ()
{
- return 0;
+ return do_refill();
}
int
MidiDiskstream::do_refill ()
{
+ // yeah, the data's ready. promise.
return 0;
}
@@ -832,17 +833,198 @@ MidiDiskstream::do_refill ()
int
MidiDiskstream::do_flush (Session::RunContext context, bool force_flush)
{
+ /* hey, so did you write that data? */
+
+ // oh yeah, you bet. wrote it good. honest.
+
return 0;
}
void
MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
{
+ uint32_t buffer_position;
+ bool more_work = true;
+ int err = 0;
+ MidiRegion* region = 0;
+ jack_nframes_t total_capture;
+ MidiRegion::SourceList srcs;
+ MidiRegion::SourceList::iterator src;
+ vector<CaptureInfo*>::iterator ci;
+ bool mark_write_completed = false;
+
+ finish_capture (true);
+
+ /* butler is already stopped, but there may be work to do
+ to flush remaining data to disk.
+ */
+
+ while (more_work && !err) {
+ switch (do_flush (Session::TransportContext, true)) {
+ case 0:
+ more_work = false;
+ break;
+ case 1:
+ break;
+ case -1:
+ error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
+ err++;
+ }
+ }
+
+ /* XXX is there anything we can do if err != 0 ? */
+ Glib::Mutex::Lock lm (capture_info_lock);
+
+ if (capture_info.empty()) {
+ return;
+ }
+
+ if (abort_capture) {
+
+ list<Source*>* deletion_list = new list<Source*>;
+
+ if (_write_source) {
+ _write_source->mark_for_remove ();
+ _write_source->release ();
+
+ deletion_list->push_back (_write_source);
+
+ _write_source = 0;
+ }
+
+ /* new source set up in "out" below */
+
+ if (!deletion_list->empty()) {
+ DeleteSources (deletion_list);
+ } else {
+ delete deletion_list;
+ }
+
+ } else {
+
+ assert(_write_source);
+
+ for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
+ total_capture += (*ci)->frames;
+ }
+
+ /* figure out the name for this take */
+
+ SMFSource* s = _write_source;
+
+ if (s) {
+
+ srcs.push_back (s);
+
+ cerr << "MidiDiskstream: updating source after capture\n";
+ s->update_header (capture_info.front()->start, when, twhen);
+
+ s->set_captured_for (_name);
+
+ }
+
+ /* Register a new region with the Session that
+ describes the entire source. Do this first
+ so that any sub-regions will obviously be
+ children of this one (later!)
+ */
+ try {
+ assert(_write_source);
+ region = new MidiRegion (srcs, _write_source->last_capture_start_frame(), total_capture,
+ region_name_from_path (_write_source->name()),
+ 0, Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile));
+
+ region->special_set_position (capture_info.front()->start);
+ }
+
+
+ catch (failed_constructor& err) {
+ error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
+ /* XXX what now? */
+ }
+
+ _last_capture_regions.push_back (region);
+
+ // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
+
+ XMLNode &before = _playlist->get_state();
+ _playlist->freeze ();
+
+ for (buffer_position = _write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
+
+ string region_name;
+ _session.region_name (region_name, _write_source->name(), false);
+
+ // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
+
+ try {
+ region = new MidiRegion (srcs, buffer_position, (*ci)->frames, region_name);
+ }
+
+ catch (failed_constructor& err) {
+ error << _("MidiDiskstream: could not create region for captured audio!") << endmsg;
+ continue; /* XXX is this OK? */
+ }
+
+ _last_capture_regions.push_back (region);
+
+ // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
+
+ i_am_the_modifier++;
+ _playlist->add_region (*region, (*ci)->start);
+ i_am_the_modifier--;
+
+ buffer_position += (*ci)->frames;
+ }
+
+ _playlist->thaw ();
+ XMLNode &after = _playlist->get_state();
+ _session.add_command (new MementoCommand<Playlist>(*_playlist, before, after));
+
+ mark_write_completed = true;
+
+ reset_write_sources (mark_write_completed);
+
+ }
+
+ for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
+ delete *ci;
+ }
+
+ capture_info.clear ();
+ capture_start_frame = 0;
}
void
MidiDiskstream::finish_capture (bool rec_monitors_input)
{
+ was_recording = false;
+
+ if (capture_captured == 0) {
+ return;
+ }
+
+ // Why must we destroy?
+ assert(!destructive());
+
+ CaptureInfo* ci = new CaptureInfo;
+
+ ci->start = capture_start_frame;
+ ci->frames = capture_captured;
+
+ /* XXX theoretical race condition here. Need atomic exchange ?
+ However, the circumstances when this is called right
+ now (either on record-disable or transport_stopped)
+ mean that no actual race exists. I think ...
+ We now have a capture_info_lock, but it is only to be used
+ to synchronize in the transport_stop and the capture info
+ accessors, so that invalidation will not occur (both non-realtime).
+ */
+
+ // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
+
+ capture_info.push_back (ci);
+ capture_captured = 0;
}
void
@@ -852,12 +1034,8 @@ MidiDiskstream::set_record_enabled (bool yn)
return;
}
- /* can't rec-enable in destructive mode if transport is before start */
-
- if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
- return;
- }
-
+ assert(!destructive());
+
if (yn && _source_port == 0) {
/* pick up connections not initiated *from* the IO object
@@ -1014,11 +1192,7 @@ MidiDiskstream::set_state (const XMLNode& node)
_playlist->set_orig_diskstream_id (_id);
}
- if (!destructive() && capture_pending_node) {
- /* destructive streams have one and only one source per channel,
- and so they never end up in pending capture in any useful
- sense.
- */
+ if (capture_pending_node) {
use_pending_capture_data (*capture_pending_node);
}
@@ -1083,10 +1257,7 @@ MidiDiskstream::use_new_write_source (uint32_t n)
}
_write_source->use ();
-
- /* do not remove destructive files even if they are empty */
-
- _write_source->set_allow_remove_if_empty (!destructive());
+ _write_source->set_allow_remove_if_empty (true);
return 0;
}
@@ -1098,29 +1269,11 @@ MidiDiskstream::reset_write_sources (bool mark_write_complete, bool force)
return;
}
- if (!destructive()) {
-
- if (_write_source && mark_write_complete) {
- _write_source->mark_streaming_write_completed ();
- }
- use_new_write_source ();
-
- } else {
- if (_write_source == 0) {
- use_new_write_source ();
- }
- }
-
- if (destructive()) {
-
- /* we now have all our write sources set up, so create the
- playlist's single region.
- */
-
- if (_playlist->empty()) {
- setup_destructive_playlist ();
- }
+ if (_write_source && mark_write_complete) {
+ _write_source->mark_streaming_write_completed ();
}
+ use_new_write_source ();
+ assert(_write_source);
}
int
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index db28c06f17..443c5b57bf 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -43,8 +43,11 @@ MidiPlaylist::State::~State ()
{}
MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden)
- : Playlist (session, node, hidden)
+ : Playlist (session, node, DataType::MIDI, hidden)
{
+ const XMLProperty* prop = node.property("type");
+ assert(prop && DataType(prop->value()) == DataType::MIDI);
+
in_set_state = true;
set_state (node);
in_set_state = false;
@@ -57,7 +60,7 @@ MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden)
}
MidiPlaylist::MidiPlaylist (Session& session, string name, bool hidden)
- : Playlist (session, name, hidden)
+ : Playlist (session, name, DataType::MIDI, hidden)
{
save_state (_("initial state"));
@@ -70,6 +73,7 @@ MidiPlaylist::MidiPlaylist (Session& session, string name, bool hidden)
MidiPlaylist::MidiPlaylist (const MidiPlaylist& other, string name, bool hidden)
: Playlist (other, name, hidden)
{
+ throw; // nope
save_state (_("initial state"));
/*
@@ -246,6 +250,7 @@ MidiPlaylist::refresh_dependents (Region& r)
void
MidiPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
{
+ throw; // I don't wanna
/*
MidiRegion *orig = dynamic_cast<MidiRegion*>(o);
MidiRegion *left = dynamic_cast<MidiRegion*>(l);
@@ -333,20 +338,18 @@ MidiPlaylist::check_dependents (Region& r, bool norefresh)
int
MidiPlaylist::set_state (const XMLNode& node)
{
- /*
- XMLNode *child;
- XMLNodeList nlist;
- XMLNodeConstIterator niter;
-
if (!in_set_state) {
Playlist::set_state (node);
}
- nlist = node.children();
+ // Actually Charles, I don't much care for children
+
+ /*
+ XMLNodeList nlist = node.children();
- for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+ for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
- child = *niter;
+ XMLNode* const child = *niter;
}*/
diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc
index 0902337030..5b8a49049e 100644
--- a/libs/ardour/midi_region.cc
+++ b/libs/ardour/midi_region.cc
@@ -48,7 +48,7 @@ using namespace ARDOUR;
/** Basic MidiRegion constructor (one channel) */
MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t length, bool announce)
- : Region (src, start, length, PBD::basename_nosuffix(src.name()), 0, Region::Flag(Region::DefaultFlags|Region::External))
+ : Region (src, start, length, PBD::basename_nosuffix(src.name()), DataType::MIDI, 0, Region::Flag(Region::DefaultFlags|Region::External))
{
save_state ("initial state");
@@ -59,7 +59,7 @@ MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t le
/* Basic MidiRegion constructor (one channel) */
MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
- : Region (src, start, length, name, layer, flags)
+ : Region (src, start, length, name, DataType::MIDI, layer, flags)
{
save_state ("initial state");
@@ -70,7 +70,7 @@ MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t le
/* Basic MidiRegion constructor (many channels) */
MidiRegion::MidiRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
- : Region (srcs, start, length, name, layer, flags)
+ : Region (srcs, start, length, name, DataType::MIDI, layer, flags)
{
save_state ("initial state");
@@ -108,6 +108,8 @@ MidiRegion::MidiRegion (MidiSource& src, const XMLNode& node)
save_state ("initial state");
+ assert(_type == DataType::MIDI);
+
CheckNewRegion (this); /* EMIT SIGNAL */
}
@@ -120,6 +122,8 @@ MidiRegion::MidiRegion (SourceList& srcs, const XMLNode& node)
save_state ("initial state");
+ assert(_type == DataType::MIDI);
+
CheckNewRegion (this); /* EMIT SIGNAL */
}
@@ -332,6 +336,8 @@ MidiRegion::separate_by_channel (Session& session, vector<MidiRegion*>& v) const
v.push_back (new MidiRegion (srcs, _start, _length, new_name, _layer, _flags));
}
#endif
+
+ // Actually, I would prefer not if that's alright
return -1;
}
diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc
index 4cda0f6ebd..6728231de6 100644
--- a/libs/ardour/midi_source.cc
+++ b/libs/ardour/midi_source.cc
@@ -42,7 +42,7 @@ using namespace PBD;
sigc::signal<void,MidiSource *> MidiSource::MidiSourceCreated;
MidiSource::MidiSource (string name)
- : Source (name)
+ : Source (name, DataType::MIDI)
{
_read_data_count = 0;
_write_data_count = 0;
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index cdbd441cd6..470759f3ac 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -129,44 +129,6 @@ MidiTrack::use_diskstream (const PBD::ID& id)
return set_diskstream (*dstream);
}
-bool
-MidiTrack::record_enabled () const
-{
- return _diskstream->record_enabled ();
-}
-
-void
-MidiTrack::set_record_enable (bool yn, void *src)
-{
- if (_freeze_record.state == Frozen) {
- return;
- }
-#if 0
- if (_mix_group && src != _mix_group && _mix_group->is_active()) {
- _mix_group->apply (&MidiTrack::set_record_enable, yn, _mix_group);
- return;
- }
-
- /* keep track of the meter point as it was before we rec-enabled */
-
- if (!diskstream->record_enabled()) {
- _saved_meter_point = _meter_point;
- }
-
- diskstream->set_record_enabled (yn, src);
-
- if (diskstream->record_enabled()) {
- set_meter_point (MeterInput, this);
- } else {
- set_meter_point (_saved_meter_point, this);
- }
-
- if (_session.get_midi_feedback()) {
- _midi_rec_enable_control.send_feedback (record_enabled());
- }
-#endif
-}
-
MidiDiskstream&
MidiTrack::midi_diskstream() const
{
@@ -482,7 +444,109 @@ int
MidiTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick,
bool can_record, bool rec_monitors_input)
{
- passthru (start_frame, end_frame, nframes, offset, declick, false);
+ //passthru (start_frame, end_frame, nframes, offset, declick, false);
+ int dret;
+ RawMidi* b; // FIXME: this won't work, duh
+ //Sample* tmpb;
+ jack_nframes_t transport_frame;
+ MidiDiskstream& diskstream = midi_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().get_total() == 0 && _redirects.empty()) {
+ return 0;
+ }
+
+ if (!_active) {
+ silence (nframes, offset);
+ return 0;
+ }
+
+ transport_frame = _session.transport_frame();
+
+ if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
+ /* need to do this so that the diskstream sets its
+ playback distance to zero, thus causing diskstream::commit
+ to do nothing.
+ */
+ return diskstream.process (transport_frame, 0, 0, can_record, rec_monitors_input);
+ }
+
+ _silent = false;
+ //apply_gain_automation = false;
+
+ if ((dret = diskstream.process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
+
+ silence (nframes, offset);
+
+ return dret;
+ }
+
+ /* special condition applies */
+
+ if (_meter_point == MeterInput) {
+ just_meter_input (start_frame, end_frame, nframes, offset);
+ }
+
+ if (diskstream.record_enabled() && !can_record && !_session.get_auto_input()) {
+
+ /* not actually recording, but we want to hear the input material anyway,
+ at least potentially (depending on monitoring options)
+ */
+
+ passthru (start_frame, end_frame, nframes, offset, 0, true);
+
+ } else if ((b = diskstream.playback_buffer()) != 0) {
+ /*
+ XXX is it true that the earlier test on n_outputs()
+ means that we can avoid checking it again here? i think
+ so, because changing the i/o configuration of an IO
+ requires holding the AudioEngine lock, which we hold
+ while in the process() tree.
+ */
+
+
+ /* copy the diskstream data to all output buffers */
+
+ //const size_t limit = n_process_buffers().get(DataType::AUDIO);
+ BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
+
+ //uint32_t n;
+ //uint32_t i;
+#if 0
+ for (i = 0, n = 1; i < limit; ++i, ++n) {
+ memcpy (bufs.get_audio(i).data(nframes), b, sizeof (Sample) * nframes);
+ if (n < diskstream.n_channels().get(DataType::AUDIO)) {
+ tmpb = diskstream.playback_buffer(n);
+ if (tmpb!=0) {
+ b = tmpb;
+ }
+ }
+ }
+
+ /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
+
+ if (!diskstream.record_enabled() && _session.transport_rolling()) {
+ Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
+
+ if (am.locked() && gain_automation_playback()) {
+ apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
+ }
+ }
+#endif
+ process_output_buffers (bufs, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !_session.get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
+
+ } else {
+ /* problem with the diskstream; just be quiet for a bit */
+ silence (nframes, offset);
+ }
return 0;
}
@@ -571,6 +635,7 @@ MidiTrack::set_latency_delay (jack_nframes_t longest_session_latency)
void
MidiTrack::bounce (InterThreadInfo& itt)
{
+ throw;
//vector<MidiSource*> srcs;
//_session.write_one_midi_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
}
@@ -579,6 +644,7 @@ MidiTrack::bounce (InterThreadInfo& itt)
void
MidiTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt)
{
+ throw;
//vector<MidiSource*> srcs;
//_session.write_one_midi_track (*this, start, end, false, srcs, itt);
}
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 6d5e8f7847..61aa5c587a 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -72,17 +72,22 @@ struct RegionSortByLastLayerOp {
}
};
-Playlist::Playlist (Session& sess, string nom, bool hide)
+Playlist::Playlist (Session& sess, string nom, DataType type, bool hide)
: _session (sess)
+ , _type(type)
{
init (hide);
_name = nom;
}
-Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
+Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide)
: _session (sess)
+ , _type(type)
{
+ const XMLProperty* prop = node.property("type");
+ assert(!prop || DataType(prop->value()) == _type);
+
init (hide);
_name = "unnamed"; /* reset by set_state */
@@ -92,7 +97,7 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
}
Playlist::Playlist (const Playlist& other, string namestr, bool hide)
- : _name (namestr), _session (other._session), _orig_diskstream_id(other._orig_diskstream_id)
+ : _name (namestr), _session (other._session), _type(other._type), _orig_diskstream_id(other._orig_diskstream_id)
{
init (hide);
@@ -125,7 +130,7 @@ Playlist::Playlist (const Playlist& other, string namestr, bool hide)
}
Playlist::Playlist (const Playlist& other, jack_nframes_t start, jack_nframes_t cnt, string str, bool hide)
- : _name (str), _session (other._session), _orig_diskstream_id(other._orig_diskstream_id)
+ : _name (str), _session (other._session), _type(other._type), _orig_diskstream_id(other._orig_diskstream_id)
{
RegionLock rlock2 (&((Playlist&)other));
@@ -247,12 +252,14 @@ Playlist::init (bool hide)
Playlist::Playlist (const Playlist& pl)
: _session (pl._session)
+ , _type(pl.data_type())
{
fatal << _("playlist const copy constructor called") << endmsg;
}
Playlist::Playlist (Playlist& pl)
: _session (pl._session)
+ , _type(pl.data_type())
{
fatal << _("playlist non-const copy constructor called") << endmsg;
}
@@ -1426,6 +1433,7 @@ Playlist::state (bool full_state)
char buf[64];
node->add_property (X_("name"), _name);
+ node->add_property (X_("type"), _type.to_string());
_orig_diskstream_id.print (buf);
node->add_property (X_("orig_diskstream_id"), buf);
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 03a4d1d2a3..3481ee3eea 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -51,8 +51,9 @@ Change Region::HiddenChanged = ARDOUR::new_change ();
sigc::signal<void,Region *> Region::CheckNewRegion;
/** Basic Region constructor (single source) */
-Region::Region (Source& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags)
+Region::Region (Source& src, jack_nframes_t start, jack_nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
: _name(name)
+ , _type(type)
, _flags(flags)
, _start(start)
, _length(length)
@@ -76,8 +77,9 @@ Region::Region (Source& src, jack_nframes_t start, jack_nframes_t length, const
}
/** Basic Region constructor (many sources) */
-Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags)
+Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
: _name(name)
+ , _type(type)
, _flags(flags)
, _start(start)
, _length(length)
@@ -114,6 +116,7 @@ Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, c
/** Create a new Region from part of an existing one */
Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: _name(name)
+ , _type(other.data_type())
, _flags(Flag(flags & ~(Locked|WholeFile|Hidden)))
, _start(other._start + offset)
, _length(length)
@@ -153,6 +156,7 @@ Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t lengt
/** Pure copy constructor */
Region::Region (const Region &other)
: _name(other._name)
+ , _type(other.data_type())
, _flags(Flag(other._flags & ~Locked))
, _start(other._start)
, _length(other._length)
@@ -196,6 +200,7 @@ Region::Region (const Region &other)
Region::Region (SourceList& srcs, const XMLNode& node)
: _name(X_("error: XML did not reset this"))
+ , _type(DataType::NIL) // to be loaded from XML
, _flags(Flag(0))
, _start(0)
, _length(0)
@@ -230,12 +235,14 @@ Region::Region (SourceList& srcs, const XMLNode& node)
if (set_state (node)) {
throw failed_constructor();
}
-
+
+ assert(_type != DataType::NIL);
assert(_sources.size() > 0);
}
Region::Region (Source& src, const XMLNode& node)
: _name(X_("error: XML did not reset this"))
+ , _type(DataType::NIL)
, _flags(Flag(0))
, _start(0)
, _length(0)
@@ -257,6 +264,7 @@ Region::Region (Source& src, const XMLNode& node)
throw failed_constructor();
}
+ assert(_type != DataType::NIL);
assert(_sources.size() > 0);
}
@@ -957,6 +965,7 @@ Region::state (bool full_state)
_id.print (buf);
node->add_property ("id", buf);
node->add_property ("name", _name);
+ node->add_property ("type", _type.to_string());
snprintf (buf, sizeof (buf), "%u", _start);
node->add_property ("start", buf);
snprintf (buf, sizeof (buf), "%u", _length);
@@ -1004,6 +1013,12 @@ Region::set_state (const XMLNode& node)
}
_name = prop->value();
+
+ if ((prop = node.property ("type")) == 0) {
+ _type = DataType::AUDIO;
+ } else {
+ _type = DataType(prop->value());
+ }
if ((prop = node.property ("start")) != 0) {
_start = (jack_nframes_t) atoi (prop->value().c_str());
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 9cfaf18cb0..33165574a8 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -431,10 +431,10 @@ Session::~Session ()
}
#ifdef TRACK_DESTRUCTION
- cerr << "delete audio regions\n";
+ cerr << "delete regions\n";
#endif /* TRACK_DESTRUCTION */
- for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); ) {
- AudioRegionList::iterator tmp;
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
+ RegionList::iterator tmp;
tmp =i;
++tmp;
@@ -461,8 +461,8 @@ Session::~Session ()
#ifdef TRACK_DESTRUCTION
cerr << "delete audio sources\n";
#endif /* TRACK_DESTRUCTION */
- for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
- AudioSourceList::iterator tmp;
+ for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
+ SourceList::iterator tmp;
tmp = i;
++tmp;
@@ -2137,11 +2137,11 @@ Session::remove_route (shared_ptr<Route> route)
/* writer goes out of scope, forces route list update */
}
- AudioTrack* at;
- AudioDiskstream* ds = 0;
+ Track* t;
+ Diskstream* ds = 0;
- if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
- ds = &at->audio_diskstream();
+ if ((t = dynamic_cast<Track*>(route.get())) != 0) {
+ ds = &t->diskstream();
}
if (ds) {
@@ -2183,7 +2183,7 @@ Session::route_solo_changed (void* src, shared_ptr<Route> route)
bool is_track;
- is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
+ is_track = (dynamic_cast<Track*>(route.get()) != 0);
shared_ptr<RouteList> r = routes.reader ();
@@ -2195,7 +2195,7 @@ Session::route_solo_changed (void* src, shared_ptr<Route> route)
/* don't mess with busses */
- if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
+ if (dynamic_cast<Track*>((*i).get()) == 0) {
continue;
}
@@ -2203,7 +2203,7 @@ Session::route_solo_changed (void* src, shared_ptr<Route> route)
/* don't mess with tracks */
- if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
+ if (dynamic_cast<Track*>((*i).get()) != 0) {
continue;
}
}
@@ -2239,7 +2239,7 @@ Session::route_solo_changed (void* src, shared_ptr<Route> route)
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->soloed()) {
something_soloed = true;
- if (dynamic_cast<AudioTrack*>((*i).get())) {
+ if (dynamic_cast<Track*>((*i).get())) {
if (is_track) {
same_thing_soloed = true;
break;
@@ -2296,7 +2296,7 @@ Session::update_route_solo_state ()
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->soloed()) {
mute = true;
- if (dynamic_cast<AudioTrack*>((*i).get())) {
+ if (dynamic_cast<Track*>((*i).get())) {
is_track = true;
}
break;
@@ -2341,7 +2341,7 @@ Session::modify_solo_mute (bool is_track, bool mute)
/* only alter track solo mute */
- if (dynamic_cast<AudioTrack*>((*i).get())) {
+ if (dynamic_cast<Track*>((*i).get())) {
if ((*i)->soloed()) {
(*i)->set_solo_mute (!mute);
} else {
@@ -2353,7 +2353,7 @@ Session::modify_solo_mute (bool is_track, bool mute)
/* only alter bus solo mute */
- if (!dynamic_cast<AudioTrack*>((*i).get())) {
+ if (!dynamic_cast<Track*>((*i).get())) {
if ((*i)->soloed()) {
@@ -2506,7 +2506,7 @@ Session::new_region_name (string old)
while (number < (UINT_MAX-1)) {
- AudioRegionList::const_iterator i;
+ RegionList::const_iterator i;
string sbuf;
number++;
@@ -2514,13 +2514,13 @@ Session::new_region_name (string old)
snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number);
sbuf = buf;
- for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
+ for (i = regions.begin(); i != regions.end(); ++i) {
if (i->second->name() == sbuf) {
break;
}
}
- if (i == audio_regions.end()) {
+ if (i == regions.end()) {
break;
}
}
@@ -2543,7 +2543,7 @@ Session::region_name (string& result, string base, bool newlevel) const
Glib::Mutex::Lock lm (region_lock);
- snprintf (buf, sizeof (buf), "%d", (int)audio_regions.size() + 1);
+ snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1);
result = "region.";
@@ -2579,7 +2579,7 @@ Session::region_name (string& result, string base, bool newlevel) const
name_taken = false;
- for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
+ for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
if (i->second->name() == result) {
name_taken = true;
break;
@@ -2603,62 +2603,48 @@ Session::region_name (string& result, string base, bool newlevel) const
void
Session::add_region (Region* region)
{
- AudioRegion* ar = 0;
- AudioRegion* oar = 0;
bool added = false;
{
Glib::Mutex::Lock lm (region_lock);
- if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
-
- AudioRegionList::iterator x;
+ RegionList::iterator x;
- for (x = audio_regions.begin(); x != audio_regions.end(); ++x) {
+ for (x = regions.begin(); x != regions.end(); ++x) {
- oar = dynamic_cast<AudioRegion*> (x->second);
-
- if (ar->region_list_equivalent (*oar)) {
- break;
- }
+ if (region->region_list_equivalent (*x->second)) {
+ break;
}
+ }
- if (x == audio_regions.end()) {
-
- pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
+ if (x == regions.end()) {
- entry.first = region->id();
- entry.second = ar;
+ pair<RegionList::key_type,RegionList::mapped_type> entry;
- pair<AudioRegionList::iterator,bool> x = audio_regions.insert (entry);
-
- if (!x.second) {
- return;
- }
+ entry.first = region->id();
+ entry.second = region;
- added = true;
- }
+ pair<RegionList::iterator,bool> x = regions.insert (entry);
- } else {
+ if (!x.second) {
+ return;
+ }
- fatal << _("programming error: ")
- << X_("unknown region type passed to Session::add_region()")
- << endmsg;
- /*NOTREACHED*/
+ added = true;
+ }
- }
}
/* mark dirty because something has changed even if we didn't
add the region to the region list.
- */
-
+ */
+
set_dirty();
-
+
if (added) {
region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
- AudioRegionAdded (ar); /* EMIT SIGNAL */
+ RegionAdded (region); /* EMIT SIGNAL */
}
}
@@ -2680,47 +2666,38 @@ Session::region_renamed (Region* region)
void
Session::remove_region (Region* region)
{
- AudioRegionList::iterator i;
- AudioRegion* ar = 0;
+ RegionList::iterator i;
bool removed = false;
-
+
{
Glib::Mutex::Lock lm (region_lock);
- if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
- if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
- audio_regions.erase (i);
- removed = true;
- }
-
- } else {
-
- fatal << _("programming error: ")
- << X_("unknown region type passed to Session::remove_region()")
- << endmsg;
- /*NOTREACHED*/
+ if ((i = regions.find (region->id())) != regions.end()) {
+ regions.erase (i);
+ removed = true;
}
+
}
/* mark dirty because something has changed even if we didn't
remove the region from the region list.
- */
+ */
set_dirty();
if (removed) {
- AudioRegionRemoved(ar); /* EMIT SIGNAL */
+ RegionRemoved(region); /* EMIT SIGNAL */
}
}
Region*
Session::find_whole_file_parent (Region& child)
{
- AudioRegionList::iterator i;
- AudioRegion* region;
+ RegionList::iterator i;
+ Region* region;
Glib::Mutex::Lock lm (region_lock);
- for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
+ for (i = regions.begin(); i != regions.end(); ++i) {
region = i->second;
@@ -2812,17 +2789,16 @@ Session::remove_region_from_region_list (Region& r)
}
/* Source Management */
-
void
-Session::add_audio_source (AudioSource* source)
+Session::add_source (Source* source)
{
- pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
+ pair<SourceList::key_type, SourceList::mapped_type> entry;
{
- Glib::Mutex::Lock lm (audio_source_lock);
+ Glib::Mutex::Lock lm (source_lock);
entry.first = source->id();
entry.second = source;
- audio_sources.insert (entry);
+ sources.insert (entry);
}
source->GoingAway.connect (mem_fun (this, &Session::remove_source));
@@ -2834,13 +2810,13 @@ Session::add_audio_source (AudioSource* source)
void
Session::remove_source (Source* source)
{
- AudioSourceList::iterator i;
+ SourceList::iterator i;
{
- Glib::Mutex::Lock lm (audio_source_lock);
+ Glib::Mutex::Lock lm (source_lock);
- if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
- audio_sources.erase (i);
+ if ((i = sources.find (source->id())) != sources.end()) {
+ sources.erase (i);
}
}
@@ -2860,11 +2836,11 @@ Session::remove_source (Source* source)
Source *
Session::source_by_id (const PBD::ID& id)
{
- Glib::Mutex::Lock lm (audio_source_lock);
- AudioSourceList::iterator i;
+ Glib::Mutex::Lock lm (source_lock);
+ SourceList::iterator i;
Source* source = 0;
- if ((i = audio_sources.find (id)) != audio_sources.end()) {
+ if ((i = sources.find (id)) != sources.end()) {
source = i->second;
}
@@ -3479,9 +3455,9 @@ Session::record_enable_change_all (bool yn)
shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- AudioTrack* at;
+ Track* at;
- if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
+ if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
at->set_record_enable (yn, this);
}
}
@@ -3791,9 +3767,9 @@ Session::freeze (InterThreadInfo& itt)
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- AudioTrack *at;
+ Track *at;
- if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
+ if ((at = dynamic_cast<Track*>((*i).get())) != 0) {
/* XXX this is wrong because itt.progress will keep returning to zero at the start
of every track.
*/
@@ -3986,7 +3962,7 @@ Session::ntracks () const
shared_ptr<RouteList> r = routes.reader ();
for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
- if (dynamic_cast<AudioTrack*> ((*i).get())) {
+ if (dynamic_cast<Track*> ((*i).get())) {
++n;
}
}
@@ -4001,7 +3977,7 @@ Session::nbusses () const
shared_ptr<RouteList> r = routes.reader ();
for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
- if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
+ if (dynamic_cast<Track*> ((*i).get()) == 0) {
++n;
}
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 2a08859205..5e96a8ca8a 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -63,8 +63,11 @@
#include <ardour/midi_diskstream.h>
#include <ardour/utils.h>
#include <ardour/audioplaylist.h>
+#include <ardour/midi_playlist.h>
+#include <ardour/smf_source.h>
#include <ardour/audiofilesource.h>
#include <ardour/destructive_filesource.h>
+#include <ardour/midi_source.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/auditioner.h>
#include <ardour/export.h>
@@ -82,6 +85,7 @@
#include <ardour/version.h>
#include <ardour/location.h>
#include <ardour/audioregion.h>
+#include <ardour/midi_region.h>
#include <ardour/crossfade.h>
#include <ardour/control_protocol_manager.h>
@@ -264,7 +268,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
/* These are all static "per-class" signals */
Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
- AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
+ Source::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));
Diskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
@@ -1348,26 +1352,19 @@ Session::state(bool full_state)
child = node->add_child ("Sources");
if (full_state) {
- Glib::Mutex::Lock sl (audio_source_lock);
+ Glib::Mutex::Lock sl (source_lock);
- for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
+ for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
- /* Don't save information about AudioFileSources that are empty */
-
- AudioFileSource* fs;
- if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) {
- DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
+ DestructiveFileSource* const dfs = dynamic_cast<DestructiveFileSource*> (siter->second);
- /* destructive file sources are OK if they are empty, because
- we will re-use them every time.
- */
+ /* Don't save sources that are empty, unless they're destructive (which are OK
+ if they are empty, because we will re-use them every time.)
+ */
- if (!dfs) {
- if (fs->length() == 0) {
- continue;
- }
- }
+ if ( ! dfs && siter->second->length() == 0) {
+ continue;
}
child->add_child_nocopy (siter->second->get_state());
@@ -1379,7 +1376,7 @@ Session::state(bool full_state)
if (full_state) {
Glib::Mutex::Lock rl (region_lock);
- for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
+ for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
/* only store regions not attached to playlists */
@@ -1769,7 +1766,7 @@ Session::load_regions (const XMLNode& node)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
- AudioRegion* region;
+ Region* region;
nlist = node.children();
@@ -1783,9 +1780,33 @@ Session::load_regions (const XMLNode& node)
return 0;
}
-AudioRegion *
+Region *
Session::XMLRegionFactory (const XMLNode& node, bool full)
{
+ const XMLProperty* type = node.property("type");
+
+ try {
+
+ if ( !type || type->value() == "audio" ) {
+
+ return XMLAudioRegionFactory (node, full);
+
+ } else if (type->value() == "midi") {
+
+ return XMLMidiRegionFactory (node, full);
+
+ }
+
+ } catch (failed_constructor& err) {
+ return 0;
+ }
+
+ return 0;
+}
+
+AudioRegion *
+Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
+{
const XMLProperty* prop;
Source* source;
AudioSource* as;
@@ -1855,14 +1876,65 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
}
}
+MidiRegion *
+Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
+{
+ const XMLProperty* prop;
+ Source* source;
+ MidiSource* ms;
+ MidiRegion::SourceList sources;
+ uint32_t nchans = 1;
+
+ if (node.name() != X_("Region")) {
+ return 0;
+ }
+
+ if ((prop = node.property (X_("channels"))) != 0) {
+ nchans = atoi (prop->value().c_str());
+ }
+
+ // Multiple midi channels? that's just crazy talk
+ assert(nchans == 1);
+
+ if ((prop = node.property (X_("source-0"))) == 0) {
+ if ((prop = node.property ("source")) == 0) {
+ error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
+ return 0;
+ }
+ }
+
+ PBD::ID s_id (prop->value());
+
+ if ((source = source_by_id (s_id)) == 0) {
+ error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
+ return 0;
+ }
+
+ ms = dynamic_cast<MidiSource*>(source);
+ if (!ms) {
+ error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-audio source id =%1"), s_id) << endmsg;
+ return 0;
+ }
+
+ sources.push_back (ms);
+
+ try {
+ return new MidiRegion (sources, node);
+ }
+
+ catch (failed_constructor& err) {
+ return 0;
+ }
+}
+
XMLNode&
Session::get_sources_as_xml ()
{
XMLNode* node = new XMLNode (X_("Sources"));
- Glib::Mutex::Lock lm (audio_source_lock);
+ Glib::Mutex::Lock lm (source_lock);
- for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
+ for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
node->add_child_nocopy (i->second->get_state());
}
@@ -1923,13 +1995,29 @@ Session::XMLSourceFactory (const XMLNode& node)
if (node.name() != "Source") {
return 0;
}
+
+ DataType type = DataType::AUDIO;
+ const XMLProperty* prop = node.property("type");
+ if (prop) {
+ type = DataType(prop->value());
+ }
try {
+
+
+ if (type == DataType::AUDIO) {
+
src = AudioFileSource::create (node);
+
+ } else if (type == DataType::MIDI) {
+
+ src = new SMFSource (node);
+
}
- catch (failed_constructor& err) {
- error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
+
+ } catch (failed_constructor& err) {
+ error << _("Found a file that cannot be read by Ardour. Talk to the progammers.") << endmsg;
return 0;
}
@@ -2241,17 +2329,28 @@ Session::load_unused_playlists (const XMLNode& node)
return 0;
}
-
Playlist *
Session::XMLPlaylistFactory (const XMLNode& node)
{
+ const XMLProperty* type = node.property("type");
+
try {
+
+ if ( !type || type->value() == "audio" ) {
+
return new AudioPlaylist (*this, node);
- }
+
+ } else if (type->value() == "midi") {
- catch (failed_constructor& err) {
+ return new MidiPlaylist (*this, node);
+
+ }
+
+ } catch (failed_constructor& err) {
return 0;
}
+
+ return 0;
}
int
@@ -2961,9 +3060,9 @@ Session::cleanup_sources (Session::cleanup_report& rep)
rep.paths.clear ();
rep.space = 0;
- for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
+ for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
- AudioSourceList::iterator tmp;
+ SourceList::iterator tmp;
tmp = i;
++tmp;
@@ -2980,7 +3079,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
adding it to the list of all sources below
*/
- audio_sources.erase (i);
+ sources.erase (i);
}
i = tmp;
@@ -2993,19 +3092,18 @@ Session::cleanup_sources (Session::cleanup_report& rep)
for (vector<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;
- AudioRegion* ar;
+ for (RegionList::iterator r = regions.begin(); r != regions.end(); ) {
+ RegionList::iterator tmp;
tmp = r;
++tmp;
- ar = r->second;
+ Region* const reg = r->second;
- for (uint32_t n = 0; n < ar->n_channels(); ++n) {
- if (&ar->source (n) == (*i)) {
+ for (uint32_t n = 0; n < reg->n_channels(); ++n) {
+ if (&reg->source (n) == (*i)) {
/* this region is dead */
- remove_region (ar);
+ remove_region (reg);
}
}
@@ -3050,7 +3148,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
/* add our current source list
*/
- for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
+ for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
AudioFileSource* fs;
if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 86e2e8a9aa..9a03d0fabd 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -54,6 +54,8 @@ SMFSource::SMFSource (std::string path, Flag flags)
if (init (path, false)) {
throw failed_constructor ();
}
+
+ SourceCreated (this); /* EMIT SIGNAL */
}
SMFSource::SMFSource (const XMLNode& node)
@@ -68,6 +70,8 @@ SMFSource::SMFSource (const XMLNode& node)
if (init (_name, true)) {
throw failed_constructor ();
}
+
+ SourceCreated (this); /* EMIT SIGNAL */
}
SMFSource::~SMFSource ()
@@ -89,8 +93,9 @@ SMFSource::init (string pathstr, bool must_exist)
{
bool is_new = false;
- _length = 0;
+ _length = 1024; // FIXME FIXME FIXME: force save
+ /*
if (!find (pathstr, must_exist, is_new)) {
cerr << "cannot find " << pathstr << " with me = " << must_exist << endl;
return -1;
@@ -99,6 +104,9 @@ SMFSource::init (string pathstr, bool must_exist)
if (is_new && must_exist) {
return -1;
}
+ */
+
+ // Yeah, we sound it. Swear.
return 0;
}
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index b487d4e3a3..4d5f42b028 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -51,7 +51,7 @@ SndFileSource::SndFileSource (const XMLNode& node)
}
}
- AudioSourceCreated (this); /* EMIT SIGNAL */
+ SourceCreated (this); /* EMIT SIGNAL */
}
SndFileSource::SndFileSource (string idstr, Flag flags)
@@ -73,7 +73,7 @@ SndFileSource::SndFileSource (string idstr, Flag flags)
}
- AudioSourceCreated (this); /* EMIT SIGNAL */
+ SourceCreated (this); /* EMIT SIGNAL */
}
SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, jack_nframes_t rate, Flag flags)
@@ -184,7 +184,7 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf,
}
}
- AudioSourceCreated (this); /* EMIT SIGNAL */
+ SourceCreated (this); /* EMIT SIGNAL */
}
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index e5aba19d2c..1506983e18 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -42,7 +42,11 @@ using std::max;
using namespace ARDOUR;
-Source::Source (string name)
+sigc::signal<void,Source*> Source::SourceCreated;
+
+
+Source::Source (string name, DataType type)
+ : _type(type)
{
_name = name;
_use_cnt = 0;
@@ -50,11 +54,12 @@ Source::Source (string name)
}
Source::Source (const XMLNode& node)
+ : _type(DataType::AUDIO)
{
_use_cnt = 0;
_timestamp = 0;
- if (set_state (node)) {
+ if (set_state (node) || _type == DataType::NIL) {
throw failed_constructor();
}
}
@@ -70,6 +75,7 @@ Source::get_state ()
char buf[64];
node->add_property ("name", _name);
+ node->add_property ("type", _type.to_string());
_id.print (buf);
node->add_property ("id", buf);
@@ -98,6 +104,10 @@ Source::set_state (const XMLNode& node)
return -1;
}
+ if ((prop = node.property ("type")) != 0) {
+ _type = DataType(prop->value());
+ }
+
if ((prop = node.property ("timestamp")) != 0) {
sscanf (prop->value().c_str(), "%ld", &_timestamp);
}