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/midi_playlist.h"
34 #include "ardour/midi_playlist_source.h"
35 #include "ardour/midi_region.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 MidiPlaylistSource::MidiPlaylistSource (Session& s, const ID& orig, const std::string& name, boost::shared_ptr<MidiPlaylist> p,
50 uint32_t chn, frameoffset_t begin, framecnt_t len, Source::Flag flags)
51 : Source (s, DataType::AUDIO, name)
52 , MidiSource (s, name, flags)
53 , PlaylistSource (s, orig, name, p, DataType::AUDIO, begin, len, flags)
55 ensure_buffers_for_level (_level);
58 MidiPlaylistSource::MidiPlaylistSource (Session& s, const XMLNode& node)
60 , MidiSource (s, node)
61 , PlaylistSource (s, node)
63 /* PlaylistSources are never writable, renameable, removable or destructive */
64 _flags = Flag (_flags & ~(Writable|CanRename|Removable|RemovableIfEmpty|RemoveAtDestroy|Destructive));
66 /* ancestors have already called ::set_state() in their XML-based
70 if (set_state (node, Stateful::loading_state_version, false)) {
71 throw failed_constructor ();
75 MidiPlaylistSource::~MidiPlaylistSource ()
80 MidiPlaylistSource::get_state ()
82 XMLNode& node (MidiSource::get_state ());
84 /* merge PlaylistSource state */
86 PlaylistSource::add_state (node);
93 MidiPlaylistSource::set_state (const XMLNode& node, int version)
95 return set_state (node, version, true);
99 MidiPlaylistSource::set_state (const XMLNode& node, int version, bool with_descendants)
101 if (with_descendants) {
102 if (Source::set_state (node, version) ||
103 MidiSource::set_state (node, version) ||
104 PlaylistSource::set_state (node, version)) {
109 ensure_buffers_for_level (_level);
115 MidiPlaylistSource::length (framepos_t) const
117 pair<framepos_t,framepos_t> extent = _playlist->get_extent();
118 return extent.second - extent.first;
122 MidiPlaylistSource::read_unlocked (Evoral::EventSink<framepos_t>& dst,
124 framepos_t start, framecnt_t cnt,
125 MidiStateTracker* tracker) const
127 boost::shared_ptr<MidiPlaylist> mp = boost::dynamic_pointer_cast<MidiPlaylist> (_playlist);
133 return mp->read (dst, start, cnt);
137 MidiPlaylistSource::write_unlocked (MidiRingBuffer<framepos_t>& dst,
141 fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::write_unlocked() called - should be impossible") << endmsg;
147 MidiPlaylistSource::append_event_unlocked_beats(const Evoral::Event<Evoral::MusicalTime>& /*ev*/)
149 fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_unlocked_beats() called - should be impossible") << endmsg;
154 MidiPlaylistSource::append_event_unlocked_frames(const Evoral::Event<framepos_t>& ev, framepos_t source_start)
156 fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_unlocked_frames() called - should be impossible") << endmsg;
161 MidiPlaylistSource::load_model (bool, bool)
163 fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::load_model() called - should be impossible") << endmsg;
168 MidiPlaylistSource::destroy_model ()
170 fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::destroy_model() called - should be impossible") << endmsg;
175 MidiPlaylistSource::flush_midi ()
181 MidiPlaylistSource::empty () const
183 return !_playlist || _playlist->empty();
187 MidiPlaylistSource::ensure_buffers_for_level (uint32_t level)