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