13
0

Replace Session::discover_best_sound/midi_dir with Session::get_best_session_directory_for_new_source

git-svn-id: svn://localhost/ardour2/trunk@1997 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Tim Mayberry 2007-06-17 00:45:58 +00:00
parent 0346cdc281
commit ee29fcacfb
7 changed files with 79 additions and 229 deletions

View File

@ -106,6 +106,7 @@ session_state.cc
session_time.cc
session_timefx.cc
session_transport.cc
session_utils.cc
silentfilesource.cc
sndfile_helpers.cc
sndfilesource.cc

View File

@ -1556,10 +1556,7 @@ class Session : public PBD::StatefulDestructible
Glib::Mutex space_lock;
string old_sound_dir (bool with_path = true) const;
string discover_best_sound_dir (bool destructive = false);
string discover_best_midi_dir ();
int ensure_sound_dir (string, string&);
int ensure_midi_dir (string, string&);
string get_best_session_directory_for_new_source ();
void refresh_disk_space ();
mutable gint _playback_load;

View File

@ -10,6 +10,17 @@ using std::string;
int find_session (string str, string& path, string& snapshot, bool& isnew);
/**
* Create a SessionDirectory at the path specified by
* session_directory_path, this includes all subdirectories.
*
* @return true if the session directory was able to be created
* or if it already existed, false otherwise.
*
* @see SessionDirectory
*/
bool create_session_directory (const string& session_directory_path);
};
#endif

View File

@ -36,6 +36,7 @@
#include <ardour/ardour.h>
#include <ardour/types.h>
#include <ardour/session.h>
#include <ardour/session_directory.h>
#include <ardour/audio_diskstream.h>
#include <ardour/sndfilesource.h>
#include <ardour/sndfile_helpers.h>
@ -147,7 +148,9 @@ Session::import_audiofile (import_status& status)
newfiles.push_back (boost::shared_ptr<AudioFileSource>());
}
sounds_dir = discover_best_sound_dir ();
SessionDirectory sdir(get_best_session_directory_for_new_source ());
sounds_dir = sdir.sound_path().to_string();
basepath = PBD::basename_nosuffix (status.paths.front());
for (int n = 0; n < info.channels; ++n) {

View File

@ -2972,7 +2972,9 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
string foo = buf;
spath = discover_best_sound_dir ();
SessionDirectory sdir(get_best_session_directory_for_new_source ());
spath = sdir.sound_path().to_string();
spath += '/';
string::size_type pos = foo.find_last_of ('/');
@ -3159,7 +3161,9 @@ Session::midi_path_from_name (string name)
string foo = buf;
spath = discover_best_midi_dir ();
SessionDirectory sdir(get_best_session_directory_for_new_source ());
spath = sdir.sound_path().to_string();
spath += '/';
string::size_type pos = foo.find_last_of ('/');
@ -3890,12 +3894,13 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
boost::shared_ptr<AudioFileSource> fsource;
uint32_t x;
char buf[PATH_MAX+1];
string dir;
ChanCount nchans(track.audio_diskstream()->n_channels());
nframes_t position;
nframes_t this_chunk;
nframes_t to_do;
BufferSet buffers;
SessionDirectory sdir(get_best_session_directory_for_new_source ());
const string sound_dir = sdir.sound_path().to_string();
// any bigger than this seems to cause stack overflows in called functions
const nframes_t chunk_size = (128 * 1024)/4;
@ -3913,13 +3918,11 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
if (track.has_external_redirects()) {
goto out;
}
dir = discover_best_sound_dir ();
for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) {
for (x = 0; x < 99999; ++x) {
snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", dir.c_str(), playlist->name().c_str(), chan_n, x+1);
snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1);
if (access (buf, F_OK) != 0) {
break;
}

View File

@ -64,6 +64,7 @@
#include <ardour/configuration.h>
#include <ardour/session.h>
#include <ardour/session_directory.h>
#include <ardour/session_utils.h>
#include <ardour/buffer.h>
#include <ardour/audio_diskstream.h>
#include <ardour/midi_diskstream.h>
@ -1504,14 +1505,15 @@ Session::path_from_region_name (string name, string identifier)
{
char buf[PATH_MAX+1];
uint32_t n;
string dir = discover_best_sound_dir ();
SessionDirectory sdir(get_best_session_directory_for_new_source());
string sound_dir = sdir.sound_path().to_string();
for (n = 0; n < 999999; ++n) {
if (identifier.length()) {
snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(),
identifier.c_str(), n);
} else {
snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(), n);
}
if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
@ -1660,102 +1662,16 @@ Session::refresh_disk_space ()
#endif
}
int
Session::ensure_sound_dir (string path, string& result)
{
string dead;
string peak;
/* Ensure that the parent directory exists */
if (g_mkdir_with_parents (path.c_str(), 0775)) {
error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
return -1;
}
/* Ensure that the sounds directory exists */
result = path;
result += '/';
result += sound_dir_name;
if (g_mkdir_with_parents (result.c_str(), 0775)) {
error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
return -1;
}
dead = path;
dead += '/';
dead += dead_sound_dir_name;
if (g_mkdir_with_parents (dead.c_str(), 0775)) {
error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
return -1;
}
peak = path;
peak += '/';
peak += peak_dir_name;
if (g_mkdir_with_parents (peak.c_str(), 0775)) {
error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
return -1;
}
/* callers expect this to be terminated ... */
result += '/';
return 0;
}
int
Session::ensure_midi_dir (string path, string& result)
{
string dead;
/* Ensure that the parent directory exists */
if (g_mkdir_with_parents (path.c_str(), 0775)) {
error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
return -1;
}
/* Ensure that the sounds directory exists */
result = path;
result += '/';
result += midi_dir_name;
if (g_mkdir_with_parents (result.c_str(), 0775)) {
error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
return -1;
}
dead = path;
dead += '/';
dead += dead_midi_dir_name;
if (g_mkdir_with_parents (dead.c_str(), 0775)) {
error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
return -1;
}
/* callers expect this to be terminated ... */
result += '/';
return 0;
}
string
Session::discover_best_sound_dir (bool destructive)
Session::get_best_session_directory_for_new_source ()
{
vector<space_and_path>::iterator i;
string result;
string result = _session_dir->root_path().to_string();
/* handle common case without system calls */
if (session_dirs.size() == 1) {
return sound_dir();
return result;
}
/* OK, here's the algorithm we're following here:
@ -1797,9 +1713,6 @@ Session::discover_best_sound_dir (bool destructive)
}
if (free_enough >= 2) {
bool found_it = false;
/* use RR selection process, ensuring that the one
picked works OK.
*/
@ -1812,19 +1725,15 @@ Session::discover_best_sound_dir (bool destructive)
}
if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
if (ensure_sound_dir ((*i).path, result) == 0) {
if (create_session_directory ((*i).path)) {
result = (*i).path;
last_rr_session_dir = i;
found_it = true;
break;
return result;
}
}
} while (i != last_rr_session_dir);
if (!found_it) {
result = sound_dir();
}
} else {
/* pick FS with the most freespace (and that
@ -1838,125 +1747,12 @@ Session::discover_best_sound_dir (bool destructive)
sort (sorted.begin(), sorted.end(), cmp);
for (i = sorted.begin(); i != sorted.end(); ++i) {
if (ensure_sound_dir ((*i).path, result) == 0) {
if (create_session_directory ((*i).path)) {
result = (*i).path;
last_rr_session_dir = i;
break;
return result;
}
}
/* if the above fails, fall back to the most simplistic solution */
if (i == sorted.end()) {
return sound_dir();
}
}
return result;
}
string
Session::discover_best_midi_dir ()
{
vector<space_and_path>::iterator i;
string result;
/* handle common case without system calls */
if (session_dirs.size() == 1) {
return midi_dir();
}
/* OK, here's the algorithm we're following here:
We want to select which directory to use for
the next file source to be created. Ideally,
we'd like to use a round-robin process so as to
get maximum performance benefits from splitting
the files across multiple disks.
However, in situations without much diskspace, an
RR approach may end up filling up a filesystem
with new files while others still have space.
Its therefore important to pay some attention to
the freespace in the filesystem holding each
directory as well. However, if we did that by
itself, we'd keep creating new files in the file
system with the most space until it was as full
as all others, thus negating any performance
benefits of this RAID-1 like approach.
So, we use a user-configurable space threshold. If
there are at least 2 filesystems with more than this
much space available, we use RR selection between them.
If not, then we pick the filesystem with the most space.
This gets a good balance between the two
approaches.
*/
refresh_disk_space ();
int free_enough = 0;
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
free_enough++;
}
}
if (free_enough >= 2) {
bool found_it = false;
/* use RR selection process, ensuring that the one
picked works OK.
*/
i = last_rr_session_dir;
do {
if (++i == session_dirs.end()) {
i = session_dirs.begin();
}
if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
if (ensure_midi_dir ((*i).path, result) == 0) {
last_rr_session_dir = i;
found_it = true;
break;
}
}
} while (i != last_rr_session_dir);
if (!found_it) {
result = midi_dir();
}
} else {
/* pick FS with the most freespace (and that
seems to actually work ...)
*/
vector<space_and_path> sorted;
space_and_path_ascending_cmp cmp;
sorted = session_dirs;
sort (sorted.begin(), sorted.end(), cmp);
for (i = sorted.begin(); i != sorted.end(); ++i) {
if (ensure_midi_dir ((*i).path, result) == 0) {
last_rr_session_dir = i;
break;
}
}
/* if the above fails, fall back to the most simplistic solution */
if (i == sorted.end()) {
return midi_dir();
}
}
return result;

View File

@ -0,0 +1,39 @@
#include <pbd/error.h>
#include <ardour/session_directory.h>
#include "i18n.h"
namespace ARDOUR {
using namespace PBD;
bool
create_session_directory (const string& session_directory_path)
{
SessionDirectory sdir(session_directory_path);
try
{
// create all the required session directories
sdir.create();
}
catch(sys::filesystem_error& ex)
{
// log the exception
warning << string_compose
(
_("Unable to create session directory at path %1 : %2"),
session_directory_path,
ex.what()
);
return false;
}
// successfully created the session directory
return true;
}
} // namespace ARDOUR