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