summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-03-17 17:39:21 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-03-17 17:39:21 +0000
commit5e836403adcb62a59141226baa32515ae7789661 (patch)
tree40e47327306f1328f504ce16b81981206572af5d /libs
parent6097ce578b9dc4d51f421c2e4cca2de64948aa66 (diff)
lots of fidgety work to get track renaming to work correctly now that we have to rename audio files too; some GUI tweaks
git-svn-id: svn://localhost/trunk/ardour2@404 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/diskstream.h3
-rw-r--r--libs/ardour/ardour/filesource.h8
-rw-r--r--libs/ardour/ardour/session.h4
-rw-r--r--libs/ardour/ardour/source.h6
-rw-r--r--libs/ardour/audio_track.cc14
-rw-r--r--libs/ardour/destructive_filesource.cc2
-rw-r--r--libs/ardour/diskstream.cc59
-rw-r--r--libs/ardour/externalsource.cc6
-rw-r--r--libs/ardour/filesource.cc57
-rw-r--r--libs/ardour/route.cc1
-rw-r--r--libs/ardour/session.cc224
-rw-r--r--libs/ardour/session_state.cc60
-rw-r--r--libs/ardour/sndfilesource.cc2
-rw-r--r--libs/ardour/source.cc112
14 files changed, 405 insertions, 153 deletions
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index a163c125d7..a0436696b0 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -100,7 +100,7 @@ class DiskStream : public Stateful, public sigc::trackable
jack_nframes_t roll_delay() const { return _roll_delay; }
void set_roll_delay (jack_nframes_t);
- void set_name (string str, void* src);
+ int set_name (string str, void* src);
string input_source (uint32_t n=0) const {
if (n < channels.size()) {
@@ -244,6 +244,7 @@ class DiskStream : public Stateful, public sigc::trackable
void set_block_size (jack_nframes_t);
int internal_playback_seek (jack_nframes_t distance);
int can_internal_playback_seek (jack_nframes_t distance);
+ int rename_write_sources ();
void reset_write_sources (bool, bool force = false);
void non_realtime_input_change ();
diff --git a/libs/ardour/ardour/filesource.h b/libs/ardour/ardour/filesource.h
index af46596ec5..c7ae97c281 100644
--- a/libs/ardour/ardour/filesource.h
+++ b/libs/ardour/ardour/filesource.h
@@ -54,12 +54,15 @@ class FileSource : public Source {
FileSource (const XMLNode&, jack_nframes_t rate);
~FileSource ();
+ int set_name (std::string str, bool destructive);
+
+ void set_allow_remove_if_empty (bool yn);
+
jack_nframes_t length() const { return _length; }
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
void mark_for_remove();
string peak_path(string audio_path);
- string old_peak_path(string audio_path);
string path() const { return _path; }
virtual int seek (jack_nframes_t frame) {return 0; }
@@ -93,7 +96,8 @@ class FileSource : public Source {
string _take_id;
SampleFormat _sample_format;
int _sample_size;
-
+ bool allow_remove_if_empty;
+
static char bwf_country_code[3];
static char bwf_organization_code[4];
static char bwf_serial_number[13];
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index d0da2fef26..24f15e97f5 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -253,8 +253,9 @@ class Session : public sigc::trackable, public Stateful
static string template_dir ();
static void get_template_list (list<string>&);
+ static string change_audio_path_by_name (string oldpath, string oldname, string newname, bool destructive);
static string peak_path_from_audio_path (string);
- static string old_peak_path_from_audio_path (string);
+ string audio_path_from_name (string, uint32_t nchans, uint32_t chan, bool destructive);
void process (jack_nframes_t nframes);
@@ -1498,6 +1499,7 @@ class Session : public sigc::trackable, public Stateful
RouteList routes;
mutable PBD::NonBlockingRWLock route_lock;
void add_route (Route*);
+ uint32_t destructive_index;
int load_routes (const XMLNode&);
Route* XMLRouteFactory (const XMLNode&);
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index 7a5e2eb23a..88a478a420 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -56,6 +56,7 @@ class Source : public Stateful, public sigc::trackable
virtual ~Source ();
const string& name() const { return _name; }
+
ARDOUR::id_t id() const { return _id; }
/* returns the number of items in this `source' */
@@ -103,10 +104,11 @@ class Source : public Stateful, public sigc::trackable
XMLNode& get_state ();
int set_state (const XMLNode&);
-
static int start_peak_thread ();
static void stop_peak_thread ();
+ int rename_peakfile (std::string newpath);
+
static void set_build_missing_peakfiles (bool yn) {
_build_missing_peakfiles = yn;
}
@@ -125,7 +127,6 @@ class Source : public Stateful, public sigc::trackable
jack_nframes_t _length;
bool next_peak_clear_should_notify;
string peakpath;
- int peakfile; /* fd */
time_t _timestamp;
string _captured_for;
@@ -138,7 +139,6 @@ class Source : public Stateful, public sigc::trackable
int do_build_peak (jack_nframes_t, jack_nframes_t);
virtual jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const = 0;
virtual string peak_path(string audio_path) = 0;
- virtual string old_peak_path(string audio_path) = 0;
static pthread_t peak_thread;
static bool have_peak_thread;
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 85cd86632c..ae3d1719c7 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -755,13 +755,23 @@ AudioTrack::toggle_monitor_input ()
int
AudioTrack::set_name (string str, void *src)
{
+ int ret;
+
if (record_enabled() && _session.actively_recording()) {
/* this messes things up if done while recording */
return -1;
}
- diskstream->set_name (str, src);
- return IO::set_name (str, src);
+ if (diskstream->set_name (str, src)) {
+ return -1;
+ }
+
+ /* save state so that the statefile fully reflects any filename changes */
+
+ if ((ret = IO::set_name (str, src)) == 0) {
+ _session.save_state ("");
+ }
+ return ret;
}
int
diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc
index 1ca6b5be5a..40138405b6 100644
--- a/libs/ardour/destructive_filesource.cc
+++ b/libs/ardour/destructive_filesource.cc
@@ -69,7 +69,6 @@ jack_nframes_t DestructiveFileSource::xfade_frames = 64;
DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first, SampleFormat samp_format)
: FileSource (path, rate, repair_first, samp_format)
{
- cerr << "DESTRUCTO DISK STREAM, " << _name << endl;
if (out_coefficient == 0) {
setup_standard_crossfades (rate);
}
@@ -84,7 +83,6 @@ DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate,
DestructiveFileSource::DestructiveFileSource (const XMLNode& node, jack_nframes_t rate)
: FileSource (node, rate)
{
- cerr << "from XML, DESTRUCTO DISK STREAM, " << _name << endl;
if (out_coefficient == 0) {
setup_standard_crossfades (rate);
}
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index cd67659290..28da6c9c31 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -69,6 +69,9 @@ DiskStream::DiskStream (Session &sess, const string &name, Flag flag)
/* prevent any write sources from being created */
in_set_state = true;
+
+
+
init (flag);
use_new_playlist ();
in_set_state = false;
@@ -472,13 +475,27 @@ void
DiskStream::use_destructive_playlist ()
{
/* use the sources associated with the single full-extent region */
+
+ Playlist::RegionList* rl = _playlist->regions_at (0);
+
+ if (rl->empty()) {
+ throw failed_constructor();
+ }
+
+ AudioRegion* region = dynamic_cast<AudioRegion*> (rl->front());
+
+ if (region == 0) {
+ throw failed_constructor();
+ }
+
+ delete rl;
- AudioRegion* region = dynamic_cast<AudioRegion*> (_playlist->regions_at (0)->front());
uint32_t n;
ChannelList::iterator chan;
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
(*chan).write_source = dynamic_cast<FileSource*>(&region->source (n));
+ (*chan).write_source->set_allow_remove_if_empty (false);
}
/* the source list will never be reset for a destructive track */
@@ -491,7 +508,7 @@ DiskStream::set_io (IO& io)
set_align_style_from_io ();
}
-void
+int
DiskStream::set_name (string str, void *src)
{
if (str != _name) {
@@ -499,12 +516,14 @@ DiskStream::set_name (string str, void *src)
_name = str;
if (!in_set_state && recordable()) {
-
- /* open new capture files so that they have the correct name */
-
- reset_write_sources (false);
+ /* rename existing capture files so that they have the correct name */
+ return rename_write_sources ();
+ } else {
+ return -1;
}
}
+
+ return 0;
}
void
@@ -2097,8 +2116,12 @@ DiskStream::set_state (const XMLNode& node)
if (!had_playlist) {
_playlist->set_orig_diskstream_id (_id);
}
-
- if (capture_pending_node) {
+
+ if (!destructive() && capture_pending_node) {
+ /* destructive streams have one and only one source per channel,
+ and so they never end up in pending capture in any useful
+ sense.
+ */
use_pending_capture_data (*capture_pending_node);
}
@@ -2170,6 +2193,10 @@ DiskStream::use_new_write_source (uint32_t n)
chan.write_source->use ();
+ /* do not remove destructive files even if they are empty */
+
+ chan.write_source->set_allow_remove_if_empty (!destructive());
+
return 0;
}
@@ -2213,6 +2240,22 @@ DiskStream::reset_write_sources (bool mark_write_complete, bool force)
}
}
+int
+DiskStream::rename_write_sources ()
+{
+ ChannelList::iterator chan;
+ uint32_t n;
+
+ for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
+ if ((*chan).write_source != 0) {
+ (*chan).write_source->set_name (_name, destructive());
+ /* XXX what to do if one of them fails ? */
+ }
+ }
+
+ return 0;
+}
+
void
DiskStream::set_block_size (jack_nframes_t nframes)
{
diff --git a/libs/ardour/externalsource.cc b/libs/ardour/externalsource.cc
index 568100ca44..4fb102a4a0 100644
--- a/libs/ardour/externalsource.cc
+++ b/libs/ardour/externalsource.cc
@@ -84,12 +84,6 @@ ExternalSource::peak_path (string audio_path)
return res;
}
-string
-ExternalSource::old_peak_path (string audio_path)
-{
- return peak_path (audio_path);
-}
-
#ifdef HAVE_COREAUDIO
ExternalSource*
diff --git a/libs/ardour/filesource.cc b/libs/ardour/filesource.cc
index b2fcc3d36d..ad8979173e 100644
--- a/libs/ardour/filesource.cc
+++ b/libs/ardour/filesource.cc
@@ -165,6 +165,7 @@ FileSource::init (string pathstr, bool must_exist, jack_nframes_t rate)
fd = -1;
remove_at_unref = false;
next_peak_clear_should_notify = false;
+ allow_remove_if_empty = true;
if (pathstr[0] != '/') {
@@ -300,7 +301,7 @@ FileSource::init (string pathstr, bool must_exist, jack_nframes_t rate)
}
if ((ret = initialize_peakfile (new_file, _path))) {
- error << string_compose (_("FileSource: cannot initialize peakfile for %1"), _path) << endmsg;
+ error << string_compose (_("FileSource: cannot initialize peakfile for %1 as %2"), _path, peakpath) << endmsg;
}
out:
@@ -325,7 +326,7 @@ FileSource::~FileSource ()
if (fd >= 0) {
- if (remove_at_unref || is_empty (_path)) {
+ if (remove_at_unref || (is_empty (_path) && allow_remove_if_empty)) {
unlink (_path.c_str());
unlink (peakpath.c_str());
}
@@ -334,6 +335,41 @@ FileSource::~FileSource ()
}
}
+void
+FileSource::set_allow_remove_if_empty (bool yn)
+{
+ allow_remove_if_empty = yn;
+}
+
+int
+FileSource::set_name (string newname, bool destructive)
+{
+ LockMonitor lm (_lock, __LINE__, __FILE__);
+ string oldpath = _path;
+ string newpath = Session::change_audio_path_by_name (oldpath, _name, newname, destructive);
+
+ if (newpath.empty()) {
+ error << string_compose (_("programming error: %1"), "cannot generate a changed audio path") << endmsg;
+ return -1;
+ }
+
+ if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
+ error << string_compose (_("cannot rename audio file for %1 to %2"), _name, newpath) << endmsg;
+ return -1;
+ }
+
+ _name = basename (newpath);
+ _path = newpath;
+
+ return rename_peakfile (peak_path (_path));
+}
+
+string
+FileSource::peak_path (string audio_path)
+{
+ return Session::peak_path_from_audio_path (audio_path);
+}
+
int
FileSource::discover_chunks (bool silent)
{
@@ -1230,9 +1266,9 @@ FileSource::is_empty (string path)
less than 1msec at typical sample rates.
*/
- /* NOTE: 700 bytes is the size of a BWF header structure *plus* our minimal coding history */
+ /* NOTE: 698 bytes is the size of a BWF header structure *plus* our minimal coding history */
- return (statbuf.st_size == 0 || statbuf.st_size == wave_header_size || statbuf.st_size == 700);
+ return (statbuf.st_size == 0 || statbuf.st_size == wave_header_size || statbuf.st_size == 698);
}
void
@@ -1248,18 +1284,6 @@ FileSource::mark_streaming_write_completed ()
}
}
-string
-FileSource::peak_path(string audio_path)
-{
- return Session::peak_path_from_audio_path (audio_path);
-}
-
-string
-FileSource::old_peak_path(string audio_path)
-{
- return Session::old_peak_path_from_audio_path (audio_path);
-}
-
void
FileSource::mark_take (string id)
{
@@ -1470,3 +1494,4 @@ FileSource::repair (string path, jack_nframes_t rate)
fclose (in);
return ret;
}
+
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 18ce52dd43..84979fce6a 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -622,6 +622,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) {
pan (bufs, nbufs, nframes, offset, speed_quietning);
} else {
+ // cerr << "panner state = " << _panner->automation_state() << endl;
if (!_panner->empty() &&
(_panner->automation_state() & Play ||
((_panner->automation_state() & Touch) && !_panner->touching()))) {
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 9b61b5d816..fd54981908 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1881,6 +1881,11 @@ Session::add_route (Route* route)
_control_out = route;
}
+ AudioTrack* at = dynamic_cast<AudioTrack*>(route);
+ if (at && at->mode() == Destructive) {
+ destructive_index++;
+ }
+
set_dirty();
save_state (_current_snapshot_name);
@@ -2601,7 +2606,7 @@ void
Session::add_source (Source* source)
{
pair<SourceList::key_type, SourceList::mapped_type> entry;
-
+
{
LockMonitor lm (source_lock, __LINE__, __FILE__);
entry.first = source->id();
@@ -2654,8 +2659,109 @@ Session::get_source (ARDOUR::id_t id)
return source;
}
-FileSource *
-Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
+string
+Session::peak_path_from_audio_path (string audio_path)
+{
+ /* XXX hardly bombproof! fix me */
+
+ string res;
+
+ res = PBD::dirname (audio_path);
+ res = PBD::dirname (res);
+ res += '/';
+ res += peak_dir_name;
+ res += '/';
+ res += PBD::basename_nosuffix (audio_path);
+ res += ".peak";
+
+ return res;
+}
+
+string
+Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
+{
+ string look_for;
+ string old_basename = basename_nosuffix (oldname);
+ string new_legalized = legalize_for_path (newname);
+
+ /* note: we know (or assume) the old path is already valid */
+
+ if (destructive) {
+
+ /* destructive file sources have a name of the form:
+
+ /path/to/Tnnnn-NAME(%[LR])?.wav
+
+ 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);
+
+ /* '-' is not a legal character for the NAME part of the path */
+
+ if ((dash = path.find_last_of ('-')) == string::npos) {
+ return "";
+ }
+
+ prefix = path.substr (slash+1, dash-(slash+1));
+
+ path = dir;
+ path += prefix;
+ path += '-';
+ path += new_legalized;
+ path += ".wav"; /* XXX gag me with a spoon */
+
+ } else {
+
+ /* non-destructive file sources have a name of the form:
+
+ /path/to/NAME-nnnnn(%[LR])?.wav
+
+ the task here is to replace NAME with the new name.
+ */
+
+ /* find last slash */
+
+ string dir;
+ string suffix;
+ string::size_type slash;
+ string::size_type dash;
+
+ if ((slash = path.find_last_of ('/')) == string::npos) {
+ return "";
+ }
+
+ dir = path.substr (0, slash+1);
+
+ /* '-' is not a legal character for the NAME part of the path */
+
+ if ((dash = path.find_last_of ('-')) == string::npos) {
+ return "";
+ }
+
+ suffix = path.substr (dash);
+
+ path = dir;
+ path += new_legalized;
+ path += suffix;
+ }
+
+ return path;
+}
+
+string
+Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
{
string spath;
uint32_t cnt;
@@ -2664,56 +2770,74 @@ Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
string legalized;
buf[0] = '\0';
- legalized = legalize_for_path (ds.name());
+ legalized = legalize_for_path (name);
/* find a "version" of the file name that doesn't exist in
any of the possible directories.
*/
- for (cnt = 1; cnt <= limit; ++cnt) {
-
+ for (cnt = (destructive ? destructive_index + 1 : 1); cnt <= limit; ++cnt) {
+
vector<space_and_path>::iterator i;
uint32_t existing = 0;
-
+
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
-
+
spath = (*i).path;
-
+
if (destructive) {
spath += tape_dir_name;
} else {
spath += sound_dir_name;
}
- spath += '/';
- spath += legalized;
-
- if (ds.n_channels() < 2) {
- snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
- } else if (ds.n_channels() == 2) {
- if (chan == 0) {
- snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
+
+ if (destructive) {
+ if (nchan < 2) {
+ snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
+ } else if (nchan == 2) {
+ if (nchan == 0) {
+ snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
+ } else {
+ snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
+ }
+ } else if (nchan < 26) {
+ snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
} else {
- snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
+ snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
}
- } else if (ds.n_channels() < 26) {
- snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
} else {
- snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
+
+ spath += '/';
+ spath += legalized;
+
+ if (nchan < 2) {
+ snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
+ } else if (nchan == 2) {
+ if (chan == 0) {
+ snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
+ } else {
+ snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
+ }
+ } else if (nchan < 26) {
+ snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
+ } else {
+ snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
+ }
}
if (access (buf, F_OK) == 0) {
existing++;
}
}
-
+
if (existing == 0) {
break;
}
- }
- if (cnt > limit) {
- error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, ds.name()) << endmsg;
- throw failed_constructor();
+ if (cnt > limit) {
+ error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
+ throw failed_constructor();
+ }
}
/* we now have a unique name for the file, but figure out where to
@@ -2722,7 +2846,11 @@ Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
string foo = buf;
- spath = discover_best_sound_dir ();
+ if (destructive) {
+ spath = tape_dir ();
+ } else {
+ spath = discover_best_sound_dir ();
+ }
string::size_type pos = foo.find_last_of ('/');
@@ -2732,6 +2860,14 @@ Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
spath += foo.substr (pos + 1);
}
+ return spath;
+}
+
+FileSource *
+Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
+{
+ string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
+
/* this might throw failed_constructor(), which is OK */
if (destructive) {
@@ -2944,40 +3080,6 @@ Session::is_auditioning () const
}
}
-
-string
-Session::peak_path_from_audio_path (string audio_path)
-{
- /* XXX hardly bombproof! fix me */
-
- string res;
-
- res = PBD::dirname (audio_path);
- res = PBD::dirname (res);
- res += '/';
- res += peak_dir_name;
- res += '/';
- res += PBD::basename_nosuffix (audio_path);
- res += ".peak";
-
- return res;
-}
-
-string
-Session::old_peak_path_from_audio_path (string audio_path)
-{
- /* This is a hangover from when audio and peak files
- lived in the same directory. We need it to to
- be able to open old sessions.
- */
-
- /* XXX hardly bombproof! fix me */
-
- string res = audio_path.substr (0, audio_path.find_last_of ('.'));
- res += ".peak";
- return res;
-}
-
void
Session::set_all_solo (bool yn)
{
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 5bb7ad01e4..3bfcb97c70 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -192,6 +192,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
pending_abort = false;
layer_model = MoveAddHigher;
xfade_model = ShortCrossfade;
+ destructive_index = 0;
/* allocate conversion buffers */
_conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
@@ -401,13 +402,32 @@ Session::setup_raid_path (string path)
if (colons == 0) {
- /* no multiple search path, just one directory (common case) */
+ /* no multiple search path, just one location (common case) */
sp.path = path;
sp.blocks = 0;
session_dirs.push_back (sp);
+
+ string fspath;
+
+ /* sounds dir */
+
+ fspath += sp.path;
+ if (fspath[fspath.length()-1] != '/') {
+ fspath += '/';
+ }
+ fspath += sound_dir_name;
+ fspath += ':';
+
+ /* tape dir */
+
+ fspath += sp.path;
+ if (fspath[fspath.length()-1] != '/') {
+ fspath += '/';
+ }
+ fspath += tape_dir_name;
- FileSource::set_search_path (path + sound_dir_name);
+ FileSource::set_search_path (fspath);
return;
}
@@ -418,6 +438,9 @@ Session::setup_raid_path (string path)
sp.blocks = 0;
sp.path = remaining.substr (0, colon);
+ session_dirs.push_back (sp);
+
+ /* add sounds to file search path */
fspath += sp.path;
if (fspath[fspath.length()-1] != '/') {
@@ -426,7 +449,14 @@ Session::setup_raid_path (string path)
fspath += sound_dir_name;
fspath += ':';
- session_dirs.push_back (sp);
+ /* add tape dir to file search path */
+
+ fspath += sp.path;
+ if (fspath[fspath.length()-1] != '/') {
+ fspath += '/';
+ }
+ fspath += tape_dir_name;
+ fspath += ':';
remaining = remaining.substr (colon+1);
}
@@ -436,11 +466,19 @@ Session::setup_raid_path (string path)
sp.blocks = 0;
sp.path = remaining;
+ fspath += ':';
fspath += sp.path;
if (fspath[fspath.length()-1] != '/') {
fspath += '/';
}
fspath += sound_dir_name;
+ fspath += ':';
+
+ fspath += sp.path;
+ if (fspath[fspath.length()-1] != '/') {
+ fspath += '/';
+ }
+ fspath += tape_dir_name;
session_dirs.push_back (sp);
}
@@ -681,7 +719,7 @@ Session::save_state (string snapshot_name, bool pending)
if (!pending) {
bool was_dirty = dirty();
-
+
_state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
if (was_dirty) {
@@ -1298,10 +1336,18 @@ Session::state(bool full_state)
/* Don't save information about FileSources that are empty */
FileSource* fs;
-
+
if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
- if (fs->length() == 0) {
- continue;
+ DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
+
+ /* destructive file sources are OK if they are empty, because
+ we will re-use them every time.
+ */
+
+ if (!dfs) {
+ if (fs->length() == 0) {
+ continue;
+ }
}
}
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index 5db5f95c35..522f94b5c2 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -87,7 +87,7 @@ SndFileSource::init (const string& idstr, bool build_peak)
_path = file;
if (build_peak) {
- if (initialize_peakfile (false, file)) {
+ if (initialize_peakfile (false, _path)) {
sf_close (sf);
sf = 0;
throw failed_constructor ();
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index fb09293fd5..ffb067733d 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -59,7 +59,6 @@ Source::Source (bool announce)
_use_cnt = 0;
_peaks_built = false;
next_peak_clear_should_notify = true;
- peakfile = -1;
_timestamp = 0;
_read_data_count = 0;
_write_data_count = 0;
@@ -70,7 +69,6 @@ Source::Source (const XMLNode& node)
_use_cnt = 0;
_peaks_built = false;
next_peak_clear_should_notify = true;
- peakfile = -1;
_timestamp = 0;
_read_data_count = 0;
_write_data_count = 0;
@@ -82,9 +80,6 @@ Source::Source (const XMLNode& node)
Source::~Source ()
{
- if (peakfile >= 0) {
- close (peakfile);
- }
}
XMLNode&
@@ -320,6 +315,25 @@ Source::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const
}
int
+Source::rename_peakfile (string newpath)
+{
+ /* caller must hold _lock */
+
+ string oldpath = peakpath;
+
+ if (access (oldpath.c_str(), F_OK) == 0) {
+ if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
+ error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
+ return -1;
+ }
+ }
+
+ peakpath = newpath;
+
+ return 0;
+}
+
+int
Source::initialize_peakfile (bool newfile, string audio_path)
{
struct stat statbuf;
@@ -344,33 +358,6 @@ Source::initialize_peakfile (bool newfile, string audio_path)
return -1;
}
- /* older sessions stored peaks in the same directory
- as the audio. so check there as well.
- */
-
- string oldpeakpath = old_peak_path (audio_path);
-
- if (stat (oldpeakpath.c_str(), &statbuf)) {
-
- if (errno == ENOENT) {
-
- statbuf.st_size = 0;
-
- } else {
-
- /* it exists in the audio dir , but there is some kind of error */
-
- error << string_compose(_("Source: cannot stat peakfile \"%1\" or \"%2\""), peakpath, oldpeakpath) << endmsg;
- return -1;
- }
-
- } else {
-
- /* we found it in the sound dir, where they lived once upon a time, in a land ... etc. */
-
- peakpath = oldpeakpath;
- }
-
} else {
/* we found it in the peaks dir */
@@ -391,11 +378,6 @@ Source::initialize_peakfile (bool newfile, string audio_path)
}
}
- if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
- error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
- return -1;
- }
-
if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
build_peaks_from_scratch ();
}
@@ -418,7 +400,8 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
PeakData* staging = 0;
Sample* raw_staging = 0;
char * workbuf = 0;
-
+ int peakfile = -1;
+
expected_peaks = (cnt / (double) frames_per_peak);
scale = npeaks/expected_peaks;
@@ -474,11 +457,21 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
if (scale == 1.0) {
+ off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData);
+
+ /* open, read, close */
+
+ if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
+ error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
+ return -1;
+ }
+
// cerr << "DIRECT PEAKS\n";
- off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData);
+ nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
+ close (peakfile);
- if ((nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte)) != sizeof (PeakData) * npeaks) {
+ if (nread != sizeof (PeakData) * npeaks) {
cerr << "Source["
<< _name
<< "]: cannot read peaks from peakfile! (read only "
@@ -537,6 +530,13 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
+ /* open ... close during out: handling */
+
+ if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
+ error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
+ return 0;
+ }
+
while (nvisual_peaks < npeaks) {
if (i == stored_peaks_read) {
@@ -669,6 +669,10 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
}
out:
+ if (peakfile >= 0) {
+ close (peakfile);
+ }
+
if (staging) {
delete [] staging;
}
@@ -734,7 +738,6 @@ Source::build_peaks ()
}
if (pr_signal) {
- off_t fend = lseek (peakfile, 0, SEEK_END);
PeaksReady (); /* EMIT SIGNAL */
}
}
@@ -754,6 +757,7 @@ Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
jack_nframes_t frames_read;
jack_nframes_t frames_to_read;
off_t first_peak_byte;
+ int peakfile = -1;
int ret = -1;
#ifdef DEBUG_PEAK_BUILD
@@ -772,6 +776,11 @@ Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
workbuf = new char[max(frames_per_peak, cnt) * 4];
+ if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
+ error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
+ return -1;
+ }
+
while (cnt) {
frames_to_read = min (frames_per_peak, cnt);
@@ -810,6 +819,9 @@ Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
out:
delete [] peakbuf;
+ if (peakfile >= 0) {
+ close (peakfile);
+ }
if (workbuf)
delete [] workbuf;
return ret;
@@ -856,13 +868,27 @@ Source::release ()
jack_nframes_t
Source::available_peaks (double zoom_factor) const
{
+ int peakfile;
+ off_t end;
+
if (zoom_factor < frames_per_peak) {
return length(); // peak data will come from the audio file
}
/* peak data comes from peakfile */
- LockMonitor lm (_lock, __LINE__, __FILE__);
- off_t end = lseek (peakfile, 0, SEEK_END);
+ if ((peakfile = ::open (peakpath.c_str(), O_RDONLY)) < 0) {
+ error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
+ return 0;
+ }
+
+ {
+ LockMonitor lm (_lock, __LINE__, __FILE__);
+ end = lseek (peakfile, 0, SEEK_END);
+ }
+
+ close (peakfile);
+
return (end/sizeof(PeakData)) * frames_per_peak;
}
+