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:
parent
0346cdc281
commit
ee29fcacfb
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
39
libs/ardour/session_utils.cc
Normal file
39
libs/ardour/session_utils.cc
Normal 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
|
Loading…
Reference in New Issue
Block a user