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