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