try {
afs = boost::dynamic_pointer_cast<AudioFileSource> (
SourceFactory::createReadable (DataType::AUDIO, *_session,
- path, false, n, Source::Flag (0), false));
+ path, n, Source::Flag (0), false));
srclist.push_back(afs);
protected:
/** Constructor to be called for existing external-to-session files */
- AudioFileSource (Session&, const Glib::ustring& path, bool embedded, Source::Flag flags);
+ AudioFileSource (Session&, const Glib::ustring& path, Source::Flag flags);
/** Constructor to be called for new in-session files */
- AudioFileSource (Session&, const Glib::ustring& path, bool embedded, Source::Flag flags,
+ AudioFileSource (Session&, const Glib::ustring& path, Source::Flag flags,
SampleFormat samp_format, HeaderFormat hdr_format);
/** Constructor to be called for existing in-session files */
mutable CAAudioFile af;
uint16_t n_channels;
- void init ();
+ void init_cafile ();
int safe_read (Sample*, nframes_t start, nframes_t cnt, AudioBufferList&) const;
};
void mark_take (const Glib::ustring& id);
void mark_immutable ();
- const Glib::ustring& take_id () const { return _take_id; }
- bool is_embedded () const { return _is_embedded; }
- uint16_t channel() const { return _channel; }
+ const Glib::ustring& take_id () const { return _take_id; }
+ bool within_session () const { return _within_session; }
+ uint16_t channel() const { return _channel; }
int set_state (const XMLNode&, int version);
protected:
FileSource (Session& session, DataType type,
- const Glib::ustring& path, bool embedded,
+ const Glib::ustring& path,
Source::Flag flags = Source::Flag(0));
FileSource (Session& session, const XMLNode& node, bool must_exist);
virtual int init (const Glib::ustring& idstr, bool must_exist);
virtual int move_dependents_to_trash() { return 0; }
-
- void set_embedded_from_name();
+ void set_within_session_from_path (const std::string&);
bool removable () const;
Glib::ustring _take_id;
bool _file_is_new;
uint16_t _channel;
- bool _is_embedded;
+ bool _within_session;
static std::map<DataType, Glib::ustring> search_paths;
};
std::string name() const { return _name; }
std::string snap_name() const { return _current_snapshot_name; }
std::string raid_path () const;
+ bool path_is_within_session (const std::string&);
void set_snap_name ();
class SMFSource : public MidiSource, public FileSource, public Evoral::SMF {
public:
/** Constructor for existing external-to-session files */
- SMFSource (Session& session, const Glib::ustring& path, bool embedded,
+ SMFSource (Session& session, const Glib::ustring& path,
Source::Flag flags = Source::Flag(0));
/** Constructor for existing in-session files */
class SndFileSource : public AudioFileSource {
public:
/** Constructor to be called for existing external-to-session files */
- SndFileSource (Session&, const Glib::ustring& path, bool embedded, int chn, Flag flags);
+ SndFileSource (Session&, const Glib::ustring& path, int chn, Flag flags);
/* Constructor to be called for new in-session files */
- SndFileSource (Session&, const Glib::ustring& path, bool embedded,
+ SndFileSource (Session&, const Glib::ustring& path,
SampleFormat samp_format, HeaderFormat hdr_format, nframes_t rate,
Flag flags = SndFileSource::default_writable_flags);
nframes_t nframes, float sample_rate);
static boost::shared_ptr<Source> createReadable (DataType type, Session&,
- const std::string& path, bool embedded,
+ const std::string& path,
int chn, Source::Flag flags, bool announce = true, bool async = false);
static boost::shared_ptr<Source> createWritable (DataType type, Session&,
- const std::string& path, bool embedded,
+ const std::string& path,
bool destructive, nframes_t rate, bool announce = true, bool async = false);
static Glib::Cond* PeaksToBuild;
/* until we write, this file is considered removable */
chan->write_source->mark_for_remove ();
- cerr << "New write source " << chan->write_source->path() << " flags " << enum_2_string (chan->write_source->flags()) << endl;
return 0;
}
try {
fs = boost::dynamic_pointer_cast<AudioFileSource> (
SourceFactory::createWritable (DataType::AUDIO, _session,
- prop->value(), true,
- false, _session.frame_rate()));
+ prop->value(), false, _session.frame_rate()));
}
catch (failed_constructor& err) {
Glib::StaticPrivate<SizedSampleBuffer> thread_interleave_buffer = GLIBMM_STATIC_PRIVATE_INIT;
/** Constructor used for existing internal-to-session files. */
-AudioFileSource::AudioFileSource (Session& s, const ustring& path, bool embedded, Source::Flag flags)
+AudioFileSource::AudioFileSource (Session& s, const ustring& path, Source::Flag flags)
: Source (s, DataType::AUDIO, path, flags)
, AudioSource (s, path)
- , FileSource (s, DataType::AUDIO, path, embedded, flags)
+ , FileSource (s, DataType::AUDIO, path, flags)
{
- if (init (path, true)) {
+ if (init (_path, true)) {
throw failed_constructor ();
}
+
}
/** Constructor used for new internal-to-session files. */
-AudioFileSource::AudioFileSource (Session& s, const ustring& path, bool embedded, Source::Flag flags,
+AudioFileSource::AudioFileSource (Session& s, const ustring& path, Source::Flag flags,
SampleFormat /*samp_format*/, HeaderFormat /*hdr_format*/)
: Source (s, DataType::AUDIO, path, flags)
, AudioSource (s, path)
- , FileSource (s, DataType::AUDIO, path, embedded, flags)
+ , FileSource (s, DataType::AUDIO, path, flags)
{
- _is_embedded = false;
-
- if (init (path, false)) {
+ if (init (_path, false)) {
throw failed_constructor ();
}
}
-/** Constructor used for existing internal-to-session files. File must exist. */
+/** Constructor used for existing internal-to-session files via XML. File must exist. */
AudioFileSource::AudioFileSource (Session& s, const XMLNode& node, bool must_exist)
: Source (s, node)
, AudioSource (s, node)
if (set_state (node, Stateful::loading_state_version)) {
throw failed_constructor ();
}
-
- if (init (_name, must_exist)) {
+
+ if (init (_path, must_exist)) {
throw failed_constructor ();
}
}
if (Glib::file_test (str, Glib::FILE_TEST_EXISTS)) {
- if (is_embedded()) {
+ if (!within_session()) {
/* it would be nice to rename it but the nature of
the bug means that we can't reliably use it.
: Source (s, node)
, AudioFileSource (s, node)
{
- init ();
+ init_cafile ();
}
CoreAudioSource::CoreAudioSource (Session& s, const string& path, bool, int chn, Flag flags)
Source::Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
{
_channel = chn;
- init ();
+ init_cafile ();
}
void
-CoreAudioSource::init ()
+CoreAudioSource::init_cafile ()
{
/* note that we temporarily truncated _id at the colon */
try {
map<DataType, ustring> FileSource::search_paths;
-FileSource::FileSource (Session& session, DataType type,
- const ustring& path, bool embedded, Source::Flag flag)
+FileSource::FileSource (Session& session, DataType type, const ustring& path, Source::Flag flag)
: Source(session, type, path, flag)
, _path(path)
, _file_is_new(true)
, _channel (0)
- , _is_embedded(embedded)
{
+ set_within_session_from_path (path);
}
FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist*/)
: Source(session, node)
, _file_is_new (false)
{
+ /* this setting of _path is temporary - we expect derived classes
+ to call ::init() which will actually locate the file
+ and reset _path and _within_session correctly.
+ */
+
_path = _name;
- set_embedded_from_name();
+ _within_session = true;
}
bool
throw MissingSource ();
}
- /* XXX is this necessary? or even wise? */
+ set_within_session_from_path (pathstr);
- if (_is_embedded) {
+ if (_within_session) {
_name = Glib::path_get_basename (_name);
}
return 0;
}
-void
-FileSource::set_embedded_from_name ()
-{
- _is_embedded = (_name.find(PATH_SEP) != string::npos);
-}
-
int
FileSource::set_state (const XMLNode& node, int /*version*/)
{
_channel = 0;
}
- set_embedded_from_name();
-
return 0;
}
int
FileSource::move_to_trash (const ustring& trash_dir_name)
{
- if (is_embedded()) {
- cerr << "tried to move an embedded region to trash" << endl;
- return -1;
- }
-
- if (!writable()) {
+ if (!within_session() || !writable()) {
return -1;
}
/** Find the actual source file based on \a filename.
*
- * If the source is embedded, \a filename should be a simple filename (no slashes).
+ * If the source is within the session tree, \a filename should be a simple filename (no slashes).
* If the source is external, \a filename should be a full path.
* In either case, found_path is set to the complete absolute path of the source file.
* \return true iff the file was found.
}
}
+void
+FileSource::set_within_session_from_path (const std::string& path)
+{
+ _within_session = _session.path_is_within_session (path);
+}
try {
nsrcs.push_back (boost::dynamic_pointer_cast<Source> (
SourceFactory::createWritable (region->data_type(), session,
- path, true,
- false, session.frame_rate())));
+ path, false, session.frame_rate())));
}
catch (failed_constructor& err) {
const DataType type = ((*i).rfind(".mid") != string::npos)
? DataType::MIDI : DataType::AUDIO;
+
source = SourceFactory::createWritable (type, sess,
- i->c_str(), true,
+ i->c_str(),
false, // destructive
samplerate);
}
nframes64_t natural_position = source ? source->natural_position() : 0;
if (status.replace_existing_source) {
- fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl;
+ fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
} else {
status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
boost::shared_ptr<MidiSource> newsrc = boost::dynamic_pointer_cast<MidiSource>(
SourceFactory::createWritable(DataType::MIDI, _session,
- newpath, true, false, _session.frame_rate()));
+ newpath, false, _session.frame_rate()));
newsrc->set_timeline_position(_timeline_position);
_model->write_to(newsrc);
return path;
}
-/** Return the full path (in some session directory) for a new embedded source.
+/** Return the full path (in some session directory) for a new within-session source.
* \a name must be a session-unique name that does not contain slashes
* (e.g. as returned by new_*_source_name)
*/
return Glib::path_get_basename(buf);
}
-/** Create a new embedded audio source */
+/** Create a new within-session audio source */
boost::shared_ptr<AudioFileSource>
Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
{
const string path = new_source_path_from_name(DataType::AUDIO, name);
return boost::dynamic_pointer_cast<AudioFileSource> (
- SourceFactory::createWritable (DataType::AUDIO, *this, path, true, destructive, frame_rate()));
+ SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
}
/** Return a unique name based on \a base for a new internal MIDI source */
}
-/** Create a new embedded MIDI source */
+/** Create a new within-session MIDI source */
boost::shared_ptr<MidiSource>
Session::create_midi_source_for_session (MidiDiskstream& ds)
{
return boost::dynamic_pointer_cast<SMFSource> (
SourceFactory::createWritable (
- DataType::MIDI, *this, path, true, false, frame_rate()));
+ DataType::MIDI, *this, path, false, frame_rate()));
}
try {
fsource = boost::dynamic_pointer_cast<AudioFileSource> (
- SourceFactory::createWritable (DataType::AUDIO, *this, buf, true, false, frame_rate()));
+ SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate()));
}
catch (failed_constructor& err) {
request_stop ();
}
}
-/*
-void
-Session::midi_clock_start (Parser& ignored, nframes_t timestamp)
-{
- if (config.get_external_sync() && (config.get_sync_source() == MIDIClock)) {
- request_transport_speed (1.0);
- }
-}
-
-void
-Session::midi_clock_continue (Parser& parser, nframes_t timestamp)
-{
- midi_clock_start (parser, 0);
-}
-
-void
-Session::midi_clock_stop (Parser& ignored, nframes_t timestamp)
-{
- if (config.get_external_sync() && (config.get_slave_source() == MIDIClock)) {
- request_stop ();
- }
-}
-*/
void
Session::mmc_deferred_play (MIDI::MachineControl &/*mmc*/)
last_rr_session_dir = session_dirs.begin();
}
+bool
+Session::path_is_within_session (const std::string& path)
+{
+ for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
+ if (path.find ((*i).path) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
int
Session::ensure_subdirs ()
{
using namespace Glib;
/** Constructor used for new internal-to-session files. File cannot exist. */
-SMFSource::SMFSource (Session& s, const ustring& path, bool embedded, Source::Flag flags)
+SMFSource::SMFSource (Session& s, const ustring& path, Source::Flag flags)
: Source(s, DataType::MIDI, path, flags)
, MidiSource(s, path)
- , FileSource(s, DataType::MIDI, path, embedded, flags)
+ , FileSource(s, DataType::MIDI, path, flags)
, Evoral::SMF()
, _last_ev_time_beats(0.0)
, _last_ev_time_frames(0)
, _smf_last_read_end (0)
{
- if (init(_name, false)) {
+ if (init(_path, false)) {
throw failed_constructor ();
}
throw failed_constructor ();
}
- if (init(_name, true)) {
+ if (init(_path, true)) {
throw failed_constructor ();
}
}
/** Files created this way are never writable or removable */
-SndFileSource::SndFileSource (Session& s, const ustring& path, bool embedded, int chn, Flag flags)
+SndFileSource::SndFileSource (Session& s, const ustring& path, int chn, Flag flags)
: Source(s, DataType::AUDIO, path, flags)
- , AudioFileSource (s, path, embedded,
- Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
+ , AudioFileSource (s, path, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
{
_channel = chn;
}
/** This constructor is used to construct new files, not open existing ones. */
-SndFileSource::SndFileSource (Session& s, const ustring& path, bool embedded,
+SndFileSource::SndFileSource (Session& s, const ustring& path,
SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags)
: Source(s, DataType::AUDIO, path, flags)
- , AudioFileSource (s, path, embedded, flags, sfmt, hf)
+ , AudioFileSource (s, path, flags, sfmt, hf)
{
int fmt = 0;
sf = 0;
_broadcast_info = 0;
- if (is_embedded()) {
- _name = _path;
- } else {
- _name = Glib::path_get_basename (_path);
- }
-
/* although libsndfile says we don't need to set this,
valgrind and source code shows us that we do.
*/
void
Source::mark_for_remove ()
{
- // This operation is not allowed for sources for destructive tracks or embedded files.
- // Fortunately mark_for_remove() is never called for embedded files. This function
- // must be fixed if that ever happens.
- if (_flags & Destructive) {
+ // This operation is not allowed for sources for destructive tracks or out-of-session files.
+
+ /* XXX need a way to detect _within_session() condition here - move it from FileSource?
+ */
+
+ if ((_flags & Destructive)) {
return;
}
}
boost::shared_ptr<Source>
-SourceFactory::createReadable (DataType type, Session& s, const string& path, bool embedded,
- int chn, Source::Flag flags, bool announce, bool defer_peaks)
+SourceFactory::createReadable (DataType type, Session& s, const string& path,
+ int chn, Source::Flag flags, bool announce, bool defer_peaks)
{
if (type == DataType::AUDIO) {
try {
- Source* src = new SndFileSource (s, path, embedded, chn, flags);
+ Source* src = new SndFileSource (s, path, chn, flags);
// boost_debug_shared_ptr_mark_interesting (src, typeid(src).name());
boost::shared_ptr<Source> ret (src);
catch (failed_constructor& err) {
#ifdef USE_COREAUDIO_FOR_FILES
- Source* src = new CoreAudioSource (s, path, embedded, chn, flags);
+ Source* src = new CoreAudioSource (s, path, chn, flags);
// boost_debug_shared_ptr_mark_interesting (src, typeid(src).name());
boost::shared_ptr<Source> ret (src);
if (setup_peakfile (ret, defer_peaks)) {
} else if (type == DataType::MIDI) {
- Source* src = new SMFSource (s, path, embedded, SMFSource::Flag(0));
+ Source* src = new SMFSource (s, path, SMFSource::Flag(0));
// boost_debug_shared_ptr_mark_interesting (src, typeid(src).name());
boost::shared_ptr<Source> ret (src);
}
boost::shared_ptr<Source>
-SourceFactory::createWritable (DataType type, Session& s, const std::string& path, bool embedded,
- bool destructive, nframes_t rate, bool announce, bool defer_peaks)
+SourceFactory::createWritable (DataType type, Session& s, const std::string& path,
+ bool destructive, nframes_t rate, bool announce, bool defer_peaks)
{
/* this might throw failed_constructor(), which is OK */
if (type == DataType::AUDIO) {
- Source* src = new SndFileSource (s, path, embedded,
+ Source* src = new SndFileSource (s, path,
s.config.get_native_file_data_format(),
s.config.get_native_file_header_format(),
rate,
} else if (type == DataType::MIDI) {
- Source* src = new SMFSource (s, path, embedded, Source::Flag(0));
+ Source* src = new SMFSource (s, path, Source::Flag(0));
// boost_debug_shared_ptr_mark_interesting (src, typeid(src).name());
boost::shared_ptr<Source> ret (src);