remove entire "stub" file concept; open new audio and MIDI files on demand (at first write); could be a few gotchas with some corner case scenarios, but apparently works OK

git-svn-id: svn://localhost/ardour2/branches/3.0@9038 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2011-03-02 17:05:16 +00:00
parent 488d54a341
commit 5e431d1d58
17 changed files with 133 additions and 260 deletions

View file

@ -19,7 +19,6 @@ extern const char* const templates_dir_name;
extern const char* const route_templates_dir_name; extern const char* const route_templates_dir_name;
extern const char* const surfaces_dir_name; extern const char* const surfaces_dir_name;
extern const char* const user_config_dir_name; extern const char* const user_config_dir_name;
extern const char* const stub_dir_name;
extern const char* const panner_dir_name; extern const char* const panner_dir_name;
}; };

View file

@ -48,12 +48,6 @@ public:
const std::string& path() const { return _path; } const std::string& path() const { return _path; }
int unstubify ();
void stubify ();
bool is_stub () const;
static bool is_stub_path (const std::string& path);
virtual bool safe_file_extension (const std::string& path) const = 0; virtual bool safe_file_extension (const std::string& path) const = 0;
int move_to_trash (const std::string& trash_dir_name); int move_to_trash (const std::string& trash_dir_name);
@ -104,6 +98,7 @@ protected:
uint16_t _channel; uint16_t _channel;
bool _within_session; bool _within_session;
std::string _origin; std::string _origin;
bool _open;
void prevent_deletion (); void prevent_deletion ();
}; };

View file

@ -78,7 +78,7 @@ class MidiSource : virtual public Source, public boost::enable_shared_from_this<
virtual framecnt_t length (framepos_t pos) const; virtual framecnt_t length (framepos_t pos) const;
virtual void update_length (framepos_t pos, framecnt_t cnt); virtual void update_length (framepos_t pos, framecnt_t cnt);
virtual void mark_streaming_midi_write_started (NoteMode mode, framepos_t start_time); virtual void mark_streaming_midi_write_started (NoteMode mode);
virtual void mark_streaming_write_started (); virtual void mark_streaming_write_started ();
virtual void mark_streaming_write_completed (); virtual void mark_streaming_write_completed ();
void mark_write_starting_now (); void mark_write_starting_now ();

View file

@ -187,7 +187,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
std::string peak_path_from_audio_path (std::string) const; std::string peak_path_from_audio_path (std::string) const;
std::string new_audio_source_name (const std::string&, uint32_t nchans, uint32_t chan, bool destructive); std::string new_audio_source_name (const std::string&, uint32_t nchans, uint32_t chan, bool destructive);
std::string new_midi_source_name (const std::string&); std::string new_midi_source_name (const std::string&);
std::string new_source_path_from_name (DataType type, const std::string&, bool as_stub = false); std::string new_source_path_from_name (DataType type, const std::string&);
RouteList new_route_from_template (uint32_t how_many, const std::string& template_path); RouteList new_route_from_template (uint32_t how_many, const std::string& template_path);
void process (pframes_t nframes); void process (pframes_t nframes);
@ -543,10 +543,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
static PBD::Signal0<int> AskAboutPendingState; static PBD::Signal0<int> AskAboutPendingState;
boost::shared_ptr<AudioFileSource> create_audio_source_for_session ( boost::shared_ptr<AudioFileSource> create_audio_source_for_session (
size_t, std::string const &, uint32_t, bool destructive, bool as_stub = false); size_t, std::string const &, uint32_t, bool destructive);
boost::shared_ptr<MidiSource> create_midi_source_for_session ( boost::shared_ptr<MidiSource> create_midi_source_for_session (
Track*, std::string const &, bool as_stub = false); Track*, std::string const &);
boost::shared_ptr<Source> source_by_id (const PBD::ID&); boost::shared_ptr<Source> source_by_id (const PBD::ID&);
boost::shared_ptr<Source> source_by_path_and_channel (const std::string&, uint16_t); boost::shared_ptr<Source> source_by_path_and_channel (const std::string&, uint16_t);
@ -1472,7 +1472,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void add_session_range_location (framepos_t, framepos_t); void add_session_range_location (framepos_t, framepos_t);
void setup_midi_machine_control (); void setup_midi_machine_control ();
void cleanup_stubfiles ();
void route_order_key_changed (); void route_order_key_changed ();

View file

@ -51,17 +51,6 @@ public:
*/ */
const PBD::sys::path sound_path () const; const PBD::sys::path sound_path () const;
/**
* @return the absolute path to the directory in which
* the session stores STUB audio files.
*
* If the session is an older session with an existing
* "sounds" directory then it will return a path to that
* directory otherwise it will return the new location
* of root_path()/interchange/session_name/audiofiles/.stubs
*/
const PBD::sys::path sound_stub_path () const;
/** /**
* @return the absolute path to the directory in which * @return the absolute path to the directory in which
* the session stores MIDI files, ie * the session stores MIDI files, ie
@ -69,13 +58,6 @@ public:
*/ */
const PBD::sys::path midi_path () const; const PBD::sys::path midi_path () const;
/**
* @return the absolute path to the directory in which
* the session stores STUB MIDI files, ie
* root_path()/interchange/session_name/midifiles/.stubs
*/
const PBD::sys::path midi_stub_path () const;
/** /**
* @return the absolute path to the directory in which * @return the absolute path to the directory in which
* the session stores MIDNAM patch files, ie * the session stores MIDNAM patch files, ie

View file

@ -54,7 +54,7 @@ public:
void append_event_unlocked_beats (const Evoral::Event<Evoral::MusicalTime>& ev); void append_event_unlocked_beats (const Evoral::Event<Evoral::MusicalTime>& ev);
void append_event_unlocked_frames (const Evoral::Event<framepos_t>& ev, framepos_t source_start); void append_event_unlocked_frames (const Evoral::Event<framepos_t>& ev, framepos_t source_start);
void mark_streaming_midi_write_started (NoteMode mode, framepos_t start_time); void mark_streaming_midi_write_started (NoteMode mode);
void mark_streaming_write_completed (); void mark_streaming_write_completed ();
XMLNode& get_state (); XMLNode& get_state ();
@ -73,6 +73,8 @@ public:
void set_path (const std::string& newpath); void set_path (const std::string& newpath);
private: private:
int open_for_write ();
framecnt_t read_unlocked (Evoral::EventSink<framepos_t>& dst, framecnt_t read_unlocked (Evoral::EventSink<framepos_t>& dst,
framepos_t position, framepos_t position,
framepos_t start, framepos_t start,

View file

@ -1425,9 +1425,6 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo
if (s) { if (s) {
srcs.push_back (s); srcs.push_back (s);
if (s->unstubify ()) {
error << string_compose (_("Could not move capture file from %1"), s->path()) << endmsg;
}
s->update_header (capture_info.front()->start, when, twhen); s->update_header (capture_info.front()->start, when, twhen);
s->set_captured_for (_name.val()); s->set_captured_for (_name.val());
s->mark_immutable (); s->mark_immutable ();
@ -1903,13 +1900,8 @@ AudioDiskstream::use_new_write_source (uint32_t n)
ChannelInfo* chan = (*c)[n]; ChannelInfo* chan = (*c)[n];
try { try {
/* file starts off as a stub file, it will be converted
when we're done with a capture pass.
*/
if ((chan->write_source = _session.create_audio_source_for_session (n_channels().n_audio(), if ((chan->write_source = _session.create_audio_source_for_session (n_channels().n_audio(),
name(), n, destructive(), name(), n, destructive())) == 0) {
true)) == 0) {
throw failed_constructor(); throw failed_constructor();
} }
} }

View file

@ -16,7 +16,6 @@ const char* const templates_dir_name = X_("templates");
const char* const route_templates_dir_name = X_("route_templates"); const char* const route_templates_dir_name = X_("route_templates");
const char* const surfaces_dir_name = X_("surfaces"); const char* const surfaces_dir_name = X_("surfaces");
const char* const user_config_dir_name = X_("ardour3"); const char* const user_config_dir_name = X_("ardour3");
const char* const stub_dir_name = X_(".stubs");
const char* const panner_dir_name = X_("panners"); const char* const panner_dir_name = X_("panners");
} }

View file

@ -60,6 +60,7 @@ FileSource::FileSource (Session& session, DataType type, const string& path, con
, _file_is_new(true) , _file_is_new(true)
, _channel (0) , _channel (0)
, _origin (origin) , _origin (origin)
, _open (false)
{ {
set_within_session_from_path (path); set_within_session_from_path (path);
@ -99,8 +100,7 @@ FileSource::prevent_deletion ()
bool bool
FileSource::removable () const FileSource::removable () const
{ {
bool r = (_path.find (stub_dir_name) != string::npos) || bool r = ((_flags & Removable)
((_flags & Removable)
&& ((_flags & RemoveAtDestroy) || && ((_flags & RemoveAtDestroy) ||
((_flags & RemovableIfEmpty) && empty() == 0))); ((_flags & RemovableIfEmpty) && empty() == 0)));
@ -537,44 +537,6 @@ FileSource::set_within_session_from_path (const std::string& path)
_within_session = _session.path_is_within_session (path); _within_session = _session.path_is_within_session (path);
} }
bool
FileSource::is_stub_path (const std::string& path)
{
return path.find (stub_dir_name) != string::npos;
}
bool
FileSource::is_stub () const
{
return is_stub_path (_path);
}
int
FileSource::unstubify ()
{
string::size_type pos = _path.find (stub_dir_name);
if (pos == string::npos || (_flags & Destructive)) {
return 0;
}
vector<string> v;
v.push_back (Glib::path_get_dirname (Glib::path_get_dirname (_path)));
v.push_back (Glib::path_get_basename(_path));
string newpath = Glib::build_filename (v);
if (::rename (_path.c_str(), newpath.c_str()) != 0) {
error << string_compose (_("rename from %1 to %2 failed: %3)"), _path, newpath, strerror (errno)) << endmsg;
return -1;
}
set_path (newpath);
return 0;
}
void void
FileSource::set_path (const std::string& newpath) FileSource::set_path (const std::string& newpath)
{ {

View file

@ -981,10 +981,6 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
const double total_capture_beats = converter.from(total_capture); const double total_capture_beats = converter.from(total_capture);
_write_source->set_length_beats(total_capture_beats); _write_source->set_length_beats(total_capture_beats);
/* make it not a stub anymore */
_write_source->unstubify ();
/* we will want to be able to keep (over)writing the source /* we will want to be able to keep (over)writing the source
but we don't want it to be removable. this also differs but we don't want it to be removable. this also differs
from the audio situation, where the source at this point from the audio situation, where the source at this point
@ -1366,13 +1362,8 @@ MidiDiskstream::use_new_write_source (uint32_t n)
_write_source.reset(); _write_source.reset();
try { try {
/* file starts off as a stub file, it will be converted
when we're done with a capture pass, or when "stolen"
by the GUI.
*/
_write_source = boost::dynamic_pointer_cast<SMFSource>( _write_source = boost::dynamic_pointer_cast<SMFSource>(
_session.create_midi_source_for_session (0, name (), true)); _session.create_midi_source_for_session (0, name ()));
if (!_write_source) { if (!_write_source) {
throw failed_constructor(); throw failed_constructor();
@ -1385,8 +1376,6 @@ MidiDiskstream::use_new_write_source (uint32_t n)
return -1; return -1;
} }
_write_source->mark_streaming_midi_write_started (_note_mode, _session.transport_frame());
return 0; return 0;
} }
@ -1403,8 +1392,6 @@ MidiDiskstream::steal_write_sources()
boost::dynamic_pointer_cast<MidiSource>(_write_source)->session_saved (); boost::dynamic_pointer_cast<MidiSource>(_write_source)->session_saved ();
/* make it visible/present */
_write_source->unstubify ();
/* never let it go away */ /* never let it go away */
_write_source->mark_nonremovable (); _write_source->mark_nonremovable ();

View file

@ -1335,7 +1335,7 @@ MidiModel::write_to (boost::shared_ptr<MidiSource> source)
assert (ms); assert (ms);
source->drop_model(); source->drop_model();
source->mark_streaming_midi_write_started (note_mode(), ms->timeline_position ()); source->mark_streaming_midi_write_started (note_mode());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) { for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) {
source->append_event_unlocked_beats(*i); source->append_event_unlocked_beats(*i);
@ -1365,7 +1365,7 @@ MidiModel::sync_to_source ()
boost::shared_ptr<MidiSource> ms = _midi_source.lock (); boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
assert (ms); assert (ms);
ms->mark_streaming_midi_write_started (note_mode(), ms->timeline_position()); ms->mark_streaming_midi_write_started (note_mode());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) { for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) {
ms->append_event_unlocked_beats(*i); ms->append_event_unlocked_beats(*i);
@ -1400,7 +1400,7 @@ MidiModel::write_section_to (boost::shared_ptr<MidiSource> source, Evoral::Music
assert (ms); assert (ms);
source->drop_model(); source->drop_model();
source->mark_streaming_midi_write_started (note_mode(), ms->timeline_position()); source->mark_streaming_midi_write_started (note_mode());
for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) { for (Evoral::Sequence<TimeType>::const_iterator i = begin(0, true); i != end(); ++i) {
const Evoral::Event<Evoral::MusicalTime>& ev (*i); const Evoral::Event<Evoral::MusicalTime>& ev (*i);

View file

@ -265,7 +265,7 @@ MidiSource::midi_write (MidiRingBuffer<framepos_t>& source, framepos_t source_st
} }
void void
MidiSource::mark_streaming_midi_write_started (NoteMode mode, framepos_t start_frame) MidiSource::mark_streaming_midi_write_started (NoteMode mode)
{ {
if (_model) { if (_model) {
_model->set_note_mode (mode); _model->set_note_mode (mode);
@ -297,7 +297,7 @@ void
MidiSource::mark_streaming_write_started () MidiSource::mark_streaming_write_started ()
{ {
NoteMode note_mode = _model ? _model->note_mode() : Sustained; NoteMode note_mode = _model ? _model->note_mode() : Sustained;
mark_streaming_midi_write_started(note_mode, _session.transport_frame()); mark_streaming_midi_write_started (note_mode);
} }
void void

View file

@ -238,10 +238,6 @@ Session::destroy ()
delete state_tree; delete state_tree;
/* remove all stubfiles that might still be lurking */
cleanup_stubfiles ();
/* reset dynamic state version back to default */ /* reset dynamic state version back to default */
Stateful::loading_state_version = 0; Stateful::loading_state_version = 0;
@ -2878,7 +2874,7 @@ Session::change_source_path_by_name (string path, string oldname, string newname
* (e.g. as returned by new_*_source_name) * (e.g. as returned by new_*_source_name)
*/ */
string string
Session::new_source_path_from_name (DataType type, const string& name, bool as_stub) Session::new_source_path_from_name (DataType type, const string& name)
{ {
assert(name.find("/") == string::npos); assert(name.find("/") == string::npos);
@ -2886,9 +2882,9 @@ Session::new_source_path_from_name (DataType type, const string& name, bool as_s
sys::path p; sys::path p;
if (type == DataType::AUDIO) { if (type == DataType::AUDIO) {
p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path()); p = sdir.sound_path();
} else if (type == DataType::MIDI) { } else if (type == DataType::MIDI) {
p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path()); p = sdir.midi_path();
} else { } else {
error << "Unknown source type, unable to create file path" << endmsg; error << "Unknown source type, unable to create file path" << endmsg;
return ""; return "";
@ -2968,7 +2964,6 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
SessionDirectory sdir((*i).path); SessionDirectory sdir((*i).path);
string spath = sdir.sound_path().to_string(); string spath = sdir.sound_path().to_string();
string spath_stubs = sdir.sound_stub_path().to_string();
/* note that we search *without* the extension so that /* note that we search *without* the extension so that
we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf" we don't end up both "Audio 1-1.wav" and "Audio 1-1.caf"
@ -2976,8 +2971,7 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
a file format change. a file format change.
*/ */
if (matching_unsuffixed_filename_exists_in (spath, buf) || if (matching_unsuffixed_filename_exists_in (spath, buf)) {
matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
existing++; existing++;
break; break;
} }
@ -3001,10 +2995,10 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
/** Create a new within-session audio source */ /** Create a new within-session audio source */
boost::shared_ptr<AudioFileSource> boost::shared_ptr<AudioFileSource>
Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub) Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive)
{ {
const string name = new_audio_source_name (n, n_chans, chan, destructive); const string name = new_audio_source_name (n, n_chans, chan, destructive);
const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub); const string path = new_source_path_from_name(DataType::AUDIO, name);
return boost::dynamic_pointer_cast<AudioFileSource> ( return boost::dynamic_pointer_cast<AudioFileSource> (
SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate())); SourceFactory::createWritable (DataType::AUDIO, *this, path, string(), destructive, frame_rate()));
@ -3061,7 +3055,7 @@ Session::new_midi_source_name (const string& base)
/** Create a new within-session MIDI source */ /** Create a new within-session MIDI source */
boost::shared_ptr<MidiSource> boost::shared_ptr<MidiSource>
Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub) Session::create_midi_source_for_session (Track* track, string const & n)
{ {
/* try to use the existing write source for the track, to keep numbering sane /* try to use the existing write source for the track, to keep numbering sane
*/ */
@ -3080,7 +3074,7 @@ Session::create_midi_source_for_session (Track* track, string const & n, bool as
} }
const string name = new_midi_source_name (n); const string name = new_midi_source_name (n);
const string path = new_source_path_from_name (DataType::MIDI, name, as_stub); const string path = new_source_path_from_name (DataType::MIDI, name);
return boost::dynamic_pointer_cast<SMFSource> ( return boost::dynamic_pointer_cast<SMFSource> (
SourceFactory::createWritable ( SourceFactory::createWritable (

View file

@ -101,27 +101,12 @@ SessionDirectory::sound_path () const
return sources_root() / sound_dir_name; return sources_root() / sound_dir_name;
} }
const path
SessionDirectory::sound_stub_path () const
{
if(is_directory (old_sound_path ())) return old_sound_path();
// the new style sound directory
return sources_root() / sound_dir_name / stub_dir_name;
}
const path const path
SessionDirectory::midi_path () const SessionDirectory::midi_path () const
{ {
return sources_root() / midi_dir_name; return sources_root() / midi_dir_name;
} }
const path
SessionDirectory::midi_stub_path () const
{
return sources_root() / midi_dir_name / stub_dir_name;
}
const path const path
SessionDirectory::midi_patch_path () const SessionDirectory::midi_patch_path () const
{ {

View file

@ -467,13 +467,6 @@ Session::ensure_subdirs ()
return -1; return -1;
} }
dir = session_directory().sound_stub_path().to_string();
if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
error << string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
return -1;
}
dir = session_directory().midi_path().to_string(); dir = session_directory().midi_path().to_string();
if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
@ -481,13 +474,6 @@ Session::ensure_subdirs ()
return -1; return -1;
} }
dir = session_directory().midi_stub_path().to_string();
if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
error << string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
return -1;
}
dir = session_directory().dead_path().to_string(); dir = session_directory().dead_path().to_string();
if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
@ -1236,8 +1222,6 @@ Session::set_state (const XMLNode& node, int version)
setup_raid_path(_session_dir->root_path().to_string()); setup_raid_path(_session_dir->root_path().to_string());
cleanup_stubfiles ();
if ((prop = node.property (X_("id-counter"))) != 0) { if ((prop = node.property (X_("id-counter"))) != 0) {
uint64_t x; uint64_t x;
sscanf (prop->value().c_str(), "%" PRIu64, &x); sscanf (prop->value().c_str(), "%" PRIu64, &x);
@ -2416,16 +2400,12 @@ Session::commit_reversible_command (Command *cmd)
} }
static bool static bool
accept_all_non_stub_audio_files (const string& path, void */*arg*/) accept_all_audio_files (const string& path, void */*arg*/)
{ {
if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) { if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
return false; return false;
} }
if (FileSource::is_stub_path (path)) {
return false;
}
if (!AudioFileSource::safe_audio_file_extension (path)) { if (!AudioFileSource::safe_audio_file_extension (path)) {
return false; return false;
} }
@ -2434,16 +2414,12 @@ accept_all_non_stub_audio_files (const string& path, void */*arg*/)
} }
static bool static bool
accept_all_non_stub_midi_files (const string& path, void */*arg*/) accept_all_midi_files (const string& path, void */*arg*/)
{ {
if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) { if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
return false; return false;
} }
if (FileSource::is_stub_path (path)) {
return false;
}
return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) || return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
(path.length() > 4 && path.find (".smf") != (path.length() - 4)) || (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
(path.length() > 5 && path.find (".midi") != (path.length() - 5))); (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
@ -2686,8 +2662,8 @@ Session::cleanup_sources (CleanupReport& rep)
i = nexti; i = nexti;
} }
candidates = scanner (audio_path, accept_all_non_stub_audio_files, (void *) 0, true, true); candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
candidates2 = scanner (midi_path, accept_all_non_stub_midi_files, (void *) 0, true, true); candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
/* merge them */ /* merge them */
@ -2718,7 +2694,6 @@ Session::cleanup_sources (CleanupReport& rep)
++tmp; ++tmp;
if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) { if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
if (!fs->is_stub()) {
if (playlists->source_use_count (fs) != 0) { if (playlists->source_use_count (fs) != 0) {
all_sources.insert (fs->path()); all_sources.insert (fs->path());
} else { } else {
@ -2729,13 +2704,10 @@ Session::cleanup_sources (CleanupReport& rep)
in the region list. in the region list.
*/ */
cerr << "Source " << i->second->name() << "ID " << i->second->id() << " not used, remove from source list and also all regions\n";
RegionFactory::remove_regions_using_source (i->second); RegionFactory::remove_regions_using_source (i->second);
sources.erase (i); sources.erase (i);
} }
} }
}
i = tmp; i = tmp;
} }
@ -2920,45 +2892,6 @@ Session::cleanup_trash_sources (CleanupReport& rep)
return 0; return 0;
} }
void
Session::cleanup_stubfiles ()
{
vector<space_and_path>::iterator i;
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
string dir;
string lname = legalize_for_path (_name);
vector<string> v;
/* XXX this is a hack caused by semantic conflicts
between space_and_path and the SessionDirectory concept.
*/
v.push_back ((*i).path);
v.push_back ("interchange");
v.push_back (lname);
v.push_back ("audiofiles");
v.push_back (stub_dir_name);
dir = Glib::build_filename (v);
clear_directory (dir);
v.clear ();
v.push_back ((*i).path);
v.push_back ("interchange");
v.push_back (lname);
v.push_back ("midifiles");
v.push_back (stub_dir_name);
dir = Glib::build_filename (v);
clear_directory (dir);
}
}
void void
Session::set_dirty () Session::set_dirty ()
{ {

View file

@ -66,9 +66,7 @@ SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags)
throw failed_constructor (); throw failed_constructor ();
} }
if (create(path)) { /* file is not opened until write */
throw failed_constructor ();
}
} }
/** Constructor used for existing internal-to-session files. */ /** Constructor used for existing internal-to-session files. */
@ -92,6 +90,8 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist)
if (open(_path)) { if (open(_path)) {
throw failed_constructor (); throw failed_constructor ();
} }
_open = true;
} }
SMFSource::~SMFSource () SMFSource::~SMFSource ()
@ -101,6 +101,16 @@ SMFSource::~SMFSource ()
} }
} }
int
SMFSource::open_for_write ()
{
if (create (_path)) {
return -1;
}
_open = true;
return 0;
}
/** All stamps in audio frames */ /** All stamps in audio frames */
framecnt_t framecnt_t
SMFSource::read_unlocked (Evoral::EventSink<framepos_t>& destination, framepos_t const source_start, SMFSource::read_unlocked (Evoral::EventSink<framepos_t>& destination, framepos_t const source_start,
@ -110,6 +120,11 @@ SMFSource::read_unlocked (Evoral::EventSink<framepos_t>& destination, framepos_t
int ret = 0; int ret = 0;
uint64_t time = 0; // in SMF ticks, 1 tick per _ppqn uint64_t time = 0; // in SMF ticks, 1 tick per _ppqn
if (writable() && !_open) {
/* nothing to read since nothing has ben written */
return duration;
}
DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: start %1 duration %2\n", start, duration)); DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: start %1 duration %2\n", start, duration));
_read_data_count = 0; _read_data_count = 0;
@ -206,6 +221,15 @@ SMFSource::read_unlocked (Evoral::EventSink<framepos_t>& destination, framepos_t
framecnt_t framecnt_t
SMFSource::write_unlocked (MidiRingBuffer<framepos_t>& source, framepos_t position, framecnt_t duration) SMFSource::write_unlocked (MidiRingBuffer<framepos_t>& source, framepos_t position, framecnt_t duration)
{ {
if (!_open && open_for_write()) {
error << string_compose (_("cannot open MIDI file %1 for write"), _path) << endmsg;
return 0;
}
if (!_writing) {
mark_streaming_write_started ();
}
_write_data_count = 0; _write_data_count = 0;
framepos_t time; framepos_t time;
@ -387,10 +411,11 @@ SMFSource::set_state (const XMLNode& node, int version)
} }
void void
SMFSource::mark_streaming_midi_write_started (NoteMode mode, framepos_t start_frame) SMFSource::mark_streaming_midi_write_started (NoteMode mode)
{ {
Glib::Mutex::Lock lm (_lock); /* CALLER MUST HOLD LOCK */
MidiSource::mark_streaming_midi_write_started (mode, start_frame);
MidiSource::mark_streaming_midi_write_started (mode);
Evoral::SMF::begin_write (); Evoral::SMF::begin_write ();
_last_ev_time_beats = 0.0; _last_ev_time_beats = 0.0;
_last_ev_time_frames = 0; _last_ev_time_frames = 0;
@ -444,6 +469,10 @@ SMFSource::load_model (bool lock, bool force_reload)
_model->clear(); _model->clear();
} }
if (writable() && !_open) {
return;
}
_model->start_write(); _model->start_write();
Evoral::SMF::seek_to_start(); Evoral::SMF::seek_to_start();
@ -533,7 +562,7 @@ SMFSource::destroy_model ()
void void
SMFSource::flush_midi () SMFSource::flush_midi ()
{ {
if (!writable()) { if (!writable() || (writable() && !_open)) {
return; return;
} }

View file

@ -144,36 +144,8 @@ SndFileSource::SndFileSource (Session& s, const string& path, const string& orig
_info.samplerate = rate; _info.samplerate = rate;
_info.format = fmt; _info.format = fmt;
if (open()) { /* do not open the file here - do that in write_unlocked() as needed
throw failed_constructor(); */
}
if (writable() && (_flags & Broadcast)) {
SNDFILE* sf = _descriptor->allocate ();
if (sf == 0) {
error << string_compose (_("could not allocate file %1"), _path) << endmsg;
throw failed_constructor ();
}
if (!_broadcast_info) {
_broadcast_info = new BroadcastInfo;
}
_broadcast_info->set_from_session (s, header_position_offset);
_broadcast_info->set_description (string_compose ("BWF %1", _name));
if (!_broadcast_info->write_to_file (sf)) {
error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
_path, _broadcast_info->get_error())
<< endmsg;
_flags = Flag (_flags & ~Broadcast);
delete _broadcast_info;
_broadcast_info = 0;
}
_descriptor->release ();
}
} }
void void
@ -181,6 +153,8 @@ SndFileSource::init_sndfile ()
{ {
string file; string file;
_descriptor = 0;
// lets try to keep the object initalizations here at the top // lets try to keep the object initalizations here at the top
xfade_buf = 0; xfade_buf = 0;
_broadcast_info = 0; _broadcast_info = 0;
@ -253,9 +227,29 @@ SndFileSource::open ()
if (writable()) { if (writable()) {
sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE); sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE);
if (_flags & Broadcast) {
if (!_broadcast_info) {
_broadcast_info = new BroadcastInfo;
}
_broadcast_info->set_from_session (_session, header_position_offset);
_broadcast_info->set_description (string_compose ("BWF %1", _name));
if (!_broadcast_info->write_to_file (sf)) {
error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
_path, _broadcast_info->get_error())
<< endmsg;
_flags = Flag (_flags & ~Broadcast);
delete _broadcast_info;
_broadcast_info = 0;
}
}
} }
_descriptor->release (); _descriptor->release ();
_open = true;
return 0; return 0;
} }
@ -280,7 +274,14 @@ SndFileSource::read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) con
uint32_t real_cnt; uint32_t real_cnt;
framepos_t file_cnt; framepos_t file_cnt;
if (writable() && !_open) {
/* file has not been opened yet - nothing written to it */
memset (dst, 0, sizeof (Sample) * cnt);
return cnt;
}
SNDFILE* sf = _descriptor->allocate (); SNDFILE* sf = _descriptor->allocate ();
if (sf == 0) { if (sf == 0) {
error << string_compose (_("could not allocate file %1 for reading."), _path) << endmsg; error << string_compose (_("could not allocate file %1 for reading."), _path) << endmsg;
return 0; return 0;
@ -357,6 +358,10 @@ SndFileSource::read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) con
framecnt_t framecnt_t
SndFileSource::write_unlocked (Sample *data, framecnt_t cnt) SndFileSource::write_unlocked (Sample *data, framecnt_t cnt)
{ {
if (!_open && open()) {
return 0; // failure
}
if (destructive()) { if (destructive()) {
return destructive_write_unlocked (data, cnt); return destructive_write_unlocked (data, cnt);
} else { } else {
@ -511,6 +516,11 @@ SndFileSource::flush_header ()
return -1; return -1;
} }
if (!_open) {
warning << string_compose (_("attempt to flush an un-opened audio file source (%1)"), _path) << endmsg;
return -1;
}
SNDFILE* sf = _descriptor->allocate (); SNDFILE* sf = _descriptor->allocate ();
if (sf == 0) { if (sf == 0) {
error << string_compose (_("could not allocate file %1 to write header"), _path) << endmsg; error << string_compose (_("could not allocate file %1 to write header"), _path) << endmsg;
@ -531,6 +541,11 @@ SndFileSource::setup_broadcast_info (framepos_t /*when*/, struct tm& now, time_t
return -1; return -1;
} }
if (!_open) {
warning << string_compose (_("attempt to set BWF info for an un-opened audio file source (%1)"), _path) << endmsg;
return -1;
}
if (!(_flags & Broadcast)) { if (!(_flags & Broadcast)) {
return 0; return 0;
} }