remove midi_interpolation member of DiskIOProcessor (was used only to call ::distance...
[ardour.git] / libs / ardour / disk_io.cc
1 /*
2     Copyright (C) 2009-2016 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
20 #include "pbd/debug.h"
21 #include "pbd/error.h"
22
23 #include "ardour/audioplaylist.h"
24 #include "ardour/butler.h"
25 #include "ardour/debug.h"
26 #include "ardour/disk_io.h"
27 #include "ardour/disk_reader.h"
28 #include "ardour/disk_writer.h"
29 #include "ardour/location.h"
30 #include "ardour/midi_ring_buffer.h"
31 #include "ardour/midi_playlist.h"
32 #include "ardour/playlist.h"
33 #include "ardour/playlist_factory.h"
34 #include "ardour/rc_configuration.h"
35 #include "ardour/session.h"
36 #include "ardour/session_playlists.h"
37
38 #include "pbd/i18n.h"
39
40 using namespace ARDOUR;
41 using namespace PBD;
42 using namespace std;
43
44 const string DiskIOProcessor::state_node_name = X_("DiskIOProcessor");
45
46 // PBD::Signal0<void> DiskIOProcessor::DiskOverrun;
47 // PBD::Signal0<void>  DiskIOProcessor::DiskUnderrun;
48
49 DiskIOProcessor::DiskIOProcessor (Session& s, string const & str, Flag f)
50         : Processor (s, str)
51         , _flags (f)
52         , i_am_the_modifier (false)
53         , _seek_required (false)
54         , _slaved (false)
55         , loop_location (0)
56         , in_set_state (false)
57         , playback_sample (0)
58         , _need_butler (false)
59         , channels (new ChannelList)
60         , _midi_buf (new MidiRingBuffer<samplepos_t> (s.butler()->midi_diskstream_buffer_size()))
61         , _samples_written_to_ringbuffer (0)
62         , _samples_read_from_ringbuffer (0)
63 {
64         set_display_to_user (false);
65 }
66
67 void
68 DiskIOProcessor::init ()
69 {
70         set_block_size (_session.get_block_size());
71 }
72
73 void
74 DiskIOProcessor::set_buffering_parameters (BufferingPreset bp)
75 {
76         samplecnt_t read_chunk_size;
77         samplecnt_t read_buffer_size;
78         samplecnt_t write_chunk_size;
79         samplecnt_t write_buffer_size;
80
81         if (!get_buffering_presets (bp, read_chunk_size, read_buffer_size, write_chunk_size, write_buffer_size)) {
82                 return;
83         }
84
85         DiskReader::set_chunk_samples (read_chunk_size);
86         DiskWriter::set_chunk_samples (write_chunk_size);
87
88         Config->set_audio_capture_buffer_seconds (write_buffer_size);
89         Config->set_audio_playback_buffer_seconds (read_buffer_size);
90 }
91
92 bool
93 DiskIOProcessor::get_buffering_presets (BufferingPreset bp,
94                                         samplecnt_t& read_chunk_size,
95                                         samplecnt_t& read_buffer_size,
96                                         samplecnt_t& write_chunk_size,
97                                         samplecnt_t& write_buffer_size)
98 {
99         switch (bp) {
100         case Small:
101                 read_chunk_size = 65536;  /* samples */
102                 write_chunk_size = 65536; /* samples */
103                 read_buffer_size = 5;  /* seconds */
104                 write_buffer_size = 5; /* seconds */
105                 break;
106
107         case Medium:
108                 read_chunk_size = 262144;  /* samples */
109                 write_chunk_size = 131072; /* samples */
110                 read_buffer_size = 10;  /* seconds */
111                 write_buffer_size = 10; /* seconds */
112                 break;
113
114         case Large:
115                 read_chunk_size = 524288; /* samples */
116                 write_chunk_size = 131072; /* samples */
117                 read_buffer_size = 20; /* seconds */
118                 write_buffer_size = 20; /* seconds */
119                 break;
120
121         default:
122                 return false;
123         }
124
125         return true;
126 }
127
128 bool
129 DiskIOProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out)
130 {
131         if (in.n_midi() != 0 && in.n_midi() != 1) {
132                 /* we only support zero or 1 MIDI stream */
133                 return false;
134         }
135
136         /* currently no way to deliver different channels that we receive */
137         out = in;
138
139         return true;
140 }
141
142 bool
143 DiskIOProcessor::configure_io (ChanCount in, ChanCount out)
144 {
145         DEBUG_TRACE (DEBUG::DiskIO, string_compose ("Configuring %1 for in:%2 out:%3\n", name(), in, out));
146
147         bool changed = false;
148
149         {
150                 RCUWriter<ChannelList> writer (channels);
151                 boost::shared_ptr<ChannelList> c = writer.get_copy();
152
153                 uint32_t n_audio = in.n_audio();
154
155                 if (n_audio > c->size()) {
156                         add_channel_to (c, n_audio - c->size());
157                         changed = true;
158                 } else if (n_audio < c->size()) {
159                         remove_channel_from (c, c->size() - n_audio);
160                         changed = true;
161                 }
162
163                 /* writer leaves scope, actual channel list is updated */
164         }
165
166         if (in.n_midi() > 0 && !_midi_buf) {
167                 const size_t size = _session.butler()->midi_diskstream_buffer_size();
168                 _midi_buf = new MidiRingBuffer<samplepos_t>(size);
169                 changed = true;
170         }
171
172         if (changed) {
173                 seek (_session.transport_sample());
174         }
175
176         return Processor::configure_io (in, out);
177 }
178
179 int
180 DiskIOProcessor::set_block_size (pframes_t nframes)
181 {
182         return 0;
183 }
184
185 int
186 DiskIOProcessor::set_loop (Location *location)
187 {
188         if (location) {
189                 if (location->start() >= location->end()) {
190                         error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
191                         return -1;
192                 }
193         }
194
195         loop_location = location;
196
197         LoopSet (location); /* EMIT SIGNAL */
198         return 0;
199 }
200
201 void
202 DiskIOProcessor::non_realtime_locate (samplepos_t location)
203 {
204         /* now refill channel buffers */
205
206         seek (location, true);
207 }
208
209 void
210 DiskIOProcessor::non_realtime_speed_change ()
211 {
212         if (_seek_required) {
213                 seek (_session.transport_sample(), true);
214                 _seek_required = false;
215         }
216 }
217
218 bool
219 DiskIOProcessor::realtime_speed_change ()
220 {
221         return true;
222 }
223
224 int
225 DiskIOProcessor::set_state (const XMLNode& node, int version)
226 {
227         XMLProperty const * prop;
228
229         Processor::set_state (node, version);
230
231         if ((prop = node.property ("flags")) != 0) {
232                 _flags = Flag (string_2_enum (prop->value(), _flags));
233         }
234
235         return 0;
236 }
237
238 int
239 DiskIOProcessor::add_channel_to (boost::shared_ptr<ChannelList> c, uint32_t how_many)
240 {
241         while (how_many--) {
242                 c->push_back (new ChannelInfo (_session.butler()->audio_diskstream_playback_buffer_size()));
243                 interpolation.add_channel_to (_session.butler()->audio_diskstream_playback_buffer_size(), speed_buffer_size);
244                 DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: new channel, write space = %2 read = %3\n",
245                                                             name(),
246                                                             c->back()->buf->write_space(),
247                                                             c->back()->buf->read_space()));
248         }
249
250         return 0;
251 }
252
253 int
254 DiskIOProcessor::add_channel (uint32_t how_many)
255 {
256         RCUWriter<ChannelList> writer (channels);
257         boost::shared_ptr<ChannelList> c = writer.get_copy();
258
259         return add_channel_to (c, how_many);
260 }
261
262 int
263 DiskIOProcessor::remove_channel_from (boost::shared_ptr<ChannelList> c, uint32_t how_many)
264 {
265         while (how_many-- && !c->empty()) {
266                 delete c->back();
267                 c->pop_back();
268                 interpolation.remove_channel_from ();
269         }
270
271         return 0;
272 }
273
274 int
275 DiskIOProcessor::remove_channel (uint32_t how_many)
276 {
277         RCUWriter<ChannelList> writer (channels);
278         boost::shared_ptr<ChannelList> c = writer.get_copy();
279
280         return remove_channel_from (c, how_many);
281 }
282
283 void
284 DiskIOProcessor::playlist_deleted (boost::weak_ptr<Playlist> wpl)
285 {
286         boost::shared_ptr<Playlist> pl (wpl.lock());
287
288         if (!pl) {
289                 return;
290         }
291
292         for (uint32_t n = 0; n < DataType::num_types; ++n) {
293                 if (pl == _playlists[n]) {
294
295                         /* this catches an ordering issue with session destruction. playlists
296                            are destroyed before disk readers. we have to invalidate any handles
297                            we have to the playlist.
298                         */
299                         _playlists[n].reset ();
300                         break;
301                 }
302         }
303 }
304
305 boost::shared_ptr<AudioPlaylist>
306 DiskIOProcessor::audio_playlist () const
307 {
308         return boost::dynamic_pointer_cast<AudioPlaylist> (_playlists[DataType::AUDIO]);
309 }
310
311 boost::shared_ptr<MidiPlaylist>
312 DiskIOProcessor::midi_playlist () const
313 {
314         return boost::dynamic_pointer_cast<MidiPlaylist> (_playlists[DataType::MIDI]);
315 }
316
317 int
318 DiskIOProcessor::use_playlist (DataType dt, boost::shared_ptr<Playlist> playlist)
319 {
320         if (!playlist) {
321                 return 0;
322         }
323
324         DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: set to use playlist %2 (%3)\n", name(), playlist->name(), dt.to_string()));
325
326         if (playlist == _playlists[dt]) {
327                 DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: already using that playlist\n", name()));
328                 return 0;
329         }
330
331         playlist_connections.drop_connections ();
332
333         if (_playlists[dt]) {
334                 _playlists[dt]->release();
335         }
336
337         _playlists[dt] = playlist;
338         playlist->use();
339
340         playlist->ContentsChanged.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_modified, this));
341         playlist->LayeringChanged.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_modified, this));
342         playlist->DropReferences.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_deleted, this, boost::weak_ptr<Playlist>(playlist)));
343         playlist->RangesMoved.connect_same_thread (playlist_connections, boost::bind (&DiskIOProcessor::playlist_ranges_moved, this, _1, _2));
344
345         DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1 now using playlist %1 (%2)\n", name(), playlist->name(), playlist->id()));
346
347         return 0;
348 }
349
350 DiskIOProcessor::ChannelInfo::ChannelInfo (samplecnt_t bufsize)
351         : buf (new RingBufferNPT<Sample> (bufsize))
352 {
353         /* touch the ringbuffer buffer, which will cause
354            them to be mapped into locked physical RAM if
355            we're running with mlockall(). this doesn't do
356            much if we're not.
357         */
358
359         memset (buf->buffer(), 0, sizeof (Sample) * buf->bufsize());
360         capture_transition_buf = new RingBufferNPT<CaptureTransition> (256);
361 }
362
363 void
364 DiskIOProcessor::ChannelInfo::resize (samplecnt_t bufsize)
365 {
366         delete buf;
367         buf = new RingBufferNPT<Sample> (bufsize);
368         memset (buf->buffer(), 0, sizeof (Sample) * buf->bufsize());
369 }
370
371 DiskIOProcessor::ChannelInfo::~ChannelInfo ()
372 {
373         delete buf;
374         buf = 0;
375
376         delete capture_transition_buf;
377         capture_transition_buf = 0;
378 }
379
380 void
381 DiskIOProcessor::drop_route ()
382 {
383         _route.reset ();
384 }
385
386 void
387 DiskIOProcessor::set_route (boost::shared_ptr<Route> r)
388 {
389         _route = r;
390
391         if (_route) {
392                 _route->DropReferences.connect_same_thread (*this, boost::bind (&DiskIOProcessor::drop_route, this));
393         }
394 }
395
396 /** Get the start, end, and length of a location "atomically".
397  *
398  * Note: Locations don't get deleted, so all we care about when I say "atomic"
399  * is that we are always pointing to the same one and using start/length values
400  * obtained just once.  Use this function to achieve this since location being
401  * a parameter achieves this.
402  */
403 void
404 DiskIOProcessor::get_location_times(const Location* location,
405                    samplepos_t*     start,
406                    samplepos_t*     end,
407                    samplepos_t*     length)
408 {
409         if (location) {
410                 *start  = location->start();
411                 *end    = location->end();
412                 *length = *end - *start;
413         }
414 }
415