totally untested initial code for MidiPlaylistSource, to provide for compound MIDI...
[ardour.git] / libs / ardour / midi_playlist_source.cc
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 #include "pbd/convert.h"
31 #include "pbd/enumwriter.h"
32
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"
42
43 #include "i18n.h"
44
45 using namespace std;
46 using namespace ARDOUR;
47 using namespace PBD;
48
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)
54 {
55         ensure_buffers_for_level (_level);
56 }
57
58 MidiPlaylistSource::MidiPlaylistSource (Session& s, const XMLNode& node)
59         : Source (s, node)
60         , MidiSource (s, node)
61         , PlaylistSource (s, node)
62 {
63         /* PlaylistSources are never writable, renameable, removable or destructive */
64         _flags = Flag (_flags & ~(Writable|CanRename|Removable|RemovableIfEmpty|RemoveAtDestroy|Destructive));
65
66         /* ancestors have already called ::set_state() in their XML-based
67            constructors.
68         */
69         
70         if (set_state (node, Stateful::loading_state_version, false)) {
71                 throw failed_constructor ();
72         }
73 }
74
75 MidiPlaylistSource::~MidiPlaylistSource ()
76 {
77 }
78
79 XMLNode&
80 MidiPlaylistSource::get_state ()
81 {
82         XMLNode& node (MidiSource::get_state ());
83
84         /* merge PlaylistSource state */
85
86         PlaylistSource::add_state (node);
87
88         return node;
89 }
90
91         
92 int
93 MidiPlaylistSource::set_state (const XMLNode& node, int version) 
94 {
95         return set_state (node, version, true);
96 }
97
98 int
99 MidiPlaylistSource::set_state (const XMLNode& node, int version, bool with_descendants) 
100 {
101         if (with_descendants) {
102                 if (Source::set_state (node, version) || 
103                     MidiSource::set_state (node, version) ||
104                     PlaylistSource::set_state (node, version)) {
105                         return -1;
106                 }
107         }
108
109         ensure_buffers_for_level (_level);
110
111         return 0;
112 }
113
114 framecnt_t
115 MidiPlaylistSource::length (framepos_t)  const
116 {
117         pair<framepos_t,framepos_t> extent = _playlist->get_extent();
118         return extent.second - extent.first;
119 }
120
121 framepos_t 
122 MidiPlaylistSource::read_unlocked (Evoral::EventSink<framepos_t>& dst,
123                                    framepos_t position,
124                                    framepos_t start, framecnt_t cnt,
125                                    MidiStateTracker* tracker) const 
126 {
127         boost::shared_ptr<MidiPlaylist> mp = boost::dynamic_pointer_cast<MidiPlaylist> (_playlist);
128
129         if (!mp) {
130                 return 0;
131         }
132
133         return mp->read (dst, start, cnt);
134 }
135
136 framepos_t 
137 MidiPlaylistSource::write_unlocked (MidiRingBuffer<framepos_t>& dst,
138                                     framepos_t position,
139                                     framecnt_t cnt) 
140 {
141         fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::write_unlocked() called - should be impossible") << endmsg;
142         /*NOTREACHED*/
143         return 0;
144 }
145
146 void 
147 MidiPlaylistSource::append_event_unlocked_beats(const Evoral::Event<Evoral::MusicalTime>& /*ev*/)
148 {
149         fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_unlocked_beats() called - should be impossible") << endmsg;
150         /*NOTREACHED*/
151 }
152
153 void 
154 MidiPlaylistSource::append_event_unlocked_frames(const Evoral::Event<framepos_t>& ev, framepos_t source_start)
155 {
156         fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::append_event_unlocked_frames() called - should be impossible") << endmsg;
157         /*NOTREACHED*/
158 }
159
160 void
161 MidiPlaylistSource::load_model (bool, bool) 
162 {
163         fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::load_model() called - should be impossible") << endmsg;
164         /*NOTREACHED*/
165 }
166
167 void
168 MidiPlaylistSource::destroy_model () 
169 {
170         fatal << string_compose (_("programming error: %1"), "MidiPlaylistSource::destroy_model() called - should be impossible") << endmsg;
171         /*NOTREACHED*/
172 }
173
174 void
175 MidiPlaylistSource::flush_midi ()
176 {
177 }
178
179
180 bool
181 MidiPlaylistSource::empty () const
182 {
183         return !_playlist || _playlist->empty();
184 }
185
186 void
187 MidiPlaylistSource::ensure_buffers_for_level (uint32_t level)
188 {
189 }
190
191