summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-06-07 23:12:04 +0000
committerDavid Robillard <d@drobilla.net>2007-06-07 23:12:04 +0000
commitcc18cf3516cd67a1eec0f1e7ed188969c0c646f1 (patch)
treeab6742a86fa648d2875265bde7a8486b970a031b /libs/ardour
parentb17a003d0a6bf27b31d02d6ed447cb73ff855f73 (diff)
Write MIDI files to interchange/sessionname/midifiles (for real this time).
git-svn-id: svn://localhost/ardour2/trunk@1979 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/directory_names.h1
-rw-r--r--libs/ardour/ardour/session.h3
-rw-r--r--libs/ardour/ardour/session_directory.h7
-rw-r--r--libs/ardour/directory_names.cc1
-rw-r--r--libs/ardour/session.cc10
-rw-r--r--libs/ardour/session_directory.cc7
-rw-r--r--libs/ardour/session_state.cc177
-rw-r--r--libs/ardour/smf_source.cc2
8 files changed, 201 insertions, 7 deletions
diff --git a/libs/ardour/ardour/directory_names.h b/libs/ardour/ardour/directory_names.h
index 8fdec60e9c..25f468b15f 100644
--- a/libs/ardour/ardour/directory_names.h
+++ b/libs/ardour/ardour/directory_names.h
@@ -10,6 +10,7 @@ extern const char* const old_sound_dir_name;
extern const char* const sound_dir_name;
extern const char* const midi_dir_name;
extern const char* const dead_sound_dir_name;
+extern const char* const dead_midi_dir_name;
extern const char* const interchange_dir_name;
extern const char* const peak_dir_name;
extern const char* const export_dir_name;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 035a2bde1d..84c334f590 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -257,6 +257,7 @@ class Session : public PBD::StatefulDestructible
sigc::signal<void> DirtyChanged;
std::string sound_dir (bool with_path = true) const;
+ std::string midi_dir (bool with_path = true) const;
std::string peak_dir () const;
std::string automation_dir () const;
@@ -1554,7 +1555,9 @@ class Session : public PBD::StatefulDestructible
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&);
void refresh_disk_space ();
mutable gint _playback_load;
diff --git a/libs/ardour/ardour/session_directory.h b/libs/ardour/ardour/session_directory.h
index 7662894042..41667a6807 100644
--- a/libs/ardour/ardour/session_directory.h
+++ b/libs/ardour/ardour/session_directory.h
@@ -73,6 +73,13 @@ public:
* session.
*/
const path dead_sound_path () const;
+
+ /**
+ * @return The absolute path to the directory that midi
+ * files are moved to when they are no longer part of the
+ * session.
+ */
+ const path dead_midi_path () const;
/**
* @return The absolute path to the directory that audio
diff --git a/libs/ardour/directory_names.cc b/libs/ardour/directory_names.cc
index d78d32f740..dfd794a2a9 100644
--- a/libs/ardour/directory_names.cc
+++ b/libs/ardour/directory_names.cc
@@ -9,6 +9,7 @@ const char* const sound_dir_name = X_("audiofiles");
const char* const midi_dir_name = X_("midifiles");
const char* const peak_dir_name = X_("peaks");
const char* const dead_sound_dir_name = X_("dead_sounds");
+const char* const dead_midi_dir_name = X_("dead_midi");
const char* const interchange_dir_name = X_("interchange");
const char* const export_dir_name = X_("export");
const char* const templates_dir_name = X_("templates");
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index ed1947451b..7ba1e2dfb7 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -3135,8 +3135,7 @@ Session::midi_path_from_name (string name)
spath = (*i).path;
- // FIXME: different directory from audio?
- spath += sound_dir(false) + "/" + legalized;
+ spath += midi_dir(false) + "/" + legalized;
snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
@@ -3161,8 +3160,7 @@ Session::midi_path_from_name (string name)
string foo = buf;
- // FIXME: different directory than audio?
- spath = discover_best_sound_dir ();
+ spath = discover_best_midi_dir ();
spath += '/';
string::size_type pos = foo.find_last_of ('/');
@@ -3179,9 +3177,9 @@ Session::midi_path_from_name (string name)
boost::shared_ptr<MidiSource>
Session::create_midi_source_for_session (MidiDiskstream& ds)
{
- string spath = midi_path_from_name (ds.name());
+ string mpath = midi_path_from_name (ds.name());
- return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, spath, false, frame_rate()));
+ return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate()));
}
diff --git a/libs/ardour/session_directory.cc b/libs/ardour/session_directory.cc
index 0b778d85ca..99a252ecb5 100644
--- a/libs/ardour/session_directory.cc
+++ b/libs/ardour/session_directory.cc
@@ -131,6 +131,12 @@ SessionDirectory::dead_sound_path () const
}
const path
+SessionDirectory::dead_midi_path () const
+{
+ return path(m_root_path) /= dead_midi_dir_name;
+}
+
+const path
SessionDirectory::export_path () const
{
return path(m_root_path) /= export_dir_name;
@@ -145,6 +151,7 @@ SessionDirectory::sub_directories () const
tmp_paths.push_back ( midi_path () );
tmp_paths.push_back ( peak_path () );
tmp_paths.push_back ( dead_sound_path () );
+ tmp_paths.push_back ( dead_midi_path () );
tmp_paths.push_back ( export_path () );
return tmp_paths;
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;
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 9ecb961f19..11b62e488f 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -795,7 +795,7 @@ SMFSource::load_model(bool lock)
time += ev.time;
ev.time = time;
if (ret > 0) { // didn't skip (meta) event
- cerr << "ADDING EVENT TO MODEL: " << ev.time << endl;
+ //cerr << "ADDING EVENT TO MODEL: " << ev.time << endl;
_model->append(ev);
}
}