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