X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Futils.cc;h=f9d16a47b49050ff9c661838d0896ae8e88a7cc3;hb=a406d9183adc67075a4e802fd8254c2560df9964;hp=f7a4e1431604a68797c9872602811a44fbfbe3b7;hpb=bb9cc45cd22af67ac275a5e73accbe14fee664d8;p=ardour.git diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index f7a4e14316..f9d16a47b4 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -21,7 +21,6 @@ #include "libardour-config.h" #endif -#define __STDC_FORMAT_MACROS 1 #include #include /* for sprintf */ @@ -35,7 +34,11 @@ #include #include #include -#include +#include +#include + +#include +#include #ifdef HAVE_WORDEXP #include @@ -45,6 +48,7 @@ #include "pbd/stacktrace.h" #include "pbd/xml++.h" #include "pbd/basename.h" +#include "pbd/strsplit.h" #include "ardour/utils.h" #include "i18n.h" @@ -52,14 +56,14 @@ using namespace ARDOUR; using namespace std; using namespace PBD; -using Glib::ustring; -ustring -legalize_for_path (ustring str) +string +legalize_for_path (const string& str) { - ustring::size_type pos; - ustring legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=: "; - ustring legal; +#if OLD_SCHOOL_PROHIBITIVE + string::size_type pos; + string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=: "; + string legal; legal = str; pos = 0; @@ -70,19 +74,36 @@ legalize_for_path (ustring str) } return legal; +#else + string::size_type pos; + string illegal_chars = "/\\"; /* DOS, POSIX. Yes, we're going to ignore HFS */ + string legal; + + legal = str; + pos = 0; + + while ((pos = legal.find_first_of (illegal_chars, pos)) != string::npos) { + legal.replace (pos, 1, "_"); + pos += 1; + } + + return legal; +#endif } -string bump_name_once(std::string name) +string +bump_name_once (const std::string& name, char delimiter) { - string::size_type period; + string::size_type delim; string newname; - if ((period = name.find_last_of ('.')) == string::npos) { + if ((delim = name.find_last_of (delimiter)) == string::npos) { newname = name; - newname += ".1"; + newname += delimiter; + newname += "1"; } else { int isnumber = 1; - const char *last_element = name.c_str() + period + 1; + const char *last_element = name.c_str() + delim + 1; for (size_t i = 0; i < strlen(last_element); i++) { if (!isdigit(last_element[i])) { isnumber = 0; @@ -91,18 +112,19 @@ string bump_name_once(std::string name) } errno = 0; - long int version = strtol (name.c_str()+period+1, (char **)NULL, 10); + int32_t version = strtol (name.c_str()+delim+1, (char **)NULL, 10); if (isnumber == 0 || errno != 0) { // last_element is not a number, or is too large newname = name; - newname += ".1"; + newname += delimiter; + newname += "1"; } else { char buf[32]; - snprintf (buf, sizeof(buf), "%ld", version+1); + snprintf (buf, sizeof(buf), "%d", version+1); - newname = name.substr (0, period+1); + newname = name.substr (0, delim+1); newname += buf; } } @@ -111,13 +133,46 @@ string bump_name_once(std::string name) } -ostream& -operator<< (ostream& o, const BBT_Time& bbt) +bool +could_be_a_valid_path (const string& path) { - o << bbt.bars << '|' << bbt.beats << '|' << bbt.ticks; - return o; + vector posix_dirs; + vector dos_dirs; + string testpath; + + split (path, posix_dirs, '/'); + split (path, dos_dirs, '\\'); + + /* remove the last component of each */ + + posix_dirs.erase (--posix_dirs.end()); + dos_dirs.erase (--dos_dirs.end()); + + if (G_DIR_SEPARATOR == '/') { + for (vector::iterator x = posix_dirs.begin(); x != posix_dirs.end(); ++x) { + testpath = Glib::build_filename (testpath, *x); + cerr << "Testing " << testpath << endl; + if (!Glib::file_test (testpath, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) { + return false; + } + } + } + + if (G_DIR_SEPARATOR == '\\') { + testpath = ""; + for (vector::iterator x = dos_dirs.begin(); x != dos_dirs.end(); ++x) { + testpath = Glib::build_filename (testpath, *x); + cerr << "Testing " << testpath << endl; + if (!Glib::file_test (testpath, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) { + return false; + } + } + } + + return true; } + XMLNode * find_named_node (const XMLNode& node, string name) { @@ -157,7 +212,7 @@ cmp_nocase (const string& s, const string& s2) } int -touch_file (ustring path) +touch_file (string path) { int fd = open (path.c_str(), O_RDWR|O_CREAT, 0660); if (fd >= 0) { @@ -167,8 +222,8 @@ touch_file (ustring path) return 1; } -ustring -region_name_from_path (ustring path, bool strip_channels, bool add_channel_suffix, uint32_t total, uint32_t this_one) +string +region_name_from_path (string path, bool strip_channels, bool add_channel_suffix, uint32_t total, uint32_t this_one) { path = PBD::basename_nosuffix (path); @@ -176,7 +231,7 @@ region_name_from_path (ustring path, bool strip_channels, bool add_channel_suffi /* remove any "?R", "?L" or "?[a-z]" channel identifier */ - ustring::size_type len = path.length(); + string::size_type len = path.length(); if (len > 3 && (path[len-2] == '%' || path[len-2] == '?' || path[len-2] == '.') && (path[len-1] == 'R' || path[len-1] == 'L' || (islower (path[len-1])))) { @@ -200,13 +255,13 @@ region_name_from_path (ustring path, bool strip_channels, bool add_channel_suffi } bool -path_is_paired (ustring path, ustring& pair_base) +path_is_paired (string path, string& pair_base) { - ustring::size_type pos; + string::size_type pos; /* remove any leading path */ - if ((pos = path.find_last_of ('/')) != string::npos) { + if ((pos = path.find_last_of (G_DIR_SEPARATOR)) != string::npos) { path = path.substr(pos+1); } @@ -216,7 +271,7 @@ path_is_paired (ustring path, ustring& pair_base) path = path.substr (0, pos); } - ustring::size_type len = path.length(); + string::size_type len = path.length(); /* look for possible channel identifier: "?R", "%R", ".L" etc. */ @@ -231,9 +286,13 @@ path_is_paired (ustring path, ustring& pair_base) return false; } -ustring -path_expand (ustring path) +string +path_expand (string path) { + if (path.empty()) { + return path; + } + #ifdef HAVE_WORDEXP /* Handle tilde and environment variable expansion in session path */ string ret = path; @@ -262,7 +321,7 @@ path_expand (ustring path) #endif } -#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS) +#if __APPLE__ string CFStringRefToStdString(CFStringRef stringRef) { @@ -279,10 +338,10 @@ CFStringRefToStdString(CFStringRef stringRef) delete [] buf; return result; } -#endif // HAVE_COREAUDIO +#endif // __APPLE__ void -compute_equal_power_fades (nframes_t nframes, float* in, float* out) +compute_equal_power_fades (framecnt_t nframes, float* in, float* out) { double step; @@ -290,7 +349,7 @@ compute_equal_power_fades (nframes_t nframes, float* in, float* out) in[0] = 0.0f; - for (nframes_t i = 1; i < nframes - 1; ++i) { + for (framecnt_t i = 1; i < nframes - 1; ++i) { in[i] = in[i-1] + step; } @@ -299,7 +358,7 @@ compute_equal_power_fades (nframes_t nframes, float* in, float* out) const float pan_law_attenuation = -3.0f; const float scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f); - for (nframes_t n = 0; n < nframes; ++n) { + for (framecnt_t n = 0; n < nframes; ++n) { float inVal = in[n]; float outVal = 1 - inVal; out[n] = outVal * (scale * outVal + 1.0f - scale); @@ -310,11 +369,11 @@ compute_equal_power_fades (nframes_t nframes, float* in, float* out) EditMode string_to_edit_mode (string str) { - if (str == _("Splice Edit")) { + if (str == _("Splice")) { return Splice; - } else if (str == _("Slide Edit")) { + } else if (str == _("Slide")) { return Slide; - } else if (str == _("Lock Edit")) { + } else if (str == _("Lock")) { return Lock; } fatal << string_compose (_("programming error: unknown edit mode string \"%1\""), str) << endmsg; @@ -327,25 +386,21 @@ edit_mode_to_string (EditMode mode) { switch (mode) { case Slide: - return _("Slide Edit"); + return _("Slide"); case Lock: - return _("Lock Edit"); + return _("Lock"); default: case Splice: - return _("Splice Edit"); + return _("Splice"); } } -SlaveSource -string_to_slave_source (string str) +SyncSource +string_to_sync_source (string str) { - if (str == _("Internal")) { - return None; - } - - if (str == _("MTC")) { + if (str == _("MIDI Timecode") || str == _("MTC")) { return MTC; } @@ -357,29 +412,31 @@ string_to_slave_source (string str) return JACK; } - fatal << string_compose (_("programming error: unknown slave source string \"%1\""), str) << endmsg; + fatal << string_compose (_("programming error: unknown sync source string \"%1\""), str) << endmsg; /*NOTREACHED*/ - return None; + return JACK; } +/** @param sh Return a short version of the string */ const char* -slave_source_to_string (SlaveSource src) +sync_source_to_string (SyncSource src, bool sh) { switch (src) { case JACK: return _("JACK"); case MTC: - return _("MTC"); + if (sh) { + return _("MTC"); + } else { + return _("MIDI Timecode"); + } case MIDIClock: return _("MIDI Clock"); - - default: - case None: - return _("Internal"); - } + /* GRRRR .... stupid, stupid gcc - you can't get here from there, all enum values are handled */ + return _("JACK"); } float @@ -520,6 +577,80 @@ string_is_affirmative (const std::string& str) return str == "1" || str == "y" || str == "Y" || (!g_strncasecmp(str.c_str(), "yes", str.length())); } +const char* +native_header_format_extension (HeaderFormat hf, const DataType& type) +{ + if (type == DataType::MIDI) { + return ".mid"; + } + + switch (hf) { + case BWF: + return ".wav"; + case WAVE: + return ".wav"; + case WAVE64: + return ".w64"; + case CAF: + return ".caf"; + case AIFF: + return ".aif"; + case iXML: + return ".ixml"; + case RF64: + return ".rf64"; + } + + fatal << string_compose (_("programming error: unknown native header format: %1"), hf); + /*NOTREACHED*/ + return ".wav"; +} + +bool +matching_unsuffixed_filename_exists_in (const string& dir, const string& path) +{ + string bws = basename_nosuffix (path); + struct dirent* dentry; + struct stat statbuf; + DIR* dead; + bool ret = false; + + if ((dead = ::opendir (dir.c_str())) == 0) { + error << string_compose (_("cannot open directory %1 (%2)"), dir, strerror (errno)) << endl; + return false; + } + + while ((dentry = ::readdir (dead)) != 0) { + + /* avoid '.' and '..' */ + + if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || + (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) { + continue; + } + + string fullpath = Glib::build_filename (dir, dentry->d_name); + + if (::stat (fullpath.c_str(), &statbuf)) { + continue; + } + + if (!S_ISREG (statbuf.st_mode)) { + continue; + } + + string bws2 = basename_nosuffix (dentry->d_name); + + if (bws2 == bws) { + ret = true; + break; + } + } + + ::closedir (dead); + return ret; +} + extern "C" { void c_stacktrace() { stacktrace (cerr); } }