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:
parent
488d54a341
commit
5e431d1d58
|
@ -19,7 +19,6 @@ extern const char* const templates_dir_name;
|
|||
extern const char* const route_templates_dir_name;
|
||||
extern const char* const surfaces_dir_name;
|
||||
extern const char* const user_config_dir_name;
|
||||
extern const char* const stub_dir_name;
|
||||
extern const char* const panner_dir_name;
|
||||
|
||||
};
|
||||
|
|
|
@ -48,12 +48,6 @@ public:
|
|||
|
||||
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;
|
||||
|
||||
int move_to_trash (const std::string& trash_dir_name);
|
||||
|
@ -104,7 +98,8 @@ protected:
|
|||
uint16_t _channel;
|
||||
bool _within_session;
|
||||
std::string _origin;
|
||||
|
||||
bool _open;
|
||||
|
||||
void prevent_deletion ();
|
||||
};
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ class MidiSource : virtual public Source, public boost::enable_shared_from_this<
|
|||
virtual framecnt_t length (framepos_t pos) const;
|
||||
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_completed ();
|
||||
void mark_write_starting_now ();
|
||||
|
|
|
@ -187,7 +187,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
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_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);
|
||||
|
||||
void process (pframes_t nframes);
|
||||
|
@ -543,10 +543,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
static PBD::Signal0<int> AskAboutPendingState;
|
||||
|
||||
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 (
|
||||
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_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 setup_midi_machine_control ();
|
||||
void cleanup_stubfiles ();
|
||||
|
||||
void route_order_key_changed ();
|
||||
|
||||
|
|
|
@ -51,17 +51,6 @@ public:
|
|||
*/
|
||||
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
|
||||
* the session stores MIDI files, ie
|
||||
|
@ -69,13 +58,6 @@ public:
|
|||
*/
|
||||
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
|
||||
* the session stores MIDNAM patch files, ie
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
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 mark_streaming_midi_write_started (NoteMode mode, framepos_t start_time);
|
||||
void mark_streaming_midi_write_started (NoteMode mode);
|
||||
void mark_streaming_write_completed ();
|
||||
|
||||
XMLNode& get_state ();
|
||||
|
@ -73,6 +73,8 @@ public:
|
|||
void set_path (const std::string& newpath);
|
||||
|
||||
private:
|
||||
int open_for_write ();
|
||||
|
||||
framecnt_t read_unlocked (Evoral::EventSink<framepos_t>& dst,
|
||||
framepos_t position,
|
||||
framepos_t start,
|
||||
|
|
|
@ -1425,9 +1425,6 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo
|
|||
|
||||
if (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->set_captured_for (_name.val());
|
||||
s->mark_immutable ();
|
||||
|
@ -1903,13 +1900,8 @@ AudioDiskstream::use_new_write_source (uint32_t n)
|
|||
ChannelInfo* chan = (*c)[n];
|
||||
|
||||
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(),
|
||||
name(), n, destructive(),
|
||||
true)) == 0) {
|
||||
name(), n, destructive())) == 0) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 surfaces_dir_name = X_("surfaces");
|
||||
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");
|
||||
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ FileSource::FileSource (Session& session, DataType type, const string& path, con
|
|||
, _file_is_new(true)
|
||||
, _channel (0)
|
||||
, _origin (origin)
|
||||
, _open (false)
|
||||
{
|
||||
set_within_session_from_path (path);
|
||||
|
||||
|
@ -99,11 +100,10 @@ FileSource::prevent_deletion ()
|
|||
bool
|
||||
FileSource::removable () const
|
||||
{
|
||||
bool r = (_path.find (stub_dir_name) != string::npos) ||
|
||||
((_flags & Removable)
|
||||
&& ((_flags & RemoveAtDestroy) ||
|
||||
((_flags & RemovableIfEmpty) && empty() == 0)));
|
||||
|
||||
bool r = ((_flags & Removable)
|
||||
&& ((_flags & RemoveAtDestroy) ||
|
||||
((_flags & RemovableIfEmpty) && empty() == 0)));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -537,44 +537,6 @@ FileSource::set_within_session_from_path (const std::string& 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
|
||||
FileSource::set_path (const std::string& newpath)
|
||||
{
|
||||
|
|
|
@ -981,10 +981,6 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
|
|||
const double total_capture_beats = converter.from(total_capture);
|
||||
_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
|
||||
but we don't want it to be removable. this also differs
|
||||
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();
|
||||
|
||||
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>(
|
||||
_session.create_midi_source_for_session (0, name (), true));
|
||||
_session.create_midi_source_for_session (0, name ()));
|
||||
|
||||
if (!_write_source) {
|
||||
throw failed_constructor();
|
||||
|
@ -1385,8 +1376,6 @@ MidiDiskstream::use_new_write_source (uint32_t n)
|
|||
return -1;
|
||||
}
|
||||
|
||||
_write_source->mark_streaming_midi_write_started (_note_mode, _session.transport_frame());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1403,8 +1392,6 @@ MidiDiskstream::steal_write_sources()
|
|||
|
||||
boost::dynamic_pointer_cast<MidiSource>(_write_source)->session_saved ();
|
||||
|
||||
/* make it visible/present */
|
||||
_write_source->unstubify ();
|
||||
/* never let it go away */
|
||||
_write_source->mark_nonremovable ();
|
||||
|
||||
|
|
|
@ -1335,7 +1335,7 @@ MidiModel::write_to (boost::shared_ptr<MidiSource> source)
|
|||
assert (ms);
|
||||
|
||||
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) {
|
||||
source->append_event_unlocked_beats(*i);
|
||||
|
@ -1365,7 +1365,7 @@ MidiModel::sync_to_source ()
|
|||
boost::shared_ptr<MidiSource> ms = _midi_source.lock ();
|
||||
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) {
|
||||
ms->append_event_unlocked_beats(*i);
|
||||
|
@ -1400,7 +1400,7 @@ MidiModel::write_section_to (boost::shared_ptr<MidiSource> source, Evoral::Music
|
|||
assert (ms);
|
||||
|
||||
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) {
|
||||
const Evoral::Event<Evoral::MusicalTime>& ev (*i);
|
||||
|
|
|
@ -265,11 +265,11 @@ MidiSource::midi_write (MidiRingBuffer<framepos_t>& source, framepos_t source_st
|
|||
}
|
||||
|
||||
void
|
||||
MidiSource::mark_streaming_midi_write_started (NoteMode mode, framepos_t start_frame)
|
||||
MidiSource::mark_streaming_midi_write_started (NoteMode mode)
|
||||
{
|
||||
if (_model) {
|
||||
_model->set_note_mode(mode);
|
||||
_model->start_write();
|
||||
_model->set_note_mode (mode);
|
||||
_model->start_write ();
|
||||
}
|
||||
|
||||
_writing = true;
|
||||
|
@ -297,7 +297,7 @@ void
|
|||
MidiSource::mark_streaming_write_started ()
|
||||
{
|
||||
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
|
||||
|
|
|
@ -238,10 +238,6 @@ Session::destroy ()
|
|||
|
||||
delete state_tree;
|
||||
|
||||
/* remove all stubfiles that might still be lurking */
|
||||
|
||||
cleanup_stubfiles ();
|
||||
|
||||
/* reset dynamic state version back to default */
|
||||
|
||||
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)
|
||||
*/
|
||||
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);
|
||||
|
||||
|
@ -2886,9 +2882,9 @@ Session::new_source_path_from_name (DataType type, const string& name, bool as_s
|
|||
|
||||
sys::path p;
|
||||
if (type == DataType::AUDIO) {
|
||||
p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
|
||||
p = sdir.sound_path();
|
||||
} else if (type == DataType::MIDI) {
|
||||
p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
|
||||
p = sdir.midi_path();
|
||||
} else {
|
||||
error << "Unknown source type, unable to create file path" << endmsg;
|
||||
return "";
|
||||
|
@ -2968,7 +2964,6 @@ Session::new_audio_source_name (const string& base, uint32_t nchan, uint32_t cha
|
|||
SessionDirectory sdir((*i).path);
|
||||
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
if (matching_unsuffixed_filename_exists_in (spath, buf) ||
|
||||
matching_unsuffixed_filename_exists_in (spath_stubs, buf)) {
|
||||
if (matching_unsuffixed_filename_exists_in (spath, buf)) {
|
||||
existing++;
|
||||
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 */
|
||||
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 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> (
|
||||
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 */
|
||||
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
|
||||
*/
|
||||
|
@ -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 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> (
|
||||
SourceFactory::createWritable (
|
||||
|
|
|
@ -101,27 +101,12 @@ SessionDirectory::sound_path () const
|
|||
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
|
||||
SessionDirectory::midi_path () const
|
||||
{
|
||||
return sources_root() / midi_dir_name;
|
||||
}
|
||||
|
||||
const path
|
||||
SessionDirectory::midi_stub_path () const
|
||||
{
|
||||
return sources_root() / midi_dir_name / stub_dir_name;
|
||||
}
|
||||
|
||||
const path
|
||||
SessionDirectory::midi_patch_path () const
|
||||
{
|
||||
|
|
|
@ -467,13 +467,6 @@ Session::ensure_subdirs ()
|
|||
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();
|
||||
|
||||
if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
|
||||
|
@ -481,13 +474,6 @@ Session::ensure_subdirs ()
|
|||
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();
|
||||
|
||||
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());
|
||||
|
||||
cleanup_stubfiles ();
|
||||
|
||||
if ((prop = node.property (X_("id-counter"))) != 0) {
|
||||
uint64_t x;
|
||||
sscanf (prop->value().c_str(), "%" PRIu64, &x);
|
||||
|
@ -2416,16 +2400,12 @@ Session::commit_reversible_command (Command *cmd)
|
|||
}
|
||||
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FileSource::is_stub_path (path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AudioFileSource::safe_audio_file_extension (path)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2434,16 +2414,12 @@ accept_all_non_stub_audio_files (const string& path, void */*arg*/)
|
|||
}
|
||||
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FileSource::is_stub_path (path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
|
||||
(path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
|
||||
(path.length() > 5 && path.find (".midi") != (path.length() - 5)));
|
||||
|
@ -2686,8 +2662,8 @@ Session::cleanup_sources (CleanupReport& rep)
|
|||
i = nexti;
|
||||
}
|
||||
|
||||
candidates = scanner (audio_path, accept_all_non_stub_audio_files, (void *) 0, true, true);
|
||||
candidates2 = scanner (midi_path, accept_all_non_stub_midi_files, (void *) 0, true, true);
|
||||
candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
|
||||
candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
|
||||
|
||||
/* merge them */
|
||||
|
||||
|
@ -2718,22 +2694,18 @@ Session::cleanup_sources (CleanupReport& rep)
|
|||
++tmp;
|
||||
|
||||
if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
|
||||
if (!fs->is_stub()) {
|
||||
if (playlists->source_use_count (fs) != 0) {
|
||||
all_sources.insert (fs->path());
|
||||
} else {
|
||||
|
||||
/* we might not remove this source from disk, because it may be used
|
||||
by other snapshots, but its not being used in this version
|
||||
so lets get rid of it now, along with any representative regions
|
||||
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);
|
||||
sources.erase (i);
|
||||
}
|
||||
if (playlists->source_use_count (fs) != 0) {
|
||||
all_sources.insert (fs->path());
|
||||
} else {
|
||||
|
||||
/* we might not remove this source from disk, because it may be used
|
||||
by other snapshots, but its not being used in this version
|
||||
so lets get rid of it now, along with any representative regions
|
||||
in the region list.
|
||||
*/
|
||||
|
||||
RegionFactory::remove_regions_using_source (i->second);
|
||||
sources.erase (i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2920,45 +2892,6 @@ Session::cleanup_trash_sources (CleanupReport& rep)
|
|||
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
|
||||
Session::set_dirty ()
|
||||
{
|
||||
|
|
|
@ -65,10 +65,8 @@ SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags)
|
|||
if (init(_path, false)) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
if (create(path)) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
/* file is not opened until write */
|
||||
}
|
||||
|
||||
/** 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)) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
_open = true;
|
||||
}
|
||||
|
||||
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 */
|
||||
framecnt_t
|
||||
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;
|
||||
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));
|
||||
|
||||
_read_data_count = 0;
|
||||
|
@ -206,6 +221,15 @@ SMFSource::read_unlocked (Evoral::EventSink<framepos_t>& destination, framepos_t
|
|||
framecnt_t
|
||||
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;
|
||||
|
||||
framepos_t time;
|
||||
|
@ -387,10 +411,11 @@ SMFSource::set_state (const XMLNode& node, int version)
|
|||
}
|
||||
|
||||
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);
|
||||
MidiSource::mark_streaming_midi_write_started (mode, start_frame);
|
||||
/* CALLER MUST HOLD LOCK */
|
||||
|
||||
MidiSource::mark_streaming_midi_write_started (mode);
|
||||
Evoral::SMF::begin_write ();
|
||||
_last_ev_time_beats = 0.0;
|
||||
_last_ev_time_frames = 0;
|
||||
|
@ -444,6 +469,10 @@ SMFSource::load_model (bool lock, bool force_reload)
|
|||
_model->clear();
|
||||
}
|
||||
|
||||
if (writable() && !_open) {
|
||||
return;
|
||||
}
|
||||
|
||||
_model->start_write();
|
||||
Evoral::SMF::seek_to_start();
|
||||
|
||||
|
@ -533,7 +562,7 @@ SMFSource::destroy_model ()
|
|||
void
|
||||
SMFSource::flush_midi ()
|
||||
{
|
||||
if (!writable()) {
|
||||
if (!writable() || (writable() && !_open)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ SndFileSource::SndFileSource (Session& s, const string& path, const string& orig
|
|||
{
|
||||
int fmt = 0;
|
||||
|
||||
init_sndfile ();
|
||||
init_sndfile ();
|
||||
|
||||
_file_is_new = true;
|
||||
|
||||
|
@ -143,37 +143,9 @@ SndFileSource::SndFileSource (Session& s, const string& path, const string& orig
|
|||
_info.channels = 1;
|
||||
_info.samplerate = rate;
|
||||
_info.format = fmt;
|
||||
|
||||
if (open()) {
|
||||
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 ();
|
||||
}
|
||||
|
||||
/* do not open the file here - do that in write_unlocked() as needed
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -181,6 +153,8 @@ SndFileSource::init_sndfile ()
|
|||
{
|
||||
string file;
|
||||
|
||||
_descriptor = 0;
|
||||
|
||||
// lets try to keep the object initalizations here at the top
|
||||
xfade_buf = 0;
|
||||
_broadcast_info = 0;
|
||||
|
@ -253,9 +227,29 @@ SndFileSource::open ()
|
|||
|
||||
if (writable()) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -280,7 +274,14 @@ SndFileSource::read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) con
|
|||
uint32_t real_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 ();
|
||||
|
||||
if (sf == 0) {
|
||||
error << string_compose (_("could not allocate file %1 for reading."), _path) << endmsg;
|
||||
return 0;
|
||||
|
@ -357,6 +358,10 @@ SndFileSource::read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) con
|
|||
framecnt_t
|
||||
SndFileSource::write_unlocked (Sample *data, framecnt_t cnt)
|
||||
{
|
||||
if (!_open && open()) {
|
||||
return 0; // failure
|
||||
}
|
||||
|
||||
if (destructive()) {
|
||||
return destructive_write_unlocked (data, cnt);
|
||||
} else {
|
||||
|
@ -511,6 +516,11 @@ SndFileSource::flush_header ()
|
|||
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 ();
|
||||
if (sf == 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
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)) {
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user