X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsource.cc;h=f08d08b86e4e529fe316923ee3052265ef542ecc;hb=22dc575e4cbc35a5d486d6f448332fb721865d57;hp=eebc64d46392a52804a9e36c02d28c8309d9499c;hpb=79986643c0c904f6574bb5323e2233a43a9e622e;p=ardour.git diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc index eebc64d463..f08d08b86e 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -28,39 +27,54 @@ #include #include #include +#include #include +#include +#include #include #include #include +#include +#include +#include #include "i18n.h" -using std::min; -using std::max; - +using namespace std; using namespace ARDOUR; -Source::Source (string name) +Source::Source (Session& s, const string& name, DataType type) + : SessionObject(s, name) + , _type(type) { - _name = name; - _use_cnt = 0; + // not true.. is this supposed to be an assertion? + //assert(_name.find("/") == string::npos); + + _analysed = false; _timestamp = 0; + _length = 0; + _in_use = 0; } -Source::Source (const XMLNode& node) +Source::Source (Session& s, const XMLNode& node) + : SessionObject(s, "unnamed source") + , _type(DataType::AUDIO) { - _use_cnt = 0; _timestamp = 0; + _length = 0; + _analysed = false; + _in_use = 0; - if (set_state (node)) { + if (set_state (node) || _type == DataType::NIL) { throw failed_constructor(); } } Source::~Source () { + notify_callbacks (); } XMLNode& @@ -70,7 +84,8 @@ Source::get_state () char buf[64]; node->add_property ("name", _name); - _id.print (buf); + node->add_property ("type", _type.to_string()); + _id.print (buf, sizeof (buf)); node->add_property ("id", buf); if (_timestamp != 0) { @@ -98,22 +113,157 @@ Source::set_state (const XMLNode& node) return -1; } + if ((prop = node.property ("type")) != 0) { + _type = DataType(prop->value()); + } + if ((prop = node.property ("timestamp")) != 0) { sscanf (prop->value().c_str(), "%ld", &_timestamp); } + + // Don't think this is valid, absolute paths fail + //assert(_name.find("/") == string::npos); return 0; } void -Source::use () +Source::update_length (nframes_t pos, nframes_t cnt) +{ + if (pos + cnt > _length) { + _length = pos+cnt; + } +} + +void +Source::add_playlist (boost::shared_ptr pl) { - _use_cnt++; + std::pair res; + std::pair, uint32_t> newpair (pl, 1); + Glib::Mutex::Lock lm (_playlist_lock); + + res = _playlists.insert (newpair); + + if (!res.second) { + /* it already existed, bump count */ + res.first->second++; + } + + pl->GoingAway.connect (bind (mem_fun (*this, &Source::remove_playlist), boost::weak_ptr (pl))); } void -Source::release () +Source::remove_playlist (boost::weak_ptr wpl) { - if (_use_cnt) --_use_cnt; + boost::shared_ptr pl (wpl.lock()); + + if (!pl) { + return; + } + + PlaylistMap::iterator x; + Glib::Mutex::Lock lm (_playlist_lock); + + if ((x = _playlists.find (pl)) != _playlists.end()) { + if (x->second > 1) { + x->second--; + } else { + _playlists.erase (x); + } + } +} + +uint32_t +Source::used () const +{ + return _playlists.size(); +} + +bool +Source::has_been_analysed() const +{ + Glib::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 + } +} + +int +Source::load_transients (const string& path) +{ + ifstream file (path.c_str()); + + if (!file) { + 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); + } + } + + return 0; +} + +string +Source::get_transients_path () const +{ + vector parts; + string s; + + /* old sessions may not have the analysis directory */ + + _session.ensure_subdirs (); + + s = _session.analysis_dir (); + parts.push_back (s); + + s = _id.to_s(); + s += '.'; + s += TransientDetector::operational_identifier(); + parts.push_back (s); + + return Glib::build_filename (parts); +} + +bool +Source::check_for_analysis_data_on_disk () +{ + /* looks to see if the analysis files for this source are on disk. + if so, mark us already analysed. + */ + + string path = get_transients_path (); + bool ok = true; + + if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) { + ok = false; + } + + // XXX add other tests here as appropriate + + set_been_analysed (ok); + return ok; }