#include "libardour-config.h"
#endif
-#define __STDC_FORMAT_MACROS 1
#include <stdint.h>
#include <cstdio> /* for sprintf */
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
-#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include <glibmm/miscutils.h>
+#include <glibmm/fileutils.h>
#ifdef HAVE_WORDEXP
#include <wordexp.h>
#include "pbd/stacktrace.h"
#include "pbd/xml++.h"
#include "pbd/basename.h"
+#include "pbd/strsplit.h"
#include "ardour/utils.h"
#include "i18n.h"
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;
}
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;
}
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;
}
}
}
-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<string> posix_dirs;
+ vector<string> 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<string>::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<string>::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)
{
}
int
-touch_file (ustring path)
+touch_file (string path)
{
int fd = open (path.c_str(), O_RDWR|O_CREAT, 0660);
if (fd >= 0) {
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);
/* 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])))) {
}
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);
}
- /* remove filename suffixes etc. */
+ /* remove filename suffixes etc. */
if ((pos = path.find_last_of ('.')) != string::npos) {
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. */
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;
#endif
}
-#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS)
+#if __APPLE__
string
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;
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;
}
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);
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;
{
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;
}
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
}
else if (val <= METER_FALLOFF_FASTER) {
return MeterFalloffFaster;
- }
+ }
else {
return MeterFalloffFastest;
}
{
/* to be used only with XML data - not intended to handle user input */
- if (str == "1" || str == "y" || str == "Y") {
- return true;
- } else {
- std::string str_uc;
- std::transform(str.begin(), str.end(), str_uc.begin(), ::toupper);
- if (str_uc == "YES") {
- return true;
- }
- }
- return false;
+ 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" {