diff options
Diffstat (limited to 'libs/ardour/session_state.cc')
-rw-r--r-- | libs/ardour/session_state.cc | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 8d9bb55b59..793093cf70 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -1707,6 +1707,44 @@ Session::ensure_sound_dir (string path, string& 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) { @@ -1815,6 +1853,114 @@ Session::discover_best_sound_dir (bool destructive) 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; +} + int Session::load_playlists (const XMLNode& node) { @@ -1975,6 +2121,33 @@ Session::sound_dir (bool with_path) const } string +Session::midi_dir (bool with_path) const +{ + string res; + string full; + + if (with_path) { + res = _path; + } else { + full = _path; + } + + res += interchange_dir_name; + res += '/'; + res += legalize_for_path (_name); + res += '/'; + res += midi_dir_name; + + if (with_path) { + full = res; + } else { + full += res; + } + + return res; +} + +string Session::peak_dir () const { string res = _path; @@ -2518,6 +2691,8 @@ struct RegionCounter { int Session::cleanup_sources (Session::cleanup_report& rep) { + // FIXME: needs adaptation to midi + vector<boost::shared_ptr<Source> > dead_sources; vector<boost::shared_ptr<Playlist> > playlists_tbd; PathScanner scanner; @@ -2777,6 +2952,8 @@ Session::cleanup_sources (Session::cleanup_report& rep) int Session::cleanup_trash_sources (Session::cleanup_report& rep) { + // FIXME: needs adaptation for MIDI + vector<space_and_path>::iterator i; string dead_sound_dir; struct dirent* dentry; |