2 Copyright (C) 2011 Paul Davis
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.
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.
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.
20 #include "libardour-config.h"
26 #include <glibmm/fileutils.h>
27 #include <glibmm/miscutils.h>
29 #include "pbd/error.h"
30 #include "pbd/convert.h"
31 #include "pbd/enumwriter.h"
33 #include "ardour/audioplaylist.h"
34 #include "ardour/audio_playlist_source.h"
35 #include "ardour/audioregion.h"
36 #include "ardour/debug.h"
37 #include "ardour/filename_extensions.h"
38 #include "ardour/session.h"
39 #include "ardour/session_directory.h"
40 #include "ardour/session_playlists.h"
41 #include "ardour/source_factory.h"
46 using namespace ARDOUR;
49 AudioPlaylistSource::AudioPlaylistSource (Session& s, const ID& orig, const std::string& name, boost::shared_ptr<AudioPlaylist> p,
50 uint32_t chn, frameoffset_t begin, framecnt_t len, Source::Flag flags)
51 : Source (s, DataType::AUDIO, name)
52 , AudioSource (s, name)
53 , PlaylistSource (s, orig, name, p, DataType::AUDIO, begin, len, flags)
54 , _playlist_channel (chn)
56 AudioSource::_length = len;
57 ensure_buffers_for_level (_level);
60 AudioPlaylistSource::AudioPlaylistSource (Session& s, const XMLNode& node)
62 , AudioSource (s, node)
63 , PlaylistSource (s, node)
65 /* PlaylistSources are never writable, renameable, removable or destructive */
66 _flags = Flag (_flags & ~(Writable|CanRename|Removable|RemovableIfEmpty|RemoveAtDestroy|Destructive));
68 /* ancestors have already called ::set_state() in their XML-based
72 if (set_state (node, Stateful::loading_state_version, false)) {
73 throw failed_constructor ();
77 AudioPlaylistSource::~AudioPlaylistSource ()
82 AudioPlaylistSource::get_state ()
84 XMLNode& node (AudioSource::get_state ());
87 /* merge PlaylistSource state */
89 PlaylistSource::add_state (node);
91 snprintf (buf, sizeof (buf), "%" PRIu32, _playlist_channel);
92 node.add_property ("channel", buf);
99 AudioPlaylistSource::set_state (const XMLNode& node, int version)
101 return set_state (node, version, true);
105 AudioPlaylistSource::set_state (const XMLNode& node, int version, bool with_descendants)
107 if (with_descendants) {
108 if (Source::set_state (node, version) ||
109 AudioSource::set_state (node, version) ||
110 PlaylistSource::set_state (node, version)) {
115 const XMLProperty* prop;
116 pair<framepos_t,framepos_t> extent = _playlist->get_extent();
117 AudioSource::_length = extent.second - extent.first;
119 if ((prop = node.property (X_("channel"))) == 0) {
120 throw failed_constructor ();
123 sscanf (prop->value().c_str(), "%" PRIu32, &_playlist_channel);
125 ensure_buffers_for_level (_level);
131 AudioPlaylistSource::read_unlocked (Sample* dst, framepos_t start, framecnt_t cnt) const
137 pair<framepos_t,framepos_t> extent = _playlist->get_extent();
139 /* we must be careful not to read beyond the end of our "section" of
140 * the playlist, because otherwise we may read data that exists, but
141 * is not supposed be part of our data.
144 if (cnt > _playlist_length - start) {
145 to_read = _playlist_length - start;
146 to_zero = cnt - to_read;
153 /* Don't need to hold the lock for the actual read, and
154 actually, we cannot, but we do want to interlock
155 with any changes to the list of buffers caused
156 by creating new nested playlists/sources
158 Glib::Mutex::Lock lm (_level_buffer_lock);
159 sbuf = _mixdown_buffers[_level-1];
160 gbuf = _gain_buffers[_level-1];
163 boost::dynamic_pointer_cast<AudioPlaylist>(_playlist)->read (dst, sbuf, gbuf, start+_playlist_offset, to_read, _playlist_channel);
166 memset (dst+to_read, 0, sizeof (Sample) * to_zero);
173 AudioPlaylistSource::write_unlocked (Sample *src, framecnt_t cnt)
175 fatal << string_compose (_("programming error: %1"), "AudioPlaylistSource::write() called - should be impossible") << endmsg;
181 AudioPlaylistSource::empty () const
183 return !_playlist || _playlist->empty();
187 AudioPlaylistSource::n_channels () const
189 /* use just the first region to decide */
195 boost::shared_ptr<Region> r = _playlist->region_list().front ();
196 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
198 return ar->audio_source()->n_channels ();
202 AudioPlaylistSource::sample_rate () const
204 /* use just the first region to decide */
207 _session.frame_rate ();
210 boost::shared_ptr<Region> r = _playlist->region_list().front ();
211 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
213 return ar->audio_source()->sample_rate ();
217 AudioPlaylistSource::setup_peakfile ()
219 _peak_path = Glib::build_filename (_session.session_directory().peak_path().to_string(), name() + ARDOUR::peakfile_suffix);
220 return initialize_peakfile (false, string());
224 AudioPlaylistSource::peak_path (string /*audio_path_IGNORED*/)