ardour
audio_playlist_source.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 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 #ifdef WAF_BUILD
20 #include "libardour-config.h"
21 #endif
22 
23 #include <vector>
24 #include <cstdio>
25 
26 #include <glibmm/fileutils.h>
27 #include <glibmm/miscutils.h>
28 
29 #include "pbd/error.h"
30 
31 #include "ardour/audioplaylist.h"
33 #include "ardour/audioregion.h"
35 #include "ardour/session.h"
37 
38 #include "i18n.h"
39 
40 using namespace std;
41 using namespace ARDOUR;
42 using namespace PBD;
43 
44 AudioPlaylistSource::AudioPlaylistSource (Session& s, const ID& orig, const std::string& name, boost::shared_ptr<AudioPlaylist> p,
45  uint32_t chn, frameoffset_t begin, framecnt_t len, Source::Flag flags)
46  : Source (s, DataType::AUDIO, name)
47  , PlaylistSource (s, orig, name, p, DataType::AUDIO, begin, len, flags)
48  , AudioSource (s, name)
49  , _playlist_channel (chn)
50 {
53 }
54 
56  : Source (s, node)
57  , PlaylistSource (s, node)
58  , AudioSource (s, node)
59 {
60  /* PlaylistSources are never writable, renameable, removable or destructive */
62 
63  /* ancestors have already called ::set_state() in their XML-based
64  constructors.
65  */
66 
67  if (set_state (node, Stateful::loading_state_version, false)) {
68  throw failed_constructor ();
69  }
70 
72 }
73 
75 {
76 }
77 
78 XMLNode&
80 {
82  char buf[64];
83 
84  /* merge PlaylistSource state */
85 
87 
88  snprintf (buf, sizeof (buf), "%" PRIu32, _playlist_channel);
89  node.add_property ("channel", buf);
90 
91  return node;
92 }
93 
94 int
95 AudioPlaylistSource::set_state (const XMLNode& node, int version)
96 {
97  return set_state (node, version, true);
98 }
99 
100 int
101 AudioPlaylistSource::set_state (const XMLNode& node, int version, bool with_descendants)
102 {
103  if (with_descendants) {
104  if (Source::set_state (node, version) ||
105  PlaylistSource::set_state (node, version) ||
106  AudioSource::set_state (node, version)) {
107  return -1;
108  }
109  }
110 
111  const XMLProperty* prop;
112  pair<framepos_t,framepos_t> extent = _playlist->get_extent();
113 
114  AudioSource::_length = extent.second - extent.first;
115 
116  if ((prop = node.property (X_("channel"))) == 0) {
117  throw failed_constructor ();
118  }
119 
120  sscanf (prop->value().c_str(), "%" PRIu32, &_playlist_channel);
121 
123 
124  return 0;
125 }
126 
129 {
130  boost::shared_array<Sample> sbuf;
131  boost::shared_array<gain_t> gbuf;
132  framecnt_t to_read;
133  framecnt_t to_zero;
134 
135  /* we must be careful not to read beyond the end of our "section" of
136  * the playlist, because otherwise we may read data that exists, but
137  * is not supposed be part of our data.
138  */
139 
140  if (cnt > _playlist_length - start) {
141  to_read = _playlist_length - start;
142  to_zero = cnt - to_read;
143  } else {
144  to_read = cnt;
145  to_zero = 0;
146  }
147 
148  {
149  /* Don't need to hold the lock for the actual read, and
150  actually, we cannot, but we do want to interlock
151  with any changes to the list of buffers caused
152  by creating new nested playlists/sources
153  */
155  sbuf = _mixdown_buffers[_level-1];
156  gbuf = _gain_buffers[_level-1];
157  }
158 
159  boost::dynamic_pointer_cast<AudioPlaylist>(_playlist)->read (dst, sbuf.get(), gbuf.get(), start+_playlist_offset, to_read, _playlist_channel);
160 
161  if (to_zero) {
162  memset (dst+to_read, 0, sizeof (Sample) * to_zero);
163  }
164 
165  return cnt;
166 }
167 
170 {
171  fatal << string_compose (_("programming error: %1"), "AudioPlaylistSource::write() called - should be impossible") << endmsg;
172  abort(); /*NOTREACHED*/
173  return 0;
174 }
175 
176 bool
178 {
179  return !_playlist || _playlist->empty();
180 }
181 
182 uint32_t
184 {
185  /* use just the first region to decide */
186 
187  if (empty()) {
188  return 1;
189  }
190 
193 
194  return ar->audio_source()->n_channels ();
195 }
196 
197 float
199 {
200  /* use just the first region to decide */
201 
202  if (empty()) {
203  _session.frame_rate ();
204  }
205 
208 
209  return ar->audio_source()->sample_rate ();
210 }
211 
212 int
214 {
216  return initialize_peakfile (string());
217 }
218 
219 string
220 AudioPlaylistSource::peak_path (string /*audio_path_IGNORED*/)
221 {
222  return _peak_path;
223 }
224 
225 
Flag _flags
Definition: source.h:119
frameoffset_t _playlist_offset
ARDOUR::Session & _session
LIBPBD_API Transmitter fatal
std::string peak_path(std::string audio_path)
framecnt_t _length
Definition: audiosource.h:127
int set_state(const XMLNode &, int version)
const std::string & value() const
Definition: xml++.h:159
static std::vector< boost::shared_array< Sample > > _mixdown_buffers
Definition: audiosource.h:120
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
LIBARDOUR_API const char *const peakfile_suffix
Definition: Beats.hpp:239
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
framecnt_t read_unlocked(Sample *dst, framepos_t start, framecnt_t cnt) const
framecnt_t frame_rate() const
Definition: session.h:365
Definition: id.h:32
AudioPlaylistSource(Session &, const PBD::ID &orig, const std::string &name, boost::shared_ptr< AudioPlaylist >, uint32_t chn, frameoffset_t begin, framecnt_t len, Source::Flag flags)
virtual framecnt_t read(Sample *dst, framepos_t start, framecnt_t cnt, int channel=0) const
Definition: audiosource.cc:312
#define _(Text)
Definition: i18n.h:11
XMLNode & get_state()
Definition: audiosource.cc:131
boost::shared_ptr< Playlist > _playlist
int initialize_peakfile(std::string path)
Definition: audiosource.cc:239
#define X_(Text)
Definition: i18n.h:13
int64_t framecnt_t
Definition: types.h:76
XMLProperty * property(const char *)
Definition: xml++.cc:413
float Sample
Definition: types.h:54
framecnt_t write_unlocked(Sample *src, framecnt_t cnt)
int set_state(const XMLNode &, int version)
Definition: amp.h:29
boost::shared_ptr< AudioSource > audio_source(uint32_t n=0) const
void add_state(XMLNode &)
int64_t framepos_t
Definition: types.h:66
int64_t frameoffset_t
Definition: types.h:71
static int loading_state_version
Definition: stateful.h:90
const std::string peak_path() const
static Glib::Threads::Mutex _level_buffer_lock
Definition: audiosource.h:122
XMLProperty * add_property(const char *name, const std::string &value)
const char * name
uint32_t _level
Definition: source.h:126
static void ensure_buffers_for_level(uint32_t, framecnt_t)
const RegionListProperty & region_list() const
Definition: playlist.h:163
Definition: xml++.h:95
std::string name() const
Definition: debug.h:30
static std::vector< boost::shared_array< gain_t > > _gain_buffers
Definition: audiosource.h:121
int set_state(const XMLNode &, int version)
Definition: audiosource.cc:143
const SessionDirectory & session_directory() const
Definition: session.h:182
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
std::pair< framepos_t, framepos_t > get_extent() const
Definition: playlist.cc:2254
bool empty() const
Definition: playlist.cc:2230
Container::reference front()