ardour
source.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <float.h>
23 #include <cerrno>
24 #include <ctime>
25 #include <cmath>
26 #include <iomanip>
27 #include <algorithm>
28 #include <fstream>
29 
30 #include <glibmm/threads.h>
31 #include <glibmm/miscutils.h>
32 #include <glibmm/fileutils.h>
33 #include "pbd/xml++.h"
34 #include "pbd/pthread_utils.h"
35 #include "pbd/enumwriter.h"
36 
37 #include "ardour/debug.h"
38 #include "ardour/session.h"
39 #include "ardour/source.h"
41 
42 #include "i18n.h"
43 
44 using namespace std;
45 using namespace ARDOUR;
46 using namespace PBD;
47 
48 Source::Source (Session& s, DataType type, const string& name, Flag flags)
49  : SessionObject(s, name)
50  , _type(type)
51  , _flags(flags)
52  , _timeline_position(0)
53  , _use_count (0)
54  , _level (0)
55 {
56  _analysed = false;
57  _timestamp = 0;
58  fix_writable_flags ();
59 }
60 
61 Source::Source (Session& s, const XMLNode& node)
62  : SessionObject(s, "unnamed source")
63  , _type(DataType::AUDIO)
64  , _flags (Flag (Writable|CanRename))
65  , _timeline_position(0)
66  , _use_count (0)
67  , _level (0)
68 {
69  _timestamp = 0;
70  _analysed = false;
71 
73  throw failed_constructor();
74  }
75 
77 }
78 
80 {
81  DEBUG_TRACE (DEBUG::Destruction, string_compose ("Source %1 destructor %2\n", _name, this));
82 }
83 
84 void
86 {
87  if (!_session.writable()) {
89  }
90 }
91 
92 XMLNode&
94 {
95  XMLNode *node = new XMLNode ("Source");
96  char buf[64];
97 
98  node->add_property ("name", name());
99  node->add_property ("type", _type.to_string());
100  node->add_property (X_("flags"), enum_2_string (_flags));
101  id().print (buf, sizeof (buf));
102  node->add_property ("id", buf);
103 
104  if (_timestamp != 0) {
105  snprintf (buf, sizeof (buf), "%ld", _timestamp);
106  node->add_property ("timestamp", buf);
107  }
108 
109  return *node;
110 }
111 
112 int
113 Source::set_state (const XMLNode& node, int version)
114 {
115  const XMLProperty* prop;
116 
117  if ((prop = node.property ("name")) != 0) {
118  _name = prop->value();
119  } else {
120  return -1;
121  }
122 
123  if (!set_id (node)) {
124  return -1;
125  }
126 
127  if ((prop = node.property ("type")) != 0) {
128  _type = DataType(prop->value());
129  }
130 
131  if ((prop = node.property ("timestamp")) != 0) {
132  sscanf (prop->value().c_str(), "%ld", &_timestamp);
133  }
134 
135  if ((prop = node.property (X_("flags"))) != 0) {
136  _flags = Flag (string_2_enum (prop->value(), _flags));
137  } else {
138  _flags = Flag (0);
139 
140  }
141 
142  /* old style, from the period when we had DestructiveFileSource */
143  if ((prop = node.property (X_("destructive"))) != 0) {
145  }
146 
147  if (version < 3000) {
148  /* a source with an XML node must necessarily already exist,
149  and therefore cannot be removable/writable etc. etc.; 2.X
150  sometimes marks sources as removable which shouldn't be.
151  */
152  if (!(_flags & Destructive)) {
154  }
155  }
156 
157  return 0;
158 }
159 
160 bool
162 {
164  return _analysed;
165 }
166 
167 void
169 {
170  {
172  _analysed = yn;
173  }
174 
175  if (yn) {
177  AnalysisChanged(); // EMIT SIGNAL
178  }
179 }
180 
181 int
182 Source::load_transients (const string& path)
183 {
184  ifstream file (path.c_str());
185 
186  if (!file) {
187  return -1;
188  }
189 
190  transients.clear ();
191 
192  stringstream strstr;
193  double val;
194 
195  while (file.good()) {
196  file >> val;
197 
198  if (!file.fail()) {
199  framepos_t frame = (framepos_t) floor (val * _session.frame_rate());
200  transients.push_back (frame);
201  }
202  }
203 
204  return 0;
205 }
206 
207 string
209 {
210  vector<string> parts;
211  string s;
212 
213  /* old sessions may not have the analysis directory */
214 
216 
217  s = _session.analysis_dir ();
218  parts.push_back (s);
219 
220  s = id().to_s();
221  s += '.';
223  parts.push_back (s);
224 
225  return Glib::build_filename (parts);
226 }
227 
228 bool
230 {
231  /* looks to see if the analysis files for this source are on disk.
232  if so, mark us already analysed.
233  */
234 
235  string path = get_transients_path ();
236  bool ok = true;
237 
238  if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
239  ok = false;
240  }
241 
242  // XXX add other tests here as appropriate
243 
244  set_been_analysed (ok);
245  return ok;
246 }
247 
248 void
250 {
251  // This operation is not allowed for sources for destructive tracks or out-of-session files.
252 
253  /* XXX need a way to detect _within_session() condition here - move it from FileSource?
254  */
255 
256  if ((_flags & Destructive)) {
257  return;
258  }
259 
261 }
262 
263 void
265 {
266  _timeline_position = pos;
267 }
268 
269 void
271 {
272  if (!writable()) {
273  return;
274  }
275 
276  if (yn) {
278  } else {
280  }
281 }
282 
283 void
285 {
286  g_atomic_int_inc (&_use_count);
287 }
288 
289 void
291 {
292 #ifndef NDEBUG
293  gint oldval = g_atomic_int_add (&_use_count, -1);
294  if (oldval <= 0) {
295  cerr << "Bad use dec for " << name() << endl;
296  abort ();
297  }
298  assert (oldval > 0);
299 #else
300  g_atomic_int_add (&_use_count, -1);
301 #endif
302 }
303 
304 bool
306 {
307  return (_flags & Writable) && _session.writable();
308 }
309 
Flag _flags
Definition: source.h:119
ARDOUR::Session & _session
PBD::Signal0< void > AnalysisChanged
Definition: source.h:94
const std::string & value() const
Definition: xml++.h:159
bool writable() const
Definition: session.h:173
LIBARDOUR_API uint64_t Destruction
Definition: debug.cc:38
#define enum_2_string(e)
Definition: enumwriter.h:97
virtual void dec_use_count()
Definition: source.cc:290
const char * to_string() const
Definition: data_type.h:77
time_t _timestamp
Definition: source.h:120
virtual void inc_use_count()
Definition: source.cc:284
virtual ~Source()
Definition: source.cc:79
Glib::Threads::Mutex _analysis_lock
Definition: source.h:124
Definition: Beats.hpp:239
framepos_t _timeline_position
Definition: source.h:121
framecnt_t frame_rate() const
Definition: session.h:365
bool has_been_analysed() const
Definition: source.cc:161
XMLNode & get_state()
Definition: source.cc:93
virtual void set_timeline_position(framepos_t pos)
Definition: source.cc:264
#define X_(Text)
Definition: i18n.h:13
bool _analysed
Definition: source.h:122
std::string analysis_dir() const
Analysis data.
XMLProperty * property(const char *)
Definition: xml++.cc:413
#define string_2_enum(str, e)
Definition: enumwriter.h:98
gint _use_count
Definition: source.h:125
AnalysisFeatureList transients
Definition: source.h:96
Definition: amp.h:29
const PBD::ID & id() const
Definition: stateful.h:68
std::string to_s() const
Definition: id.cc:78
void print(char *buf, uint32_t bufsize) const
Definition: id.cc:73
bool set_id(const XMLNode &)
Definition: stateful.cc:381
void mark_for_remove()
Definition: source.cc:249
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
int64_t framepos_t
Definition: types.h:66
static int loading_state_version
Definition: stateful.h:90
PBD::Property< std::string > _name
XMLProperty * add_property(const char *name, const std::string &value)
const char * name
Writable
Definition: selectable.h:36
Definition: xml++.h:95
DataType _type
Definition: source.h:118
std::string name() const
virtual bool check_for_analysis_data_on_disk()
Definition: source.cc:229
Definition: debug.h:30
void fix_writable_flags()
Definition: source.cc:85
std::string get_transients_path() const
Definition: source.cc:208
void set_allow_remove_if_empty(bool yn)
Definition: source.cc:270
bool writable() const
Definition: source.cc:305
int set_state(const XMLNode &, int version)
Definition: source.cc:113
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
virtual void set_been_analysed(bool yn)
Definition: source.cc:168
static std::string operational_identifier()
int load_transients(const std::string &)
Definition: source.cc:182