X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsource.cc;h=f9772ec9eddbd4c2210c486e2b1581ac91ba7bad;hb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;hp=f819e6eb42cc317a8c75a4f64ec0f3d2eca25a6d;hpb=dbf3ba2d73dfa2b3230ff5829e4a4a49c7c5ba5f;p=ardour.git diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc index f819e6eb42..f9772ec9ed 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -19,17 +19,15 @@ #include #include -#include -#include #include #include #include #include #include #include -#include -#include +#include "pbd/gstdio_compat.h" +#include #include #include #include "pbd/xml++.h" @@ -37,11 +35,12 @@ #include "pbd/enumwriter.h" #include "ardour/debug.h" +#include "ardour/profile.h" #include "ardour/session.h" #include "ardour/source.h" #include "ardour/transient_detector.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace ARDOUR; @@ -53,6 +52,7 @@ Source::Source (Session& s, DataType type, const string& name, Flag flags) , _flags(flags) , _timeline_position(0) , _use_count (0) + , _level (0) { _analysed = false; _timestamp = 0; @@ -65,6 +65,7 @@ Source::Source (Session& s, const XMLNode& node) , _flags (Flag (Writable|CanRename)) , _timeline_position(0) , _use_count (0) + , _level (0) { _timestamp = 0; _analysed = false; @@ -98,7 +99,7 @@ Source::get_state () node->add_property ("name", name()); node->add_property ("type", _type.to_string()); node->add_property (X_("flags"), enum_2_string (_flags)); - _id.print (buf, sizeof (buf)); + id().print (buf, sizeof (buf)); node->add_property ("id", buf); if (_timestamp != 0) { @@ -110,9 +111,9 @@ Source::get_state () } int -Source::set_state (const XMLNode& node, int /*version*/) +Source::set_state (const XMLNode& node, int version) { - const XMLProperty* prop; + XMLProperty const * prop; if ((prop = node.property ("name")) != 0) { _name = prop->value(); @@ -120,9 +121,7 @@ Source::set_state (const XMLNode& node, int /*version*/) return -1; } - if ((prop = node.property ("id")) != 0) { - _id = prop->value (); - } else { + if (!set_id (node)) { return -1; } @@ -146,54 +145,69 @@ Source::set_state (const XMLNode& node, int /*version*/) _flags = Flag (_flags | Destructive); } + if (Profile->get_trx() && (_flags & Destructive)) { + error << string_compose (_("%1: this session uses destructive tracks, which are not supported"), PROGRAM_NAME) << endmsg; + return -1; + } + + if (version < 3000) { + /* a source with an XML node must necessarily already exist, + and therefore cannot be removable/writable etc. etc.; 2.X + sometimes marks sources as removable which shouldn't be. + */ + if (!(_flags & Destructive)) { + _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); + } + } + return 0; } bool Source::has_been_analysed() const { - Glib::Mutex::Lock lm (_analysis_lock); + Glib::Threads::Mutex::Lock lm (_analysis_lock); return _analysed; } void Source::set_been_analysed (bool yn) { - { - Glib::Mutex::Lock lm (_analysis_lock); - _analysed = yn; - } - if (yn) { - load_transients (get_transients_path()); - AnalysisChanged(); // EMIT SIGNAL + if (0 == load_transients (get_transients_path())) { + yn = false; + } } + if (yn != _analysed) { + Glib::Threads::Mutex::Lock lm (_analysis_lock); + _analysed = yn; + } + AnalysisChanged(); // EMIT SIGNAL } int Source::load_transients (const string& path) { - ifstream file (path.c_str()); - - if (!file) { + int rv = 0; + FILE *tf; + if (! (tf = g_fopen (path.c_str (), "rb"))) { return -1; } transients.clear (); - - stringstream strstr; - double val; - - while (file.good()) { - file >> val; - - if (!file.fail()) { - nframes64_t frame = (nframes64_t) floor (val * _session.frame_rate()); - transients.push_back (frame); + while (!feof (tf) && !ferror(tf)) { + double val; + if (1 != fscanf (tf, "%lf", &val)) { + rv = -1; + break; } + + framepos_t frame = (framepos_t) floor (val * _session.frame_rate()); + transients.push_back (frame); } - return 0; + ::fclose (tf); + return rv; } string @@ -209,7 +223,7 @@ Source::get_transients_path () const s = _session.analysis_dir (); parts.push_back (s); - s = _id.to_s(); + s = id().to_s(); s += '.'; s += TransientDetector::operational_identifier(); parts.push_back (s); @@ -242,10 +256,10 @@ Source::mark_for_remove () { // This operation is not allowed for sources for destructive tracks or out-of-session files. - /* XXX need a way to detect _within_session() condition here - move it from FileSource? + /* XXX need a way to detect _within_session() condition here - move it from FileSource? */ - if ((_flags & Destructive)) { + if ((_flags & Destructive)) { return; } @@ -253,7 +267,7 @@ Source::mark_for_remove () } void -Source::set_timeline_position (int64_t pos) +Source::set_timeline_position (framepos_t pos) { _timeline_position = pos; } @@ -272,17 +286,30 @@ Source::set_allow_remove_if_empty (bool yn) } } +void +Source::inc_use_count () +{ + g_atomic_int_inc (&_use_count); +} + void Source::dec_use_count () { #ifndef NDEBUG - gint oldval = g_atomic_int_exchange_and_add (&_use_count, -1); + gint oldval = g_atomic_int_add (&_use_count, -1); if (oldval <= 0) { cerr << "Bad use dec for " << name() << endl; abort (); } assert (oldval > 0); -#else - g_atomic_int_exchange_and_add (&_use_count, -1); +#else + g_atomic_int_add (&_use_count, -1); #endif } + +bool +Source::writable () const +{ + return (_flags & Writable) && _session.writable(); +} +