Move Loop Location to Processors
[ardour.git] / libs / ardour / disk_writer.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 "ardour/analyser.h"
21 #include "ardour/audioengine.h"
22 #include "ardour/audiofilesource.h"
23 #include "ardour/audio_buffer.h"
24 #include "ardour/audioplaylist.h"
25 #include "ardour/audioregion.h"
26 #include "ardour/butler.h"
27 #include "ardour/debug.h"
28 #include "ardour/disk_writer.h"
29 #include "ardour/midi_playlist.h"
30 #include "ardour/midi_source.h"
31 #include "ardour/midi_track.h"
32 #include "ardour/port.h"
33 #include "ardour/region_factory.h"
34 #include "ardour/session.h"
35 #include "ardour/smf_source.h"
36
37 #include "pbd/i18n.h"
38
39 using namespace ARDOUR;
40 using namespace PBD;
41 using namespace std;
42
43 ARDOUR::samplecnt_t DiskWriter::_chunk_samples = DiskWriter::default_chunk_samples ();
44 PBD::Signal0<void> DiskWriter::Overrun;
45
46 DiskWriter::DiskWriter (Session& s, string const & str, DiskIOProcessor::Flag f)
47         : DiskIOProcessor (s, str, f)
48         , _record_enabled (0)
49         , _record_safe (0)
50         , capture_start_sample (0)
51         , capture_captured (0)
52         , was_recording (false)
53         , first_recordable_sample (max_samplepos)
54         , last_recordable_sample (max_samplepos)
55         , last_possibly_recording (0)
56         , _alignment_style (ExistingMaterial)
57         , _num_captured_loops (0)
58         , _accumulated_capture_offset (0)
59         , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
60 {
61         DiskIOProcessor::init ();
62 }
63
64 DiskWriter::~DiskWriter ()
65 {
66         DEBUG_TRACE (DEBUG::Destruction, string_compose ("DiskWriter %1 @ %2 deleted\n", _name, this));
67
68         boost::shared_ptr<ChannelList> c = channels.reader();
69
70         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
71                 (*chan)->write_source.reset ();
72         }
73 }
74
75 samplecnt_t
76 DiskWriter::default_chunk_samples ()
77 {
78         return 65536;
79 }
80
81 bool
82 DiskWriter::set_write_source_name (string const & str)
83 {
84         _write_source_name = str;
85         return true;
86 }
87
88 void
89 DiskWriter::check_record_status (samplepos_t transport_sample, double speed, bool can_record)
90 {
91         int possibly_recording;
92         const int transport_rolling = 0x4;
93         const int track_rec_enabled = 0x2;
94         const int global_rec_enabled = 0x1;
95         const int fully_rec_enabled = (transport_rolling |track_rec_enabled | global_rec_enabled);
96
97         /* merge together the 3 factors that affect record status, and compute what has changed. */
98
99         possibly_recording = (speed != 0.0f ? 4 : 0)  | (record_enabled() ? 2 : 0) | (can_record ? 1 : 0);
100
101         if (possibly_recording == last_possibly_recording) {
102                 return;
103         }
104
105         if (possibly_recording == fully_rec_enabled) {
106
107                 if (last_possibly_recording == fully_rec_enabled) {
108                         return;
109                 }
110
111                 Location* loc;
112                 if  (_session.config.get_punch_in () && 0 != (loc = _session.locations()->auto_punch_location ())) {
113                         capture_start_sample = loc->start ();
114                 } else {
115                         capture_start_sample = _session.transport_sample ();
116                 }
117
118                 first_recordable_sample = capture_start_sample;
119
120                 if (_alignment_style == ExistingMaterial) {
121                         first_recordable_sample += _capture_offset + _playback_offset;
122                 }
123
124                 if  (_session.config.get_punch_out () && 0 != (loc = _session.locations()->auto_punch_location ())) {
125                         /* this freezes the punch-out point when starting to record.
126                          *
127                          * We should allow to move it or at least allow to disable punch-out
128                          * while rolling..
129                          */
130                         last_recordable_sample = loc->end ();
131                         if (_alignment_style == ExistingMaterial) {
132                                 last_recordable_sample += _capture_offset + _playback_offset;
133                         }
134                 } else {
135                         last_recordable_sample = max_samplepos;
136                 }
137
138                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: @ %2 (STS: %3) CS:%4 FRS: %5 IL: %7, OL: %8 CO: %r9 PO: %10 WOL: %11 WIL: %12\n",
139                                                                       name(),
140                                                                       transport_sample,
141                                                                       _session.transport_sample(),
142                                                                                                                                                                                                                                         capture_start_sample,
143                                                                                                                                                                                                                                         first_recordable_sample,
144                                                                                                                                                                                                                                         last_recordable_sample,
145                                                                       _input_latency,
146                                                                       _output_latency,
147                                                                       _capture_offset,
148                                                                       _playback_offset,
149                                                                       _session.worst_output_latency(),
150                                                                       _session.worst_input_latency()));
151
152
153                 prepare_record_status (capture_start_sample);
154
155         }
156
157         last_possibly_recording = possibly_recording;
158 }
159
160 void
161 DiskWriter::calculate_record_range (Evoral::OverlapType ot, samplepos_t transport_sample, samplecnt_t nframes, samplecnt_t & rec_nframes, samplecnt_t & rec_offset)
162 {
163         switch (ot) {
164         case Evoral::OverlapNone:
165                 rec_nframes = 0;
166                 break;
167
168         case Evoral::OverlapInternal:
169                 /*     ----------    recrange
170                  *       |---|       transrange
171                  */
172                 rec_nframes = nframes;
173                 rec_offset = 0;
174                 break;
175
176         case Evoral::OverlapStart:
177                 /*    |--------|    recrange
178                  *  -----|          transrange
179                  */
180                 rec_nframes = transport_sample + nframes - first_recordable_sample;
181                 if (rec_nframes) {
182                         rec_offset = first_recordable_sample - transport_sample;
183                 }
184                 break;
185
186         case Evoral::OverlapEnd:
187                 /*    |--------|    recrange
188                  *       |--------  transrange
189                  */
190                 rec_nframes = last_recordable_sample - transport_sample;
191                 rec_offset = 0;
192                 break;
193
194         case Evoral::OverlapExternal:
195                 /*    |--------|    recrange
196                  *  --------------  transrange
197                  */
198                 rec_nframes = last_recordable_sample - first_recordable_sample;
199                 rec_offset = first_recordable_sample - transport_sample;
200                 break;
201         }
202
203         DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 rec? %2 @ %3 (for %4) FRF %5 LRF %6 : rf %7 @ %8\n",
204                                                               _name, enum_2_string (ot), transport_sample, nframes,
205                                                               first_recordable_sample, last_recordable_sample, rec_nframes, rec_offset));
206 }
207
208 void
209 DiskWriter::engage_record_enable ()
210 {
211         g_atomic_int_set (&_record_enabled, 1);
212 }
213
214 void
215 DiskWriter::disengage_record_enable ()
216 {
217         g_atomic_int_set (&_record_enabled, 0);
218 }
219
220 void
221 DiskWriter::engage_record_safe ()
222 {
223         g_atomic_int_set (&_record_safe, 1);
224 }
225
226 void
227 DiskWriter::disengage_record_safe ()
228 {
229         g_atomic_int_set (&_record_safe, 0);
230 }
231
232 /** Get the start position (in session samples) of the nth capture in the current pass */
233 ARDOUR::samplepos_t
234 DiskWriter::get_capture_start_sample (uint32_t n) const
235 {
236         Glib::Threads::Mutex::Lock lm (capture_info_lock);
237
238         if (capture_info.size() > n) {
239                 /* this is a completed capture */
240                 return capture_info[n]->start;
241         } else {
242                 /* this is the currently in-progress capture */
243                 return capture_start_sample;
244         }
245 }
246
247 ARDOUR::samplecnt_t
248 DiskWriter::get_captured_samples (uint32_t n) const
249 {
250         Glib::Threads::Mutex::Lock lm (capture_info_lock);
251
252         if (capture_info.size() > n) {
253                 /* this is a completed capture */
254                 return capture_info[n]->samples;
255         } else {
256                 /* this is the currently in-progress capture */
257                 return capture_captured;
258         }
259 }
260
261 void
262 DiskWriter::set_align_style (AlignStyle a, bool force)
263 {
264         if (record_enabled() && _session.actively_recording()) {
265                 return;
266         }
267
268         if ((a != _alignment_style) || force) {
269                 _alignment_style = a;
270                 AlignmentStyleChanged ();
271         }
272 }
273
274 XMLNode&
275 DiskWriter::state ()
276 {
277         XMLNode& node (DiskIOProcessor::state ());
278         node.set_property (X_("type"), X_("diskwriter"));
279         node.set_property (X_("record-safe"), (_record_safe ? X_("yes" : "no")));
280         return node;
281 }
282
283 int
284 DiskWriter::set_state (const XMLNode& node, int version)
285 {
286         if (DiskIOProcessor::set_state (node, version)) {
287                 return -1;
288         }
289
290         if (!node.get_property (X_("record-safe"), _record_safe)) {
291                 _record_safe = false;
292         }
293
294         reset_write_sources (false, true);
295
296         return 0;
297 }
298
299 void
300 DiskWriter::non_realtime_locate (samplepos_t position)
301 {
302         if (_midi_write_source) {
303                 _midi_write_source->set_timeline_position (position);
304         }
305
306         DiskIOProcessor::non_realtime_locate (position);
307 }
308
309
310 void
311 DiskWriter::prepare_record_status (samplepos_t capture_start_sample)
312 {
313         if (recordable() && destructive()) {
314                 boost::shared_ptr<ChannelList> c = channels.reader ();
315                 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
316
317                         RingBufferNPT<CaptureTransition>::rw_vector transitions;
318                         (*chan)->capture_transition_buf->get_write_vector (&transitions);
319
320                         if (transitions.len[0] > 0) {
321                                 transitions.buf[0]->type = CaptureStart;
322                                 transitions.buf[0]->capture_val = capture_start_sample;
323                                 (*chan)->capture_transition_buf->increment_write_ptr(1);
324                         } else {
325                                 // bad!
326                                 fatal << X_("programming error: capture_transition_buf is full on rec start!  inconceivable!")
327                                         << endmsg;
328                         }
329                 }
330         }
331 }
332
333
334 /** Do some record stuff [not described in this comment!]
335  *
336  *  Also:
337  *    - Setup playback_distance with the nframes, or nframes adjusted
338  *      for current varispeed, if appropriate.
339  *    - Setup current_playback_buffer in each ChannelInfo to point to data
340  *      that someone can read playback_distance worth of data from.
341  */
342 void
343 DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample,
344                  double speed, pframes_t nframes, bool result_required)
345 {
346         if (!_active && !_pending_active) {
347                 return;
348         }
349         _active = _pending_active;
350
351         uint32_t n;
352         boost::shared_ptr<ChannelList> c = channels.reader();
353         ChannelList::iterator chan;
354
355         samplecnt_t rec_offset = 0;
356         samplecnt_t rec_nframes = 0;
357         bool nominally_recording;
358
359         bool re = record_enabled ();
360         bool punch_in = _session.config.get_punch_in () && _session.locations()->auto_punch_location ();
361         bool can_record = _session.actively_recording ();
362         can_record |= speed != 0 && _session.get_record_enabled () && punch_in && _session.transport_sample () <= _session.locations()->auto_punch_location ()->start ();
363
364         _need_butler = false;
365
366 #ifndef NDEBUG
367         if (speed != 0 && re) {
368                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: run() start: %2 end: %3 NF: %4\n", _name, start_sample, end_sample, nframes));
369         }
370 #endif
371
372         check_record_status (start_sample, speed, can_record);
373
374         if (nframes == 0) {
375                 return;
376         }
377
378         nominally_recording = (can_record && re);
379
380         // Safeguard against situations where process() goes haywire when autopunching
381         // and last_recordable_sample < first_recordable_sample
382
383         if (last_recordable_sample < first_recordable_sample) {
384                 last_recordable_sample = max_samplepos;
385         }
386
387         const Location* const loop_loc    = _loop_location;
388         samplepos_t           loop_start  = 0;
389         samplepos_t           loop_end    = 0;
390         samplepos_t           loop_length = 0;
391
392         if (loop_loc) {
393                 get_location_times (loop_loc, &loop_start, &loop_end, &loop_length);
394         }
395
396         if (nominally_recording || (re && was_recording && _session.get_record_enabled() && punch_in)) {
397
398                 Evoral::OverlapType ot = Evoral::coverage (first_recordable_sample, last_recordable_sample, start_sample, end_sample);
399                 // XXX should this be transport_sample + nframes - 1 ? coverage() expects its parameter ranges to include their end points
400                 // XXX also, first_recordable_sample & last_recordable_sample may both be == max_samplepos: coverage() will return OverlapNone in that case. Is thak OK?
401                 calculate_record_range (ot, start_sample, nframes, rec_nframes, rec_offset);
402
403                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: this time record %2 of %3 samples, offset %4\n", _name, rec_nframes, nframes, rec_offset));
404
405                 if (rec_nframes && !was_recording) {
406                         capture_captured = 0;
407
408                         if (loop_loc) {
409                                 /* Loop recording, so pretend the capture started at the loop
410                                    start rgardless of what time it is now, so the source starts
411                                    at the loop start and can handle time wrapping around.
412                                    Otherwise, start the source right now as usual.
413                                 */
414                                 capture_captured     = start_sample - loop_start;
415                                 capture_start_sample = loop_start;
416                         }
417
418                         if (_midi_write_source) {
419                                 _midi_write_source->mark_write_starting_now (capture_start_sample, capture_captured, loop_length);
420                         }
421
422                         g_atomic_int_set (const_cast<gint*> (&_samples_pending_write), 0);
423                         g_atomic_int_set (const_cast<gint*> (&_num_captured_loops), 0);
424
425                         was_recording = true;
426
427                 }
428
429                 /* For audio: not writing samples to the capture ringbuffer offsets
430                  * the recording. For midi: we need to keep track of the record range
431                  * and subtract the accumulated difference from the event time.
432                  */
433                 if (rec_nframes) {
434                         _accumulated_capture_offset += rec_offset;
435                 } else {
436                         _accumulated_capture_offset += nframes;
437                 }
438
439         }
440
441         if (can_record && !_last_capture_sources.empty ()) {
442                 _last_capture_sources.clear ();
443         }
444
445         if (rec_nframes) {
446
447                 /* AUDIO */
448
449                 const size_t n_buffers = bufs.count().n_audio();
450
451                 for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
452
453                         ChannelInfo* chaninfo (*chan);
454                         AudioBuffer& buf (bufs.get_audio (n%n_buffers));
455
456                         chaninfo->buf->get_write_vector (&chaninfo->rw_vector);
457
458                         if (rec_nframes <= (samplecnt_t) chaninfo->rw_vector.len[0]) {
459
460                                 Sample *incoming = buf.data (rec_offset);
461                                 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * rec_nframes);
462
463                         } else {
464
465                                 samplecnt_t total = chaninfo->rw_vector.len[0] + chaninfo->rw_vector.len[1];
466
467                                 if (rec_nframes > total) {
468                                         DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 overrun in %2, rec_nframes = %3 total space = %4\n",
469                                                                                     DEBUG_THREAD_SELF, name(), rec_nframes, total));
470                                         Overrun ();
471                                         return;
472                                 }
473
474                                 Sample *incoming = buf.data (rec_offset);
475                                 samplecnt_t first = chaninfo->rw_vector.len[0];
476
477                                 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * first);
478                                 memcpy (chaninfo->rw_vector.buf[1], incoming + first, sizeof (Sample) * (rec_nframes - first));
479                         }
480
481                         chaninfo->buf->increment_write_ptr (rec_nframes);
482
483                 }
484
485                 /* MIDI */
486
487                 // Pump entire port buffer into the ring buffer (TODO: split cycles?)
488                 MidiBuffer& buf    = bufs.get_midi (0);
489                 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
490                 MidiChannelFilter* filter = mt ? &mt->capture_filter() : 0;
491
492                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
493                         Evoral::Event<MidiBuffer::TimeType> ev (*i, false);
494                         if (ev.time() + rec_offset > rec_nframes) {
495                                 break;
496                         }
497 #ifndef NDEBUG
498                         if (DEBUG_ENABLED(DEBUG::MidiIO)) {
499                                 const uint8_t* __data = ev.buffer();
500                                 DEBUG_STR_DECL(a);
501                                 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), start_sample, ev.size()));
502                                 for (size_t i=0; i < ev.size(); ++i) {
503                                         DEBUG_STR_APPEND(a,hex);
504                                         DEBUG_STR_APPEND(a,"0x");
505                                         DEBUG_STR_APPEND(a,(int)__data[i]);
506                                         DEBUG_STR_APPEND(a,' ');
507                                 }
508                                 DEBUG_STR_APPEND(a,'\n');
509                                 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
510                         }
511 #endif
512                         /* Write events to the capture buffer in samples from session start,
513                            but ignoring looping so event time progresses monotonically.
514                            The source knows the loop length so it knows exactly where the
515                            event occurs in the series of recorded loops and can implement
516                            any desirable behaviour.  We don't want to send event with
517                            transport time here since that way the source can not
518                            reconstruct their actual time; future clever MIDI looping should
519                            probably be implemented in the source instead of here.
520                         */
521                         const samplecnt_t loop_offset = _num_captured_loops * loop_length;
522                         const samplepos_t event_time = start_sample + loop_offset - _accumulated_capture_offset + ev.time();
523                         if (event_time < 0 || event_time < first_recordable_sample) {
524                                 /* Event out of range, skip */
525                                 continue;
526                         }
527
528                         bool skip_event = false;
529                         if (mt) {
530                                 /* skip injected immediate/out-of-band events */
531                                 MidiBuffer const& ieb (mt->immediate_event_buffer());
532                                 for (MidiBuffer::const_iterator j = ieb.begin(); j != ieb.end(); ++j) {
533                                         if (*j == ev) {
534                                                 skip_event = true;
535                                         }
536                                 }
537                         }
538                         if (skip_event) {
539                                 continue;
540                         }
541
542                         if (!filter || !filter->filter(ev.buffer(), ev.size())) {
543                                 _midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
544                         }
545                 }
546                 g_atomic_int_add (const_cast<gint*>(&_samples_pending_write), nframes);
547
548                 if (buf.size() != 0) {
549                         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
550
551                         if (lm.locked ()) {
552                                 /* Copy this data into our GUI feed buffer and tell the GUI
553                                    that it can read it if it likes.
554                                 */
555                                 _gui_feed_buffer.clear ();
556
557                                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
558                                         /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
559                                            the end of the world if it does.
560                                         */
561                                         _gui_feed_buffer.push_back ((*i).time() + start_sample, (*i).size(), (*i).buffer());
562                                 }
563                         }
564
565                         DataRecorded (_midi_write_source); /* EMIT SIGNAL */
566                 }
567
568                 capture_captured += rec_nframes;
569                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 now captured %2 (by %3)\n", name(), capture_captured, rec_nframes));
570
571         } else {
572
573                 /* not recording this time, but perhaps we were before .. */
574
575                 if (was_recording) {
576                         finish_capture (c);
577                         _accumulated_capture_offset = 0;
578                 }
579         }
580
581         /* AUDIO BUTLER REQUIRED CODE */
582
583         if (_playlists[DataType::AUDIO] && !c->empty()) {
584                 if (((samplecnt_t) c->front()->buf->read_space() >= _chunk_samples)) {
585                         _need_butler = true;
586                 }
587         }
588
589         /* MIDI BUTLER REQUIRED CODE */
590
591         if (_playlists[DataType::MIDI] && (_midi_buf->read_space() < _midi_buf->bufsize() / 2)) {
592                 _need_butler = true;
593         }
594
595         // DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 writer run, needs butler = %2\n", name(), _need_butler));
596 }
597
598 void
599 DiskWriter::finish_capture (boost::shared_ptr<ChannelList> c)
600 {
601         was_recording = false;
602         first_recordable_sample = max_samplepos;
603         last_recordable_sample = max_samplepos;
604
605         if (capture_captured == 0) {
606                 return;
607         }
608
609         if (recordable() && destructive()) {
610                 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
611
612                         RingBufferNPT<CaptureTransition>::rw_vector transvec;
613                         (*chan)->capture_transition_buf->get_write_vector(&transvec);
614
615                         if (transvec.len[0] > 0) {
616                                 transvec.buf[0]->type = CaptureEnd;
617                                 transvec.buf[0]->capture_val = capture_captured;
618                                 (*chan)->capture_transition_buf->increment_write_ptr(1);
619                         }
620                         else {
621                                 // bad!
622                                 fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record!  inconceivable!")) << endmsg;
623                         }
624                 }
625         }
626
627
628         CaptureInfo* ci = new CaptureInfo;
629
630         ci->start =  capture_start_sample;
631         ci->samples = capture_captured;
632
633         DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("Finish capture, add new CI, %1 + %2\n", ci->start, ci->samples));
634
635         /* XXX theoretical race condition here. Need atomic exchange ?
636            However, the circumstances when this is called right
637            now (either on record-disable or transport_stopped)
638            mean that no actual race exists. I think ...
639            We now have a capture_info_lock, but it is only to be used
640            to synchronize in the transport_stop and the capture info
641            accessors, so that invalidation will not occur (both non-realtime).
642         */
643
644         capture_info.push_back (ci);
645         capture_captured = 0;
646
647         /* now we've finished a capture, reset first_recordable_sample for next time */
648         first_recordable_sample = max_samplepos;
649 }
650
651 boost::shared_ptr<MidiBuffer>
652 DiskWriter::get_gui_feed_buffer () const
653 {
654         boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
655
656         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
657         b->copy (_gui_feed_buffer);
658         return b;
659 }
660
661 void
662 DiskWriter::set_record_enabled (bool yn)
663 {
664         if (!recordable() || !_session.record_enabling_legal() || record_safe ()) {
665                 return;
666         }
667
668         /* can't rec-enable in destructive mode if transport is before start */
669
670         if (destructive() && yn && _session.transport_sample() < _session.current_start_sample()) {
671                 return;
672         }
673
674         /* yes, i know that this not proof against race conditions, but its
675            good enough. i think.
676         */
677
678         if (record_enabled() != yn) {
679                 if (yn) {
680                         engage_record_enable ();
681                 } else {
682                         disengage_record_enable ();
683                 }
684
685                 RecordEnableChanged (); /* EMIT SIGNAL */
686         }
687 }
688
689 void
690 DiskWriter::set_record_safe (bool yn)
691 {
692         if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty()) {
693                 return;
694         }
695
696         /* can't rec-safe in destructive mode if transport is before start ????
697          REQUIRES REVIEW */
698
699         if (destructive() && yn && _session.transport_sample() < _session.current_start_sample()) {
700                 return;
701         }
702
703         /* yes, i know that this not proof against race conditions, but its
704          good enough. i think.
705          */
706
707         if (record_safe () != yn) {
708                 if (yn) {
709                         engage_record_safe ();
710                 } else {
711                         disengage_record_safe ();
712                 }
713
714                 RecordSafeChanged (); /* EMIT SIGNAL */
715         }
716 }
717
718 bool
719 DiskWriter::prep_record_enable ()
720 {
721         if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty() || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
722                 return false;
723         }
724
725         /* can't rec-enable in destructive mode if transport is before start */
726
727         if (destructive() && _session.transport_sample() < _session.current_start_sample()) {
728                 return false;
729         }
730
731         boost::shared_ptr<ChannelList> c = channels.reader();
732
733         capturing_sources.clear ();
734
735         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
736                 capturing_sources.push_back ((*chan)->write_source);
737                 Source::Lock lock((*chan)->write_source->mutex());
738                 (*chan)->write_source->mark_streaming_write_started (lock);
739         }
740
741         return true;
742 }
743
744 bool
745 DiskWriter::prep_record_disable ()
746 {
747         capturing_sources.clear ();
748         return true;
749 }
750
751 float
752 DiskWriter::buffer_load () const
753 {
754         boost::shared_ptr<ChannelList> c = channels.reader();
755
756         if (c->empty ()) {
757                 return 1.0;
758         }
759
760         return (float) ((double) c->front()->buf->write_space()/
761                         (double) c->front()->buf->bufsize());
762 }
763
764 void
765 DiskWriter::set_note_mode (NoteMode m)
766 {
767         _note_mode = m;
768
769         boost::shared_ptr<MidiPlaylist> mp = boost::dynamic_pointer_cast<MidiPlaylist> (_playlists[DataType::MIDI]);
770
771         if (mp) {
772                 mp->set_note_mode (m);
773         }
774
775         if (_midi_write_source && _midi_write_source->model())
776                 _midi_write_source->model()->set_note_mode(m);
777 }
778
779 int
780 DiskWriter::seek (samplepos_t sample, bool complete_refill)
781 {
782         uint32_t n;
783         ChannelList::iterator chan;
784         boost::shared_ptr<ChannelList> c = channels.reader();
785
786         for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
787                 (*chan)->buf->reset ();
788         }
789
790         _midi_buf->reset ();
791         g_atomic_int_set(&_samples_read_from_ringbuffer, 0);
792         g_atomic_int_set(&_samples_written_to_ringbuffer, 0);
793
794         /* can't rec-enable in destructive mode if transport is before start */
795
796         if (destructive() && record_enabled() && sample < _session.current_start_sample()) {
797                 disengage_record_enable ();
798         }
799
800         playback_sample = sample;
801
802         return 0;
803 }
804
805 int
806 DiskWriter::do_flush (RunContext ctxt, bool force_flush)
807 {
808         uint32_t to_write;
809         int32_t ret = 0;
810         RingBufferNPT<Sample>::rw_vector vector;
811         RingBufferNPT<CaptureTransition>::rw_vector transvec;
812         samplecnt_t total;
813
814         transvec.buf[0] = 0;
815         transvec.buf[1] = 0;
816         vector.buf[0] = 0;
817         vector.buf[1] = 0;
818
819         boost::shared_ptr<ChannelList> c = channels.reader();
820         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
821
822                 (*chan)->buf->get_read_vector (&vector);
823
824                 total = vector.len[0] + vector.len[1];
825
826                 if (total == 0 || (total < _chunk_samples && !force_flush && was_recording)) {
827                         goto out;
828                 }
829
830                 /* if there are 2+ chunks of disk i/o possible for
831                    this track, let the caller know so that it can arrange
832                    for us to be called again, ASAP.
833
834                    if we are forcing a flush, then if there is* any* extra
835                    work, let the caller know.
836
837                    if we are no longer recording and there is any extra work,
838                    let the caller know too.
839                 */
840
841                 if (total >= 2 * _chunk_samples || ((force_flush || !was_recording) && total > _chunk_samples)) {
842                         ret = 1;
843                 }
844
845                 to_write = min (_chunk_samples, (samplecnt_t) vector.len[0]);
846
847                 // check the transition buffer when recording destructive
848                 // important that we get this after the capture buf
849
850                 if (destructive()) {
851                         (*chan)->capture_transition_buf->get_read_vector(&transvec);
852                         size_t transcount = transvec.len[0] + transvec.len[1];
853                         size_t ti;
854
855                         for (ti=0; ti < transcount; ++ti) {
856                                 CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
857
858                                 if (captrans.type == CaptureStart) {
859                                         // by definition, the first data we got above represents the given capture pos
860
861                                         (*chan)->write_source->mark_capture_start (captrans.capture_val);
862                                         (*chan)->curr_capture_cnt = 0;
863
864                                 } else if (captrans.type == CaptureEnd) {
865
866                                         // capture end, the capture_val represents total samples in capture
867
868                                         if (captrans.capture_val <= (*chan)->curr_capture_cnt + to_write) {
869
870                                                 // shorten to make the write a perfect fit
871                                                 uint32_t nto_write = (captrans.capture_val - (*chan)->curr_capture_cnt);
872
873                                                 if (nto_write < to_write) {
874                                                         ret = 1; // should we?
875                                                 }
876                                                 to_write = nto_write;
877
878                                                 (*chan)->write_source->mark_capture_end ();
879
880                                                 // increment past this transition, but go no further
881                                                 ++ti;
882                                                 break;
883                                         }
884                                         else {
885                                                 // actually ends just beyond this chunk, so force more work
886                                                 ret = 1;
887                                                 break;
888                                         }
889                                 }
890                         }
891
892                         if (ti > 0) {
893                                 (*chan)->capture_transition_buf->increment_read_ptr(ti);
894                         }
895                 }
896
897                 if ((!(*chan)->write_source) || (*chan)->write_source->write (vector.buf[0], to_write) != to_write) {
898                         error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
899                         return -1;
900                 }
901
902                 (*chan)->buf->increment_read_ptr (to_write);
903                 (*chan)->curr_capture_cnt += to_write;
904
905                 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < _chunk_samples) && !destructive()) {
906
907                         /* we wrote all of vector.len[0] but it wasn't an entire
908                            disk_write_chunk_samples of data, so arrange for some part
909                            of vector.len[1] to be flushed to disk as well.
910                         */
911
912                         to_write = min ((samplecnt_t)(_chunk_samples - to_write), (samplecnt_t) vector.len[1]);
913
914                         DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 additional write of %2\n", name(), to_write));
915
916                         if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) {
917                                 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
918                                 return -1;
919                         }
920
921                         (*chan)->buf->increment_read_ptr (to_write);
922                         (*chan)->curr_capture_cnt += to_write;
923                 }
924         }
925
926         /* MIDI*/
927
928         if (_midi_write_source) {
929
930                 const samplecnt_t total = g_atomic_int_get(const_cast<gint*> (&_samples_pending_write));
931
932                 if (total == 0 ||
933                     _midi_buf->read_space() == 0 ||
934                     (!force_flush && (total < _chunk_samples) && was_recording)) {
935                         goto out;
936                 }
937
938                 /* if there are 2+ chunks of disk i/o possible for
939                    this track), let the caller know so that it can arrange
940                    for us to be called again, ASAP.
941
942                    if we are forcing a flush, then if there is* any* extra
943                    work, let the caller know.
944
945                    if we are no longer recording and there is any extra work,
946                    let the caller know too.
947                 */
948
949                 if (total >= 2 * _chunk_samples || ((force_flush || !was_recording) && total > _chunk_samples)) {
950                         ret = 1;
951                 }
952
953                 if (force_flush) {
954                         /* push out everything we have, right now */
955                         to_write = UINT32_MAX;
956                 } else {
957                         to_write = _chunk_samples;
958                 }
959
960                 if (record_enabled() && ((total > _chunk_samples) || force_flush)) {
961                         Source::Lock lm(_midi_write_source->mutex());
962                         if (_midi_write_source->midi_write (lm, *_midi_buf, get_capture_start_sample (0), to_write) != to_write) {
963                                 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
964                                 return -1;
965                         }
966                         g_atomic_int_add(const_cast<gint*> (&_samples_pending_write), -to_write);
967                 }
968         }
969
970   out:
971         return ret;
972
973 }
974
975 void
976 DiskWriter::reset_write_sources (bool mark_write_complete, bool /*force*/)
977 {
978         ChannelList::iterator chan;
979         boost::shared_ptr<ChannelList> c = channels.reader();
980         uint32_t n;
981
982         if (!_session.writable() || !recordable()) {
983                 return;
984         }
985
986         capturing_sources.clear ();
987
988         for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
989
990                 if (!destructive()) {
991
992                         if ((*chan)->write_source) {
993
994                                 if (mark_write_complete) {
995                                         Source::Lock lock((*chan)->write_source->mutex());
996                                         (*chan)->write_source->mark_streaming_write_completed (lock);
997                                         (*chan)->write_source->done_with_peakfile_writes ();
998                                 }
999
1000                                 if ((*chan)->write_source->removable()) {
1001                                         (*chan)->write_source->mark_for_remove ();
1002                                         (*chan)->write_source->drop_references ();
1003                                 }
1004
1005                                 (*chan)->write_source.reset ();
1006                         }
1007
1008                         use_new_write_source (DataType::AUDIO, n);
1009
1010                         if (record_enabled()) {
1011                                 capturing_sources.push_back ((*chan)->write_source);
1012                         }
1013
1014                 } else {
1015
1016                         if ((*chan)->write_source == 0) {
1017                                 use_new_write_source (DataType::AUDIO, n);
1018                         }
1019                 }
1020         }
1021
1022         if (_midi_write_source) {
1023                 if (mark_write_complete) {
1024                         Source::Lock lm(_midi_write_source->mutex());
1025                         _midi_write_source->mark_streaming_write_completed (lm);
1026                 }
1027         }
1028
1029         if (_playlists[DataType::MIDI]) {
1030                 use_new_write_source (DataType::MIDI);
1031         }
1032
1033         if (destructive() && !c->empty ()) {
1034
1035                 /* we now have all our write sources set up, so create the
1036                    playlist's single region.
1037                 */
1038
1039                 if (_playlists[DataType::MIDI]->empty()) {
1040                         setup_destructive_playlist ();
1041                 }
1042         }
1043 }
1044
1045 int
1046 DiskWriter::use_new_write_source (DataType dt, uint32_t n)
1047 {
1048         if (dt == DataType::MIDI) {
1049
1050                 _accumulated_capture_offset = 0;
1051                 _midi_write_source.reset();
1052
1053                 try {
1054                         _midi_write_source = boost::dynamic_pointer_cast<SMFSource>(
1055                                 _session.create_midi_source_for_session (write_source_name ()));
1056
1057                         if (!_midi_write_source) {
1058                                 throw failed_constructor();
1059                         }
1060                 }
1061
1062                 catch (failed_constructor &err) {
1063                         error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1064                         _midi_write_source.reset();
1065                         return -1;
1066                 }
1067         } else {
1068                 boost::shared_ptr<ChannelList> c = channels.reader();
1069
1070                 if (!recordable()) {
1071                         return 1;
1072                 }
1073
1074                 if (n >= c->size()) {
1075                         error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg;
1076                         return -1;
1077                 }
1078
1079                 ChannelInfo* chan = (*c)[n];
1080
1081                 try {
1082                         if ((chan->write_source = _session.create_audio_source_for_session (
1083                                      c->size(), write_source_name(), n, destructive())) == 0) {
1084                                 throw failed_constructor();
1085                         }
1086                 }
1087
1088                 catch (failed_constructor &err) {
1089                         error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1090                         chan->write_source.reset ();
1091                         return -1;
1092                 }
1093
1094                 /* do not remove destructive files even if they are empty */
1095
1096                 chan->write_source->set_allow_remove_if_empty (!destructive());
1097         }
1098
1099         return 0;
1100 }
1101
1102 void
1103 DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abort_capture)
1104 {
1105         bool more_work = true;
1106         int err = 0;
1107         samplecnt_t total_capture;
1108         SourceList audio_srcs;
1109         SourceList midi_srcs;
1110         ChannelList::iterator chan;
1111         vector<CaptureInfo*>::iterator ci;
1112         boost::shared_ptr<ChannelList> c = channels.reader();
1113         uint32_t n = 0;
1114         bool mark_write_completed = false;
1115
1116         finish_capture (c);
1117
1118
1119         /* butler is already stopped, but there may be work to do
1120            to flush remaining data to disk.
1121         */
1122
1123         while (more_work && !err) {
1124                 switch (do_flush (TransportContext, true)) {
1125                 case 0:
1126                         more_work = false;
1127                         break;
1128                 case 1:
1129                         break;
1130                 case -1:
1131                         error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1132                         err++;
1133                 }
1134         }
1135
1136         /* XXX is there anything we can do if err != 0 ? */
1137         Glib::Threads::Mutex::Lock lm (capture_info_lock);
1138
1139         if (capture_info.empty()) {
1140                 return;
1141         }
1142
1143         if (abort_capture) {
1144
1145                 if (destructive()) {
1146                         goto outout;
1147                 }
1148
1149                 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1150
1151                         if ((*chan)->write_source) {
1152
1153                                 (*chan)->write_source->mark_for_remove ();
1154                                 (*chan)->write_source->drop_references ();
1155                                 (*chan)->write_source.reset ();
1156                         }
1157
1158                         /* new source set up in "out" below */
1159                 }
1160
1161                 if (_midi_write_source) {
1162                         _midi_write_source->mark_for_remove ();
1163                         _midi_write_source->drop_references ();
1164                         _midi_write_source.reset();
1165                 }
1166
1167                 goto out;
1168         }
1169
1170         for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1171                 total_capture += (*ci)->samples;
1172         }
1173
1174         /* figure out the name for this take */
1175
1176         for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1177
1178                 boost::shared_ptr<AudioFileSource> as = (*chan)->write_source;
1179
1180                 if (as) {
1181                         audio_srcs.push_back (as);
1182                         as->update_header (capture_info.front()->start, when, twhen);
1183                         as->set_captured_for (_name.val());
1184                         as->mark_immutable ();
1185
1186                         if (Config->get_auto_analyse_audio()) {
1187                                 Analyser::queue_source_for_analysis (as, true);
1188                         }
1189
1190                         DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("newly captured source %1 length %2\n", as->path(), as->length (0)));
1191                 }
1192
1193                 if (_midi_write_source) {
1194                         midi_srcs.push_back (_midi_write_source);
1195                 }
1196         }
1197
1198
1199         /* MIDI */
1200
1201         if (_midi_write_source) {
1202
1203                 if (_midi_write_source->length (capture_info.front()->start) == 0) {
1204                         /* No data was recorded, so this capture will
1205                            effectively be aborted; do the same as we
1206                            do for an explicit abort.
1207                         */
1208                         if (_midi_write_source) {
1209                                 _midi_write_source->mark_for_remove ();
1210                                 _midi_write_source->drop_references ();
1211                                 _midi_write_source.reset();
1212                         }
1213
1214                         goto out;
1215                 }
1216
1217                 /* phew, we have data */
1218
1219                 Source::Lock source_lock(_midi_write_source->mutex());
1220
1221                 /* figure out the name for this take */
1222
1223                 midi_srcs.push_back (_midi_write_source);
1224
1225                 _midi_write_source->set_timeline_position (capture_info.front()->start);
1226                 _midi_write_source->set_captured_for (_name);
1227
1228                 /* set length in beats to entire capture length */
1229
1230                 BeatsSamplesConverter converter (_session.tempo_map(), capture_info.front()->start);
1231                 const Temporal::Beats total_capture_beats = converter.from (total_capture);
1232                 _midi_write_source->set_length_beats (total_capture_beats);
1233
1234                 /* flush to disk: this step differs from the audio path,
1235                    where all the data is already on disk.
1236                 */
1237
1238                 _midi_write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Temporal::Beats>::ResolveStuckNotes, total_capture_beats);
1239         }
1240
1241         _last_capture_sources.insert (_last_capture_sources.end(), audio_srcs.begin(), audio_srcs.end());
1242         _last_capture_sources.insert (_last_capture_sources.end(), midi_srcs.begin(), midi_srcs.end());
1243
1244
1245         if (_route) {
1246                 _route->use_captured_sources (audio_srcs, capture_info);
1247                 _route->use_captured_sources (midi_srcs, capture_info);
1248         }
1249
1250         mark_write_completed = true;
1251
1252   out:
1253         reset_write_sources (mark_write_completed);
1254
1255   outout:
1256
1257         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1258                 delete *ci;
1259         }
1260
1261         capture_info.clear ();
1262         capture_start_sample = 0;
1263 }
1264
1265 void
1266 DiskWriter::transport_looped (samplepos_t transport_sample)
1267 {
1268         if (was_recording) {
1269                 // all we need to do is finish this capture, with modified capture length
1270                 boost::shared_ptr<ChannelList> c = channels.reader();
1271
1272                 finish_capture (c);
1273
1274                 // the next region will start recording via the normal mechanism
1275                 // we'll set the start position to the current transport pos
1276                 // no latency adjustment or capture offset needs to be made, as that already happened the first time
1277                 capture_start_sample = transport_sample;
1278                 first_recordable_sample = transport_sample; // mild lie
1279                 last_recordable_sample = max_samplepos;
1280                 was_recording = true;
1281
1282                 if (recordable() && destructive()) {
1283                         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1284
1285                                 RingBufferNPT<CaptureTransition>::rw_vector transvec;
1286                                 (*chan)->capture_transition_buf->get_write_vector(&transvec);
1287
1288                                 if (transvec.len[0] > 0) {
1289                                         transvec.buf[0]->type = CaptureStart;
1290                                         transvec.buf[0]->capture_val = capture_start_sample;
1291                                         (*chan)->capture_transition_buf->increment_write_ptr(1);
1292                                 }
1293                                 else {
1294                                         // bad!
1295                                         fatal << X_("programming error: capture_transition_buf is full on rec loop!  inconceivable!")
1296                                               << endmsg;
1297                                 }
1298                         }
1299                 }
1300
1301         }
1302
1303         /* Here we only keep track of the number of captured loops so monotonic
1304            event times can be delivered to the write source in process().  Trying
1305            to be clever here is a world of trouble, it is better to simply record
1306            the input in a straightforward non-destructive way.  In the future when
1307            we want to implement more clever MIDI looping modes it should be done in
1308            the Source and/or entirely after the capture is finished.
1309         */
1310         if (was_recording) {
1311                 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1312         }
1313 }
1314
1315 void
1316 DiskWriter::setup_destructive_playlist ()
1317 {
1318         SourceList srcs;
1319         boost::shared_ptr<ChannelList> c = channels.reader();
1320
1321         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1322                 srcs.push_back ((*chan)->write_source);
1323         }
1324
1325         /* a single full-sized region */
1326
1327         assert (!srcs.empty ());
1328
1329         PropertyList plist;
1330         plist.add (Properties::name, _name.val());
1331         plist.add (Properties::start, 0);
1332         plist.add (Properties::length, max_samplepos - srcs.front()->natural_position());
1333
1334         boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist));
1335         _playlists[DataType::AUDIO]->add_region (region, srcs.front()->natural_position());
1336
1337         /* apply region properties and update write sources */
1338         use_destructive_playlist();
1339 }
1340
1341 void
1342 DiskWriter::use_destructive_playlist ()
1343 {
1344         /* this is called from the XML-based constructor or ::set_destructive. when called,
1345            we already have a playlist and a region, but we need to
1346            set up our sources for write. we use the sources associated
1347            with the (presumed single, full-extent) region.
1348         */
1349
1350         boost::shared_ptr<Region> rp;
1351         {
1352                 const RegionList& rl (_playlists[DataType::AUDIO]->region_list_property().rlist());
1353                 if (rl.size() > 0) {
1354                         /* this can happen when dragging a region onto a tape track */
1355                         assert((rl.size() == 1));
1356                         rp = rl.front();
1357                 }
1358         }
1359
1360         if (!rp) {
1361                 reset_write_sources (false, true);
1362                 return;
1363         }
1364
1365         boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (rp);
1366
1367         if (region == 0) {
1368                 throw failed_constructor();
1369         }
1370
1371         /* be sure to stretch the region out to the maximum length (non-musical)*/
1372
1373         region->set_length (max_samplepos - region->position(), 0);
1374
1375         uint32_t n;
1376         ChannelList::iterator chan;
1377         boost::shared_ptr<ChannelList> c = channels.reader();
1378
1379         for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1380                 (*chan)->write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
1381                 assert((*chan)->write_source);
1382                 (*chan)->write_source->set_allow_remove_if_empty (false);
1383
1384                 // should be set when creating the source or loading the state
1385                 assert ((*chan)->write_source->destructive());
1386         }
1387
1388         /* the source list will never be reset for a destructive track */
1389 }
1390
1391 void
1392 DiskWriter::adjust_buffering ()
1393 {
1394         boost::shared_ptr<ChannelList> c = channels.reader();
1395
1396         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1397                 (*chan)->resize (_session.butler()->audio_diskstream_capture_buffer_size());
1398         }
1399 }
1400
1401 void
1402 DiskWriter::realtime_handle_transport_stopped ()
1403 {
1404 }
1405
1406 bool
1407 DiskWriter::set_name (string const & str)
1408 {
1409         string my_name = X_("recorder:");
1410         my_name += str;
1411
1412         if (_name != my_name) {
1413                 SessionObject::set_name (my_name);
1414         }
1415
1416         return true;
1417 }
1418
1419 std::string
1420 DiskWriter::steal_write_source_name ()
1421 {
1422         if (_playlists[DataType::MIDI]) {
1423                 string our_old_name = _midi_write_source->name();
1424
1425                 /* this will bump the name of the current write source to the next one
1426                  * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1427                  * current write source name (e.g. "MIDI 1-1" available). See the
1428                  * comments in Session::create_midi_source_by_stealing_name() about why
1429                  * we do this.
1430                  */
1431
1432                 try {
1433                         string new_path = _session.new_midi_source_path (name());
1434
1435                         if (_midi_write_source->rename (new_path)) {
1436                                 return string();
1437                         }
1438                 } catch (...) {
1439                         return string ();
1440                 }
1441
1442                 return our_old_name;
1443         }
1444
1445         return std::string();
1446 }
1447
1448 bool
1449 DiskWriter::configure_io (ChanCount in, ChanCount out)
1450 {
1451         if (!DiskIOProcessor::configure_io (in, out)) {
1452                 return false;
1453         }
1454
1455         reset_write_sources (false, true);
1456
1457         return true;
1458 }