newly created files for use in recording appear in a .stubs folder, and are moved out of it when recording stops
git-svn-id: svn://localhost/ardour2/branches/3.0@7426 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
e9ab577177
commit
c8e3f32533
|
@ -33,11 +33,12 @@
|
|||
#include "pbd/memento_command.h"
|
||||
#include "pbd/stateful_diff_command.h"
|
||||
|
||||
#include <gtkmm2ext/gtk_ui.h>
|
||||
#include <gtkmm2ext/selector.h>
|
||||
#include <gtkmm2ext/bindable_button.h>
|
||||
#include <gtkmm2ext/utils.h>
|
||||
#include "gtkmm2ext/gtk_ui.h"
|
||||
#include "gtkmm2ext/selector.h"
|
||||
#include "gtkmm2ext/bindable_button.h"
|
||||
#include "gtkmm2ext/utils.h"
|
||||
|
||||
#include "ardour/file_source.h"
|
||||
#include "ardour/midi_playlist.h"
|
||||
#include "ardour/midi_diskstream.h"
|
||||
#include "ardour/midi_patch_manager.h"
|
||||
|
@ -961,7 +962,6 @@ MidiTimeAxisView::add_region (nframes64_t pos)
|
|||
|
||||
boost::shared_ptr<Source> src = _session->create_midi_source_for_session (view()->trackview().track().get(),
|
||||
view()->trackview().track()->name());
|
||||
|
||||
PropertyList plist;
|
||||
|
||||
plist.add (ARDOUR::Properties::start, 0);
|
||||
|
@ -969,7 +969,7 @@ MidiTimeAxisView::add_region (nframes64_t pos)
|
|||
plist.add (ARDOUR::Properties::name, PBD::basename_nosuffix(src->name()));
|
||||
|
||||
boost::shared_ptr<Region> region = (RegionFactory::create (src, plist));
|
||||
|
||||
|
||||
playlist()->add_region (region, start);
|
||||
_session->add_command (new StatefulDiffCommand (playlist()));
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ class CoreAudioSource : public AudioFileSource {
|
|||
CoreAudioSource (ARDOUR::Session&, const string& path, int chn, Flag);
|
||||
~CoreAudioSource ();
|
||||
|
||||
void set_path (const std::string& p);
|
||||
|
||||
float sample_rate() const;
|
||||
int update_header (sframes_t when, struct tm&, time_t);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ 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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@ public:
|
|||
class FileSource : virtual public Source {
|
||||
public:
|
||||
const Glib::ustring& path() const { return _path; }
|
||||
|
||||
int unstubify ();
|
||||
void stubify ();
|
||||
|
||||
virtual bool safe_file_extension (const Glib::ustring& path) const = 0;
|
||||
|
||||
|
@ -57,6 +60,8 @@ public:
|
|||
bool must_exist, bool& is_new, uint16_t& chan,
|
||||
Glib::ustring& found_path);
|
||||
|
||||
void inc_use_count ();
|
||||
|
||||
protected:
|
||||
FileSource (Session& session, DataType type,
|
||||
const Glib::ustring& path,
|
||||
|
@ -66,6 +71,7 @@ protected:
|
|||
|
||||
virtual int init (const Glib::ustring& idstr, bool must_exist);
|
||||
|
||||
virtual void set_path (const std::string&);
|
||||
virtual int move_dependents_to_trash() { return 0; }
|
||||
void set_within_session_from_path (const std::string&);
|
||||
|
||||
|
|
|
@ -185,7 +185,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&);
|
||||
std::string new_source_path_from_name (DataType type, const std::string&, bool as_stub = false);
|
||||
RouteList new_route_from_template (uint32_t how_many, const std::string& template_path);
|
||||
|
||||
void process (nframes_t nframes);
|
||||
|
@ -533,9 +533,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);
|
||||
|
||||
boost::shared_ptr<MidiSource> create_midi_source_for_session (Track*, std::string const &);
|
||||
boost::shared_ptr<AudioFileSource> create_audio_source_for_session (size_t, std::string const &, uint32_t,
|
||||
bool destructive, bool as_stub = false);
|
||||
|
||||
boost::shared_ptr<MidiSource> create_midi_source_for_session (Track*, std::string const &, bool as_stub = false);
|
||||
|
||||
boost::shared_ptr<Source> source_by_id (const PBD::ID&);
|
||||
boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t);
|
||||
|
@ -1415,6 +1416,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
|
|||
void add_session_range_location (nframes_t, nframes_t);
|
||||
|
||||
void setup_midi_machine_control ();
|
||||
void cleanup_stubfiles ();
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
@ -51,6 +51,17 @@ 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
|
||||
|
@ -58,6 +69,13 @@ 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
|
||||
|
|
|
@ -69,7 +69,10 @@ public:
|
|||
|
||||
static bool safe_midi_file_extension (const Glib::ustring& path);
|
||||
|
||||
private:
|
||||
protected:
|
||||
void set_path (const std::string& newpath);
|
||||
|
||||
private:
|
||||
nframes_t read_unlocked (Evoral::EventSink<nframes_t>& dst,
|
||||
sframes_t position,
|
||||
sframes_t start,
|
||||
|
|
|
@ -66,6 +66,7 @@ class SndFileSource : public AudioFileSource {
|
|||
static int get_soundfile_info (const Glib::ustring& path, SoundFileInfo& _info, std::string& error_msg);
|
||||
|
||||
protected:
|
||||
void set_path (const std::string& p);
|
||||
void set_header_timeline_position ();
|
||||
|
||||
framecnt_t read_unlocked (Sample *dst, framepos_t start, framecnt_t cnt) const;
|
||||
|
|
|
@ -105,8 +105,8 @@ class Source : public SessionObject
|
|||
Glib::Mutex& mutex() { return _lock; }
|
||||
Flag flags() const { return _flags; }
|
||||
|
||||
void inc_use_count () { g_atomic_int_inc (&_use_count); }
|
||||
void dec_use_count ();
|
||||
virtual void inc_use_count ();
|
||||
virtual void dec_use_count ();
|
||||
int use_count() const { return g_atomic_int_get (&_use_count); }
|
||||
bool used() const { return use_count() > 0; }
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <istream>
|
||||
#include <vector>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <jack/types.h>
|
||||
|
@ -440,7 +441,7 @@ namespace ARDOUR {
|
|||
|
||||
struct CleanupReport {
|
||||
std::vector<std::string> paths;
|
||||
int64_t space;
|
||||
size_t space;
|
||||
};
|
||||
|
||||
enum PositionLockStyle {
|
||||
|
|
|
@ -1388,6 +1388,7 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo
|
|||
|
||||
(*chan)->write_source->mark_for_remove ();
|
||||
(*chan)->write_source->drop_references ();
|
||||
_session.remove_source ((*chan)->write_source);
|
||||
(*chan)->write_source.reset ();
|
||||
}
|
||||
|
||||
|
@ -1409,9 +1410,13 @@ 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 ();
|
||||
|
||||
if (Config->get_auto_analyse_audio()) {
|
||||
Analyser::queue_source_for_analysis (s, true);
|
||||
}
|
||||
|
@ -1880,7 +1885,13 @@ AudioDiskstream::use_new_write_source (uint32_t n)
|
|||
}
|
||||
|
||||
try {
|
||||
if ((chan->write_source = _session.create_audio_source_for_session (n_channels().n_audio(), name(), n, destructive())) == 0) {
|
||||
/* 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) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
}
|
||||
|
@ -1895,10 +1906,6 @@ AudioDiskstream::use_new_write_source (uint32_t n)
|
|||
|
||||
chan->write_source->set_allow_remove_if_empty (!destructive());
|
||||
|
||||
/* until we write, this file is considered removable */
|
||||
|
||||
chan->write_source->mark_for_remove ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -368,3 +368,9 @@ CoreAudioSource::get_soundfile_info (string path, SoundFileInfo& _info, string&
|
|||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
CoreAudioSource::set_path (const string& p)
|
||||
{
|
||||
FileSource::set_path (p);
|
||||
}
|
||||
|
|
|
@ -17,5 +17,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");
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <glibmm/thread.h>
|
||||
|
||||
#include "ardour/file_source.h"
|
||||
#include "ardour/directory_names.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/session_directory.h"
|
||||
#include "ardour/source_factory.h"
|
||||
|
@ -51,8 +52,6 @@ using namespace ARDOUR;
|
|||
using namespace PBD;
|
||||
using namespace Glib;
|
||||
|
||||
static const std::string PATH_SEP = "/"; // I don't do windows
|
||||
|
||||
map<DataType, ustring> FileSource::search_paths;
|
||||
|
||||
FileSource::FileSource (Session& session, DataType type, const ustring& path, Source::Flag flag)
|
||||
|
@ -80,9 +79,14 @@ FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist
|
|||
bool
|
||||
FileSource::removable () const
|
||||
{
|
||||
return (_flags & Removable)
|
||||
&& ((_flags & RemoveAtDestroy) ||
|
||||
((_flags & RemovableIfEmpty) && empty() == 0));
|
||||
bool r = (_path.find (stub_dir_name) != string::npos) ||
|
||||
((_flags & Removable)
|
||||
&& ((_flags & RemoveAtDestroy) ||
|
||||
((_flags & RemovableIfEmpty) && empty() == 0)));
|
||||
|
||||
cerr << "is " << _path << " removable ? " << r << endl;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -140,15 +144,16 @@ FileSource::move_to_trash (const ustring& trash_dir_name)
|
|||
trash_dir_name directory on whichever filesystem it was already on
|
||||
*/
|
||||
|
||||
ustring newpath;
|
||||
newpath = Glib::path_get_dirname (_path);
|
||||
newpath = Glib::path_get_dirname (newpath);
|
||||
vector<string> v;
|
||||
v.push_back (Glib::path_get_dirname (Glib::path_get_dirname (_path)));
|
||||
v.push_back (trash_dir_name);
|
||||
v.push_back (Glib::path_get_basename (_path));
|
||||
|
||||
newpath += string(PATH_SEP) + trash_dir_name + PATH_SEP;
|
||||
newpath += Glib::path_get_basename (_path);
|
||||
string newpath = Glib::build_filename (v);
|
||||
|
||||
/* the new path already exists, try versioning */
|
||||
if (access (newpath.c_str(), F_OK) == 0) {
|
||||
|
||||
if (Glib::file_test (newpath.c_str(), Glib::FILE_TEST_EXISTS)) {
|
||||
char buf[PATH_MAX+1];
|
||||
int version = 1;
|
||||
ustring newpath_v;
|
||||
|
@ -391,7 +396,7 @@ FileSource::set_source_name (const ustring& newname, bool destructive)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
|
||||
if (::rename (oldpath.c_str(), newpath.c_str()) != 0) {
|
||||
error << string_compose (_("cannot rename audio file %1 to %2"), _name, newpath) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
@ -428,3 +433,42 @@ FileSource::set_within_session_from_path (const std::string& path)
|
|||
{
|
||||
_within_session = _session.path_is_within_session (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)
|
||||
{
|
||||
_path = newpath;
|
||||
}
|
||||
|
||||
void
|
||||
FileSource::inc_use_count ()
|
||||
{
|
||||
Source::inc_use_count ();
|
||||
}
|
||||
|
||||
|
|
|
@ -957,14 +957,18 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
|
|||
|
||||
_write_source->mark_streaming_write_completed ();
|
||||
|
||||
/* 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
|
||||
must be considered immutable
|
||||
must be considered immutable. luckily, we can rely on
|
||||
MidiSource::mark_streaming_write_completed() to have
|
||||
already done the necessary work for that.
|
||||
*/
|
||||
|
||||
_write_source->mark_nonremovable ();
|
||||
|
||||
string whole_file_region_name;
|
||||
whole_file_region_name = region_name_from_path (_write_source->name(), true);
|
||||
|
||||
|
@ -1321,7 +1325,14 @@ MidiDiskstream::use_new_write_source (uint32_t n)
|
|||
_write_source.reset();
|
||||
|
||||
try {
|
||||
_write_source = boost::dynamic_pointer_cast<SMFSource>(_session.create_midi_source_for_session (0, name ()));
|
||||
/* 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));
|
||||
|
||||
if (!_write_source) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
@ -1342,8 +1353,26 @@ list<boost::shared_ptr<Source> >
|
|||
MidiDiskstream::steal_write_sources()
|
||||
{
|
||||
list<boost::shared_ptr<Source> > ret;
|
||||
|
||||
/* put some data on the disk, even if its just a header for an empty file.
|
||||
XXX should we not have a more direct method for doing this? Maybe not
|
||||
since we don't want to mess around with the model/disk relationship
|
||||
that the Source has to pay attention to.
|
||||
*/
|
||||
|
||||
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 ();
|
||||
|
||||
ret.push_back (_write_source);
|
||||
|
||||
/* get a new one */
|
||||
|
||||
use_new_write_source (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -321,19 +321,11 @@ MidiSource::session_saved()
|
|||
XXX do we need to do this every time?
|
||||
*/
|
||||
|
||||
flush_midi();
|
||||
|
||||
if (_model && _model->edited()) {
|
||||
#if 0 // old style: clone the source if necessary on every session save
|
||||
// and switch to the new source
|
||||
boost::shared_ptr<MidiSource> newsrc = clone ();
|
||||
|
||||
if (newsrc) {
|
||||
_model->set_midi_source (newsrc);
|
||||
Switched (newsrc); /* EMIT SIGNAL */
|
||||
}
|
||||
#else
|
||||
// new style: if the model is edited, write its contents into
|
||||
|
||||
|
||||
// if the model is edited, write its contents into
|
||||
// the current source file (overwiting previous contents.
|
||||
|
||||
/* temporarily drop our reference to the model so that
|
||||
|
@ -343,13 +335,19 @@ MidiSource::session_saved()
|
|||
|
||||
boost::shared_ptr<MidiModel> mm = _model ;
|
||||
_model.reset ();
|
||||
mm->sync_to_source ();
|
||||
_model = mm;
|
||||
/* data is in the file now, its not removable */
|
||||
#endif
|
||||
}
|
||||
|
||||
cerr << name() << " @ " << this << " length at save = " << _length_beats << endl;
|
||||
/* flush model contents to disk
|
||||
*/
|
||||
|
||||
mm->sync_to_source ();
|
||||
|
||||
/* reacquire model */
|
||||
|
||||
_model = mm;
|
||||
|
||||
} else {
|
||||
flush_midi();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -40,10 +40,11 @@ PlaylistFactory::create (Session& s, const XMLNode& node, bool hidden, bool unus
|
|||
|
||||
boost::shared_ptr<Playlist> pl;
|
||||
|
||||
if ( !type || type->value() == "audio" )
|
||||
if (!type || type->value() == "audio") {
|
||||
pl = boost::shared_ptr<Playlist> (new AudioPlaylist (s, node, hidden));
|
||||
else if ( type->value() == "midi" )
|
||||
} else if (type->value() == "midi") {
|
||||
pl = boost::shared_ptr<Playlist> (new MidiPlaylist (s, node, hidden));
|
||||
}
|
||||
|
||||
pl->set_region_ownership ();
|
||||
|
||||
|
|
|
@ -1388,7 +1388,6 @@ void
|
|||
Region::set_master_sources (const SourceList& srcs)
|
||||
{
|
||||
for (SourceList::const_iterator i = _master_sources.begin (); i != _master_sources.end(); ++i) {
|
||||
cerr << name() << " " << id() << " DEC M SMS\n";
|
||||
(*i)->dec_use_count ();
|
||||
}
|
||||
|
||||
|
|
|
@ -226,6 +226,10 @@ 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;
|
||||
|
@ -2606,6 +2610,7 @@ Session::remove_source (boost::weak_ptr<Source> src)
|
|||
Glib::Mutex::Lock lm (source_lock);
|
||||
|
||||
if ((i = sources.find (source->id())) != sources.end()) {
|
||||
cerr << "Removing source " << source->name() << endl;
|
||||
sources.erase (i);
|
||||
}
|
||||
}
|
||||
|
@ -2640,7 +2645,6 @@ Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn)
|
|||
Glib::Mutex::Lock lm (source_lock);
|
||||
|
||||
for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
|
||||
cerr << "comparing " << path << " with " << i->second->name() << endl;
|
||||
boost::shared_ptr<AudioFileSource> afs
|
||||
= boost::dynamic_pointer_cast<AudioFileSource>(i->second);
|
||||
|
||||
|
@ -2670,18 +2674,12 @@ Session::change_source_path_by_name (string path, string oldname, string newname
|
|||
the task here is to replace NAME with the new name.
|
||||
*/
|
||||
|
||||
/* find last slash */
|
||||
|
||||
string dir;
|
||||
string prefix;
|
||||
string::size_type slash;
|
||||
string::size_type dash;
|
||||
|
||||
if ((slash = path.find_last_of ('/')) == string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
dir = path.substr (0, slash+1);
|
||||
dir = Glib::path_get_dirname (path);
|
||||
path = Glib::path_get_basename (path);
|
||||
|
||||
/* '-' is not a legal character for the NAME part of the path */
|
||||
|
||||
|
@ -2689,7 +2687,7 @@ Session::change_source_path_by_name (string path, string oldname, string newname
|
|||
return "";
|
||||
}
|
||||
|
||||
prefix = path.substr (slash+1, dash-(slash+1));
|
||||
prefix = path.substr (0, dash);
|
||||
|
||||
path = dir;
|
||||
path += prefix;
|
||||
|
@ -2708,17 +2706,11 @@ Session::change_source_path_by_name (string path, string oldname, string newname
|
|||
|
||||
string dir;
|
||||
string suffix;
|
||||
string::size_type slash;
|
||||
string::size_type dash;
|
||||
string::size_type postfix;
|
||||
|
||||
/* find last slash */
|
||||
|
||||
if ((slash = path.find_last_of ('/')) == string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
dir = path.substr (0, slash+1);
|
||||
dir = Glib::path_get_dirname (path);
|
||||
path = Glib::path_get_basename (path);
|
||||
|
||||
/* '-' is not a legal character for the NAME part of the path */
|
||||
|
||||
|
@ -2750,7 +2742,7 @@ Session::change_source_path_by_name (string path, string oldname, string newname
|
|||
|
||||
snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
|
||||
|
||||
if (access (buf, F_OK) != 0) {
|
||||
if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
|
||||
path = buf;
|
||||
break;
|
||||
}
|
||||
|
@ -2771,7 +2763,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)
|
||||
Session::new_source_path_from_name (DataType type, const string& name, bool as_stub)
|
||||
{
|
||||
assert(name.find("/") == string::npos);
|
||||
|
||||
|
@ -2779,9 +2771,9 @@ Session::new_source_path_from_name (DataType type, const string& name)
|
|||
|
||||
sys::path p;
|
||||
if (type == DataType::AUDIO) {
|
||||
p = sdir.sound_path();
|
||||
p = (as_stub ? sdir.sound_stub_path() : sdir.sound_path());
|
||||
} else if (type == DataType::MIDI) {
|
||||
p = sdir.midi_path();
|
||||
p = (as_stub ? sdir.midi_stub_path() : sdir.midi_path());
|
||||
} else {
|
||||
error << "Unknown source type, unable to create file path" << endmsg;
|
||||
return "";
|
||||
|
@ -2889,10 +2881,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)
|
||||
Session::create_audio_source_for_session (size_t n_chans, string const & n, uint32_t chan, bool destructive, bool as_stub)
|
||||
{
|
||||
const string name = new_audio_source_name (n, n_chans, chan, destructive);
|
||||
const string path = new_source_path_from_name(DataType::AUDIO, name);
|
||||
const string path = new_source_path_from_name(DataType::AUDIO, name, as_stub);
|
||||
|
||||
return boost::dynamic_pointer_cast<AudioFileSource> (
|
||||
SourceFactory::createWritable (DataType::AUDIO, *this, path, destructive, frame_rate()));
|
||||
|
@ -2949,7 +2941,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)
|
||||
Session::create_midi_source_for_session (Track* track, string const & n, bool as_stub)
|
||||
{
|
||||
/* try to use the existing write source for the track, to keep numbering sane
|
||||
*/
|
||||
|
@ -2968,7 +2960,7 @@ Session::create_midi_source_for_session (Track* track, string const & n)
|
|||
}
|
||||
|
||||
const string name = new_midi_source_name (n);
|
||||
const string path = new_source_path_from_name (DataType::MIDI, name);
|
||||
const string path = new_source_path_from_name (DataType::MIDI, name, as_stub);
|
||||
|
||||
return boost::dynamic_pointer_cast<SMFSource> (
|
||||
SourceFactory::createWritable (
|
||||
|
@ -3067,42 +3059,6 @@ Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::
|
|||
return a->order_key(N_("signal")) < b->order_key(N_("signal"));
|
||||
}
|
||||
|
||||
void
|
||||
Session::remove_empty_sounds ()
|
||||
{
|
||||
vector<string> audio_filenames;
|
||||
|
||||
get_files_in_directory (_session_dir->sound_path(), audio_filenames);
|
||||
|
||||
Glib::Mutex::Lock lm (source_lock);
|
||||
|
||||
TapeFileMatcher tape_file_matcher;
|
||||
|
||||
remove_if (audio_filenames.begin(), audio_filenames.end(),
|
||||
boost::bind (&TapeFileMatcher::matches, &tape_file_matcher, _1));
|
||||
|
||||
for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) {
|
||||
|
||||
sys::path audio_file_path (_session_dir->sound_path());
|
||||
|
||||
audio_file_path /= *i;
|
||||
|
||||
if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) {
|
||||
|
||||
try
|
||||
{
|
||||
sys::remove (audio_file_path);
|
||||
const string peakfile = peak_path (audio_file_path.to_string());
|
||||
sys::remove (peakfile);
|
||||
}
|
||||
catch (const sys::filesystem_error& err)
|
||||
{
|
||||
error << err.what() << endmsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Session::is_auditioning () const
|
||||
{
|
||||
|
|
|
@ -101,12 +101,27 @@ 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
|
||||
{
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef HAVE_SYS_VFS_H
|
||||
#include <sys/vfs.h>
|
||||
|
@ -66,6 +65,7 @@
|
|||
#include "pbd/search_path.h"
|
||||
#include "pbd/stacktrace.h"
|
||||
#include "pbd/convert.h"
|
||||
#include "pbd/clear_dir.h"
|
||||
|
||||
#include "ardour/amp.h"
|
||||
#include "ardour/audio_diskstream.h"
|
||||
|
@ -288,7 +288,7 @@ Session::second_stage_init ()
|
|||
if (load_state (_current_snapshot_name)) {
|
||||
return -1;
|
||||
}
|
||||
remove_empty_sounds ();
|
||||
cleanup_stubfiles ();
|
||||
}
|
||||
|
||||
if (_butler->start_thread()) {
|
||||
|
@ -460,6 +460,13 @@ 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) {
|
||||
|
@ -467,6 +474,13 @@ 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_sound_path().to_string();
|
||||
|
||||
if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
|
||||
|
@ -1595,15 +1609,11 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
|
|||
|
||||
try {
|
||||
|
||||
if ( !type || type->value() == "audio" ) {
|
||||
|
||||
return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
|
||||
|
||||
} else if (type->value() == "midi") {
|
||||
|
||||
return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
|
||||
|
||||
}
|
||||
if (!type || type->value() == "audio") {
|
||||
return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
|
||||
} else if (type->value() == "midi") {
|
||||
return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
|
||||
}
|
||||
|
||||
} catch (failed_constructor& err) {
|
||||
return boost::shared_ptr<Region> ();
|
||||
|
@ -1738,24 +1748,16 @@ Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
|
|||
boost::shared_ptr<Source> source;
|
||||
boost::shared_ptr<MidiSource> ms;
|
||||
SourceList sources;
|
||||
uint32_t nchans = 1;
|
||||
|
||||
if (node.name() != X_("Region")) {
|
||||
return boost::shared_ptr<MidiRegion>();
|
||||
}
|
||||
|
||||
if ((prop = node.property (X_("channels"))) != 0) {
|
||||
nchans = atoi (prop->value().c_str());
|
||||
}
|
||||
|
||||
if ((prop = node.property ("name")) == 0) {
|
||||
cerr << "no name for this region\n";
|
||||
abort ();
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
@ -2339,6 +2341,10 @@ Session::commit_reversible_command(Command *cmd)
|
|||
static bool
|
||||
accept_all_non_peak_files (const string& path, void */*arg*/)
|
||||
{
|
||||
if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
|
||||
}
|
||||
|
||||
|
@ -2710,9 +2716,6 @@ Session::cleanup_trash_sources (CleanupReport& rep)
|
|||
|
||||
vector<space_and_path>::iterator i;
|
||||
string dead_sound_dir;
|
||||
struct dirent* dentry;
|
||||
struct stat statbuf;
|
||||
DIR* dead;
|
||||
|
||||
rep.paths.clear ();
|
||||
rep.space = 0;
|
||||
|
@ -2722,50 +2725,51 @@ Session::cleanup_trash_sources (CleanupReport& rep)
|
|||
dead_sound_dir = (*i).path;
|
||||
dead_sound_dir += dead_sound_dir_name;
|
||||
|
||||
if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((dentry = readdir (dead)) != 0) {
|
||||
|
||||
/* avoid '.' and '..' */
|
||||
|
||||
if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
|
||||
(dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string fullpath;
|
||||
|
||||
fullpath = dead_sound_dir;
|
||||
fullpath += '/';
|
||||
fullpath += dentry->d_name;
|
||||
|
||||
if (stat (fullpath.c_str(), &statbuf)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!S_ISREG (statbuf.st_mode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (unlink (fullpath.c_str())) {
|
||||
error << string_compose (_("cannot remove dead sound file %1 (%2)"),
|
||||
fullpath, strerror (errno))
|
||||
<< endmsg;
|
||||
}
|
||||
|
||||
rep.paths.push_back (dentry->d_name);
|
||||
rep.space += statbuf.st_size;
|
||||
}
|
||||
|
||||
closedir (dead);
|
||||
|
||||
clear_directory (dead_sound_dir, &rep.space, &rep.paths);
|
||||
}
|
||||
|
||||
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 ()
|
||||
{
|
||||
|
|
|
@ -432,6 +432,13 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
|
||||
|
||||
if (abort && did_record) {
|
||||
/* no reason to save the session file when we remove sources
|
||||
*/
|
||||
_state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
|
||||
}
|
||||
|
||||
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
|
||||
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
|
||||
if (tr) {
|
||||
|
@ -439,6 +446,10 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
}
|
||||
}
|
||||
|
||||
if (abort && did_record) {
|
||||
_state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
|
||||
}
|
||||
|
||||
boost::shared_ptr<RouteList> r = routes.reader ();
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
|
|
|
@ -99,7 +99,6 @@ SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist)
|
|||
SMFSource::~SMFSource ()
|
||||
{
|
||||
if (removable()) {
|
||||
cerr << name() << " is removable, empty ? " << empty() << " UC " << use_count() << endl;
|
||||
unlink (_path.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +169,7 @@ SMFSource::read_unlocked (Evoral::EventSink<nframes_t>& destination, sframes_t s
|
|||
assert(time >= start_ticks);
|
||||
const sframes_t ev_frame_time = converter.to(time / (double)ppqn()) + stamp_offset;
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
cerr << " frames = " << ev_frame_time
|
||||
<< " w/offset = " << ev_frame_time - negative_stamp_offset
|
||||
<< endl;
|
||||
|
@ -494,3 +493,9 @@ SMFSource::flush_midi ()
|
|||
mark_nonremovable ();
|
||||
}
|
||||
|
||||
void
|
||||
SMFSource::set_path (const string& p)
|
||||
{
|
||||
FileSource::set_path (p);
|
||||
SMF::set_path (_path);
|
||||
}
|
||||
|
|
|
@ -889,3 +889,13 @@ SndFileSource::file_closed ()
|
|||
|
||||
touch_peakfile ();
|
||||
}
|
||||
|
||||
void
|
||||
SndFileSource::set_path (const string& p)
|
||||
{
|
||||
FileSource::set_path (p);
|
||||
|
||||
if (_descriptor) {
|
||||
_descriptor->set_path (_path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -272,6 +272,12 @@ Source::set_allow_remove_if_empty (bool yn)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Source::inc_use_count ()
|
||||
{
|
||||
g_atomic_int_inc (&_use_count);
|
||||
}
|
||||
|
||||
void
|
||||
Source::dec_use_count ()
|
||||
{
|
||||
|
|
|
@ -66,7 +66,10 @@ public:
|
|||
|
||||
double round_to_file_precision (double val) const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
void set_path (const std::string& p);
|
||||
|
||||
private:
|
||||
std::string _file_path;
|
||||
smf_t* _smf;
|
||||
smf_track_t* _smf_track;
|
||||
|
|
|
@ -90,14 +90,13 @@ SMF::open(const std::string& path, int track) THROW_FILE_ERROR
|
|||
return -1;
|
||||
}
|
||||
|
||||
_smf = smf_load (f);
|
||||
if (_smf == NULL) {
|
||||
if ((_smf = smf_load (f)) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_smf_track = smf_get_track_by_number(_smf, track);
|
||||
if (!_smf_track)
|
||||
if ((_smf_track = smf_get_track_by_number(_smf, track)) == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
//cerr << "Track " << track << " # events: " << _smf_track->number_of_events << endl;
|
||||
if (_smf_track->number_of_events == 0) {
|
||||
|
@ -157,15 +156,22 @@ void
|
|||
SMF::close() THROW_FILE_ERROR
|
||||
{
|
||||
if (_smf) {
|
||||
#if 0
|
||||
/* XXX why would we automatically save-on-close?
|
||||
*/
|
||||
|
||||
PBD::StdioFileDescriptor d (_file_path, "w+");
|
||||
FILE* f = d.allocate ();
|
||||
if (f == 0) {
|
||||
throw FileError ();
|
||||
}
|
||||
|
||||
cerr << "CLOSE: Save SMF to " << _file_path << endl;
|
||||
|
||||
if (smf_save(_smf, f) != 0) {
|
||||
throw FileError();
|
||||
}
|
||||
#endif
|
||||
smf_delete(_smf);
|
||||
_smf = 0;
|
||||
_smf_track = 0;
|
||||
|
@ -294,5 +300,10 @@ SMF::round_to_file_precision (double val) const
|
|||
return round (val * div) / div;
|
||||
}
|
||||
|
||||
void
|
||||
SMF::set_path (const std::string& p)
|
||||
{
|
||||
_file_path = p;
|
||||
}
|
||||
|
||||
} // namespace Evoral
|
||||
|
|
|
@ -100,19 +100,19 @@ FileManager::allocate (FileDescriptor* d)
|
|||
DEBUG::FileManager,
|
||||
string_compose (
|
||||
"closed file for %1 to release file handle; now have %2 of %3 open\n",
|
||||
(*oldest)->_name, _open, _max_open
|
||||
(*oldest)->_path, _open, _max_open
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (d->open ()) {
|
||||
DEBUG_TRACE (DEBUG::FileManager, string_compose ("open of %1 failed.\n", d->_name));
|
||||
DEBUG_TRACE (DEBUG::FileManager, string_compose ("open of %1 failed.\n", d->_path));
|
||||
return true;
|
||||
}
|
||||
|
||||
_open++;
|
||||
|
||||
DEBUG_TRACE (DEBUG::FileManager, string_compose ("opened file for %1; now have %2 of %3 open.\n", d->_name, _open, _max_open));
|
||||
DEBUG_TRACE (DEBUG::FileManager, string_compose ("opened file for %1; now have %2 of %3 open.\n", d->_path, _open, _max_open));
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -148,7 +148,7 @@ FileManager::remove (FileDescriptor* d)
|
|||
close (d);
|
||||
DEBUG_TRACE (
|
||||
DEBUG::FileManager,
|
||||
string_compose ("closed file for %1; file is being removed; now have %2 of %3 open\n", d->_name, _open, _max_open)
|
||||
string_compose ("closed file for %1; file is being removed; now have %2 of %3 open\n", d->_path, _open, _max_open)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ FileManager::close (FileDescriptor* d)
|
|||
FileDescriptor::FileDescriptor (string const & n, bool w)
|
||||
: _refcount (0)
|
||||
, _last_used (0)
|
||||
, _name (n)
|
||||
, _path (n)
|
||||
, _writeable (w)
|
||||
{
|
||||
|
||||
|
@ -224,7 +224,7 @@ FdFileDescriptor::open ()
|
|||
{
|
||||
/* we must have a lock on the FileManager's mutex */
|
||||
|
||||
_fd = ::open (_name.c_str(), _writeable ? (O_RDWR | O_CREAT) : O_RDONLY, _mode);
|
||||
_fd = ::open (_path.c_str(), _writeable ? (O_RDWR | O_CREAT) : O_RDONLY, _mode);
|
||||
return (_fd == -1);
|
||||
}
|
||||
|
||||
|
@ -253,6 +253,13 @@ FdFileDescriptor::allocate ()
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
FileDescriptor::set_path (const string& p)
|
||||
{
|
||||
assert (!is_open());
|
||||
_path = p;
|
||||
}
|
||||
|
||||
/** @param n Filename.
|
||||
* @param w true to open writeable, otherwise false.
|
||||
*/
|
||||
|
@ -283,7 +290,7 @@ StdioFileDescriptor::open ()
|
|||
{
|
||||
/* we must have a lock on the FileManager's mutex */
|
||||
|
||||
_file = fopen (_name.c_str(), _mode.c_str());
|
||||
_file = fopen (_path.c_str(), _mode.c_str());
|
||||
return (_file == 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,10 @@ public:
|
|||
FileDescriptor (std::string const &, bool);
|
||||
virtual ~FileDescriptor () {}
|
||||
|
||||
const std::string& path() const { return _path; }
|
||||
|
||||
void release ();
|
||||
virtual void set_path (const std::string&);
|
||||
|
||||
/** Emitted when the file is closed */
|
||||
PBD::Signal0<void> Closed;
|
||||
|
@ -71,7 +74,7 @@ protected:
|
|||
|
||||
int _refcount; ///< number of active users of this file
|
||||
double _last_used; ///< monotonic time that this file was last allocated
|
||||
std::string _name; ///< filename
|
||||
std::string _path; ///< file path
|
||||
bool _writeable; ///< true if it should be opened writeable, otherwise false
|
||||
|
||||
FileManager* manager ();
|
||||
|
|
|
@ -86,7 +86,7 @@ SndFileDescriptor::open ()
|
|||
{
|
||||
/* we must have a lock on the FileManager's mutex */
|
||||
|
||||
_sndfile = sf_open (_name.c_str(), _writeable ? SFM_RDWR : SFM_READ, _info);
|
||||
_sndfile = sf_open (_path.c_str(), _writeable ? SFM_RDWR : SFM_READ, _info);
|
||||
return (_sndfile == 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ def build(bld):
|
|||
convert.cc
|
||||
controllable.cc
|
||||
controllable_descriptor.cc
|
||||
clear_dir.cc
|
||||
crossthread.cc
|
||||
cpus.cc
|
||||
debug.cc
|
||||
|
|
Loading…
Reference in New Issue
Block a user