cue monitoring for audio (libardour aspects)
[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         if (_active) {
438                 if (!_pending_active) {
439                         _active = false;
440                         return;
441                 }
442         } else {
443                 if (_pending_active) {
444                         _active = true;
445                 } else {
446                         return;
447                 }
448         }
449
450         _need_butler = false;
451
452         check_record_status (start_frame, can_record);
453
454         if (nframes == 0) {
455                 return;
456         }
457
458         nominally_recording = (can_record && re);
459
460         // Safeguard against situations where process() goes haywire when autopunching
461         // and last_recordable_frame < first_recordable_frame
462
463         if (last_recordable_frame < first_recordable_frame) {
464                 last_recordable_frame = max_framepos;
465         }
466
467         const Location* const loop_loc    = loop_location;
468         framepos_t            loop_start  = 0;
469         framepos_t            loop_end    = 0;
470         framepos_t            loop_length = 0;
471
472         if (loop_loc) {
473                 get_location_times (loop_loc, &loop_start, &loop_end, &loop_length);
474         }
475
476         adjust_capture_position = 0;
477
478         if (nominally_recording || (re && was_recording && _session.get_record_enabled() && (_session.config.get_punch_in() || _session.preroll_record_punch_enabled()))) {
479
480                 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, start_frame, end_frame);
481                 // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
482                 // XXX also, first_recordable_frame & last_recordable_frame may both be == max_framepos: coverage() will return OverlapNone in that case. Is thak OK?
483                 calculate_record_range (ot, start_frame, nframes, rec_nframes, rec_offset);
484
485                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: this time record %2 of %3 frames, offset %4\n", _name, rec_nframes, nframes, rec_offset));
486
487                 if (rec_nframes && !was_recording) {
488                         capture_captured = 0;
489
490                         if (loop_loc) {
491                                 /* Loop recording, so pretend the capture started at the loop
492                                    start rgardless of what time it is now, so the source starts
493                                    at the loop start and can handle time wrapping around.
494                                    Otherwise, start the source right now as usual.
495                                 */
496                                 capture_captured    = start_frame - loop_start;
497                                 capture_start_frame = loop_start;
498                         }
499
500                         if (_midi_write_source) {
501                                 _midi_write_source->mark_write_starting_now (capture_start_frame, capture_captured, loop_length);
502                         }
503
504                         g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
505                         g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
506
507                         was_recording = true;
508
509                 }
510
511                 /* For audio: not writing frames to the capture ringbuffer offsets
512                  * the recording. For midi: we need to keep track of the record range
513                  * and subtract the accumulated difference from the event time.
514                  */
515                 if (rec_nframes) {
516                         _accumulated_capture_offset += rec_offset;
517                 } else {
518                         _accumulated_capture_offset += nframes;
519                 }
520
521         }
522
523         if (can_record && !_last_capture_sources.empty()) {
524                 _last_capture_sources.clear ();
525         }
526
527         if (rec_nframes) {
528
529                 /* AUDIO */
530
531                 const size_t n_buffers = bufs.count().n_audio();
532
533                 for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
534
535                         ChannelInfo* chaninfo (*chan);
536                         AudioBuffer& buf (bufs.get_audio (n%n_buffers));
537
538                         chaninfo->buf->get_write_vector (&chaninfo->rw_vector);
539
540                         if (rec_nframes <= (framecnt_t) chaninfo->rw_vector.len[0]) {
541
542                                 Sample *incoming = buf.data (rec_offset);
543                                 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * rec_nframes);
544
545                         } else {
546
547                                 framecnt_t total = chaninfo->rw_vector.len[0] + chaninfo->rw_vector.len[1];
548
549                                 if (rec_nframes > total) {
550                                         DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 overrun in %2, rec_nframes = %3 total space = %4\n",
551                                                                                     DEBUG_THREAD_SELF, name(), rec_nframes, total));
552                                         Overrun ();
553                                         return;
554                                 }
555
556                                 Sample *incoming = buf.data (rec_offset);
557                                 framecnt_t first = chaninfo->rw_vector.len[0];
558
559                                 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * first);
560                                 memcpy (chaninfo->rw_vector.buf[1], incoming + first, sizeof (Sample) * (rec_nframes - first));
561                         }
562
563                         chaninfo->buf->increment_write_ptr (rec_nframes);
564
565                 }
566
567                 /* MIDI */
568
569                 // Pump entire port buffer into the ring buffer (TODO: split cycles?)
570                 MidiBuffer& buf    = bufs.get_midi (0);
571                 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
572                 MidiChannelFilter* filter = mt ? &mt->capture_filter() : 0;
573
574                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
575                         Evoral::Event<MidiBuffer::TimeType> ev(*i, false);
576                         if (ev.time() + rec_offset > rec_nframes) {
577                                 break;
578                         }
579 #ifndef NDEBUG
580                         if (DEBUG_ENABLED(DEBUG::MidiIO)) {
581                                 const uint8_t* __data = ev.buffer();
582                                 DEBUG_STR_DECL(a);
583                                 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), start_frame, ev.size()));
584                                 for (size_t i=0; i < ev.size(); ++i) {
585                                         DEBUG_STR_APPEND(a,hex);
586                                         DEBUG_STR_APPEND(a,"0x");
587                                         DEBUG_STR_APPEND(a,(int)__data[i]);
588                                         DEBUG_STR_APPEND(a,' ');
589                                 }
590                                 DEBUG_STR_APPEND(a,'\n');
591                                 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
592                         }
593 #endif
594                         /* Write events to the capture buffer in frames from session start,
595                            but ignoring looping so event time progresses monotonically.
596                            The source knows the loop length so it knows exactly where the
597                            event occurs in the series of recorded loops and can implement
598                            any desirable behaviour.  We don't want to send event with
599                            transport time here since that way the source can not
600                            reconstruct their actual time; future clever MIDI looping should
601                            probably be implemented in the source instead of here.
602                         */
603                         const framecnt_t loop_offset = _num_captured_loops * loop_length;
604                         const framepos_t event_time = start_frame + loop_offset - _accumulated_capture_offset + ev.time();
605                         if (event_time < 0 || event_time < first_recordable_frame) {
606                                 /* Event out of range, skip */
607                                 continue;
608                         }
609
610                         if (!filter || !filter->filter(ev.buffer(), ev.size())) {
611                                 _midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
612                         }
613                 }
614                 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
615
616                 if (buf.size() != 0) {
617                         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
618
619                         if (lm.locked ()) {
620                                 /* Copy this data into our GUI feed buffer and tell the GUI
621                                    that it can read it if it likes.
622                                 */
623                                 _gui_feed_buffer.clear ();
624
625                                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
626                                         /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
627                                            the end of the world if it does.
628                                         */
629                                         _gui_feed_buffer.push_back ((*i).time() + start_frame, (*i).size(), (*i).buffer());
630                                 }
631                         }
632
633                         DataRecorded (_midi_write_source); /* EMIT SIGNAL */
634                 }
635
636                 capture_captured += rec_nframes;
637                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 now captured %2 (by %3)\n", name(), capture_captured, rec_nframes));
638
639         } else {
640
641                 /* not recording this time, but perhaps we were before .. */
642
643                 if (was_recording) {
644                         finish_capture (c);
645                         _accumulated_capture_offset = 0;
646                 }
647         }
648
649         /* AUDIO BUTLER REQUIRED CODE */
650
651         if (_playlists[DataType::AUDIO] && !c->empty()) {
652                 if (((framecnt_t) c->front()->buf->read_space() >= _chunk_frames)) {
653                         _need_butler = true;
654                 }
655         }
656
657         /* MIDI BUTLER REQUIRED CODE */
658
659         if (_playlists[DataType::MIDI] && (_midi_buf->read_space() < _midi_buf->bufsize() / 2)) {
660                 _need_butler = true;
661         }
662
663         DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 writer run, needs butler = %2\n", name(), _need_butler));
664 }
665
666 void
667 DiskWriter::finish_capture (boost::shared_ptr<ChannelList> c)
668 {
669         was_recording = false;
670         first_recordable_frame = max_framepos;
671         last_recordable_frame = max_framepos;
672
673         if (capture_captured == 0) {
674                 return;
675         }
676
677         if (recordable() && destructive()) {
678                 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
679
680                         RingBufferNPT<CaptureTransition>::rw_vector transvec;
681                         (*chan)->capture_transition_buf->get_write_vector(&transvec);
682
683                         if (transvec.len[0] > 0) {
684                                 transvec.buf[0]->type = CaptureEnd;
685                                 transvec.buf[0]->capture_val = capture_captured;
686                                 (*chan)->capture_transition_buf->increment_write_ptr(1);
687                         }
688                         else {
689                                 // bad!
690                                 fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record!  inconceivable!")) << endmsg;
691                         }
692                 }
693         }
694
695
696         CaptureInfo* ci = new CaptureInfo;
697
698         ci->start =  capture_start_frame;
699         ci->frames = capture_captured;
700
701         /* XXX theoretical race condition here. Need atomic exchange ?
702            However, the circumstances when this is called right
703            now (either on record-disable or transport_stopped)
704            mean that no actual race exists. I think ...
705            We now have a capture_info_lock, but it is only to be used
706            to synchronize in the transport_stop and the capture info
707            accessors, so that invalidation will not occur (both non-realtime).
708         */
709
710         DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("Finish capture, add new CI, %1 + %2\n", ci->start, ci->frames));
711
712         capture_info.push_back (ci);
713         capture_captured = 0;
714
715         /* now we've finished a capture, reset first_recordable_frame for next time */
716         first_recordable_frame = max_framepos;
717 }
718
719 void
720 DiskWriter::set_record_enabled (bool yn)
721 {
722         if (!recordable() || !_session.record_enabling_legal() || record_safe ()) {
723                 return;
724         }
725
726         /* can't rec-enable in destructive mode if transport is before start */
727
728         if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
729                 return;
730         }
731
732         /* yes, i know that this not proof against race conditions, but its
733            good enough. i think.
734         */
735
736         if (record_enabled() != yn) {
737                 if (yn) {
738                         engage_record_enable ();
739                 } else {
740                         disengage_record_enable ();
741                 }
742
743                 RecordEnableChanged (); /* EMIT SIGNAL */
744         }
745 }
746
747 void
748 DiskWriter::set_record_safe (bool yn)
749 {
750         if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty()) {
751                 return;
752         }
753
754         /* can't rec-safe in destructive mode if transport is before start ????
755          REQUIRES REVIEW */
756
757         if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
758                 return;
759         }
760
761         /* yes, i know that this not proof against race conditions, but its
762          good enough. i think.
763          */
764
765         if (record_safe () != yn) {
766                 if (yn) {
767                         engage_record_safe ();
768                 } else {
769                         disengage_record_safe ();
770                 }
771
772                 RecordSafeChanged (); /* EMIT SIGNAL */
773         }
774 }
775
776 bool
777 DiskWriter::prep_record_enable ()
778 {
779         if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty() || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
780                 return false;
781         }
782
783         /* can't rec-enable in destructive mode if transport is before start */
784
785         if (destructive() && _session.transport_frame() < _session.current_start_frame()) {
786                 return false;
787         }
788
789         boost::shared_ptr<ChannelList> c = channels.reader();
790
791         capturing_sources.clear ();
792
793         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
794                 capturing_sources.push_back ((*chan)->write_source);
795                 Source::Lock lock((*chan)->write_source->mutex());
796                 (*chan)->write_source->mark_streaming_write_started (lock);
797         }
798
799         return true;
800 }
801
802 bool
803 DiskWriter::prep_record_disable ()
804 {
805         capturing_sources.clear ();
806         return true;
807 }
808
809 float
810 DiskWriter::buffer_load () const
811 {
812         boost::shared_ptr<ChannelList> c = channels.reader();
813
814         if (c->empty ()) {
815                 return 1.0;
816         }
817
818         return (float) ((double) c->front()->buf->write_space()/
819                         (double) c->front()->buf->bufsize());
820 }
821
822 void
823 DiskWriter::set_note_mode (NoteMode m)
824 {
825         _note_mode = m;
826
827         boost::shared_ptr<MidiPlaylist> mp = boost::dynamic_pointer_cast<MidiPlaylist> (_playlists[DataType::MIDI]);
828
829         if (mp) {
830                 mp->set_note_mode (m);
831         }
832
833         if (_midi_write_source && _midi_write_source->model())
834                 _midi_write_source->model()->set_note_mode(m);
835 }
836
837 int
838 DiskWriter::seek (framepos_t frame, bool complete_refill)
839 {
840         uint32_t n;
841         ChannelList::iterator chan;
842         boost::shared_ptr<ChannelList> c = channels.reader();
843
844         for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
845                 (*chan)->buf->reset ();
846         }
847
848         _midi_buf->reset ();
849         g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
850         g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
851
852         /* can't rec-enable in destructive mode if transport is before start */
853
854         if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
855                 disengage_record_enable ();
856         }
857
858         playback_sample = frame;
859         file_frame = frame;
860
861         return 0;
862 }
863
864 int
865 DiskWriter::do_flush (RunContext ctxt, bool force_flush)
866 {
867         uint32_t to_write;
868         int32_t ret = 0;
869         RingBufferNPT<Sample>::rw_vector vector;
870         RingBufferNPT<CaptureTransition>::rw_vector transvec;
871         framecnt_t total;
872
873         transvec.buf[0] = 0;
874         transvec.buf[1] = 0;
875         vector.buf[0] = 0;
876         vector.buf[1] = 0;
877
878         boost::shared_ptr<ChannelList> c = channels.reader();
879         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
880
881                 (*chan)->buf->get_read_vector (&vector);
882
883                 total = vector.len[0] + vector.len[1];
884
885                 if (total == 0 || (total < _chunk_frames && !force_flush && was_recording)) {
886                         goto out;
887                 }
888
889                 /* if there are 2+ chunks of disk i/o possible for
890                    this track, let the caller know so that it can arrange
891                    for us to be called again, ASAP.
892
893                    if we are forcing a flush, then if there is* any* extra
894                    work, let the caller know.
895
896                    if we are no longer recording and there is any extra work,
897                    let the caller know too.
898                 */
899
900                 if (total >= 2 * _chunk_frames || ((force_flush || !was_recording) && total > _chunk_frames)) {
901                         ret = 1;
902                 }
903
904                 to_write = min (_chunk_frames, (framecnt_t) vector.len[0]);
905
906                 // check the transition buffer when recording destructive
907                 // important that we get this after the capture buf
908
909                 if (destructive()) {
910                         (*chan)->capture_transition_buf->get_read_vector(&transvec);
911                         size_t transcount = transvec.len[0] + transvec.len[1];
912                         size_t ti;
913
914                         for (ti=0; ti < transcount; ++ti) {
915                                 CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
916
917                                 if (captrans.type == CaptureStart) {
918                                         // by definition, the first data we got above represents the given capture pos
919
920                                         (*chan)->write_source->mark_capture_start (captrans.capture_val);
921                                         (*chan)->curr_capture_cnt = 0;
922
923                                 } else if (captrans.type == CaptureEnd) {
924
925                                         // capture end, the capture_val represents total frames in capture
926
927                                         if (captrans.capture_val <= (*chan)->curr_capture_cnt + to_write) {
928
929                                                 // shorten to make the write a perfect fit
930                                                 uint32_t nto_write = (captrans.capture_val - (*chan)->curr_capture_cnt);
931
932                                                 if (nto_write < to_write) {
933                                                         ret = 1; // should we?
934                                                 }
935                                                 to_write = nto_write;
936
937                                                 (*chan)->write_source->mark_capture_end ();
938
939                                                 // increment past this transition, but go no further
940                                                 ++ti;
941                                                 break;
942                                         }
943                                         else {
944                                                 // actually ends just beyond this chunk, so force more work
945                                                 ret = 1;
946                                                 break;
947                                         }
948                                 }
949                         }
950
951                         if (ti > 0) {
952                                 (*chan)->capture_transition_buf->increment_read_ptr(ti);
953                         }
954                 }
955
956                 if ((!(*chan)->write_source) || (*chan)->write_source->write (vector.buf[0], to_write) != to_write) {
957                         error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
958                         return -1;
959                 }
960
961                 (*chan)->buf->increment_read_ptr (to_write);
962                 (*chan)->curr_capture_cnt += to_write;
963
964                 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < _chunk_frames) && !destructive()) {
965
966                         /* we wrote all of vector.len[0] but it wasn't an entire
967                            disk_write_chunk_frames of data, so arrange for some part
968                            of vector.len[1] to be flushed to disk as well.
969                         */
970
971                         to_write = min ((framecnt_t)(_chunk_frames - to_write), (framecnt_t) vector.len[1]);
972
973                         DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 additional write of %2\n", name(), to_write));
974
975                         if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) {
976                                 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
977                                 return -1;
978                         }
979
980                         (*chan)->buf->increment_read_ptr (to_write);
981                         (*chan)->curr_capture_cnt += to_write;
982                 }
983         }
984
985         /* MIDI*/
986
987   out:
988         return ret;
989
990 }
991
992 void
993 DiskWriter::reset_write_sources (bool mark_write_complete, bool /*force*/)
994 {
995         ChannelList::iterator chan;
996         boost::shared_ptr<ChannelList> c = channels.reader();
997         uint32_t n;
998
999         if (!_session.writable() || !recordable()) {
1000                 return;
1001         }
1002
1003         capturing_sources.clear ();
1004
1005         for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
1006
1007                 if (!destructive()) {
1008
1009                         if ((*chan)->write_source) {
1010
1011                                 if (mark_write_complete) {
1012                                         Source::Lock lock((*chan)->write_source->mutex());
1013                                         (*chan)->write_source->mark_streaming_write_completed (lock);
1014                                         (*chan)->write_source->done_with_peakfile_writes ();
1015                                 }
1016
1017                                 if ((*chan)->write_source->removable()) {
1018                                         (*chan)->write_source->mark_for_remove ();
1019                                         (*chan)->write_source->drop_references ();
1020                                 }
1021
1022                                 (*chan)->write_source.reset ();
1023                         }
1024
1025                         use_new_write_source (DataType::AUDIO, n);
1026
1027                         if (record_enabled()) {
1028                                 capturing_sources.push_back ((*chan)->write_source);
1029                         }
1030
1031                 } else {
1032
1033                         if ((*chan)->write_source == 0) {
1034                                 use_new_write_source (DataType::AUDIO, n);
1035                         }
1036                 }
1037         }
1038
1039         if (_midi_write_source) {
1040                 if (mark_write_complete) {
1041                         Source::Lock lm(_midi_write_source->mutex());
1042                         _midi_write_source->mark_streaming_write_completed (lm);
1043                 }
1044
1045                 use_new_write_source (DataType::MIDI);
1046
1047                 if (destructive() && !c->empty ()) {
1048
1049                         /* we now have all our write sources set up, so create the
1050                            playlist's single region.
1051                         */
1052
1053                         if (_playlists[DataType::MIDI]->empty()) {
1054                                 setup_destructive_playlist ();
1055                         }
1056                 }
1057         }
1058 }
1059
1060 int
1061 DiskWriter::use_new_write_source (DataType dt, uint32_t n)
1062 {
1063         if (dt == DataType::MIDI) {
1064
1065                 _accumulated_capture_offset = 0;
1066                 _midi_write_source.reset();
1067
1068                 try {
1069                         _midi_write_source = boost::dynamic_pointer_cast<SMFSource>(
1070                                 _session.create_midi_source_for_session (write_source_name ()));
1071
1072                         if (!_midi_write_source) {
1073                                 throw failed_constructor();
1074                         }
1075                 }
1076
1077                 catch (failed_constructor &err) {
1078                         error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1079                         _midi_write_source.reset();
1080                         return -1;
1081                 }
1082         } else {
1083                 boost::shared_ptr<ChannelList> c = channels.reader();
1084
1085                 if (!recordable()) {
1086                         return 1;
1087                 }
1088
1089                 if (n >= c->size()) {
1090                         error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg;
1091                         return -1;
1092                 }
1093
1094                 ChannelInfo* chan = (*c)[n];
1095
1096                 try {
1097                         if ((chan->write_source = _session.create_audio_source_for_session (
1098                                      c->size(), write_source_name(), n, destructive())) == 0) {
1099                                 throw failed_constructor();
1100                         }
1101                 }
1102
1103                 catch (failed_constructor &err) {
1104                         error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1105                         chan->write_source.reset ();
1106                         return -1;
1107                 }
1108
1109                 /* do not remove destructive files even if they are empty */
1110
1111                 chan->write_source->set_allow_remove_if_empty (!destructive());
1112         }
1113
1114         return 0;
1115 }
1116
1117 void
1118 DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abort_capture)
1119 {
1120         uint32_t buffer_position;
1121         bool more_work = true;
1122         int err = 0;
1123         boost::shared_ptr<AudioRegion> region;
1124         framecnt_t total_capture;
1125         SourceList srcs;
1126         SourceList::iterator src;
1127         ChannelList::iterator chan;
1128         vector<CaptureInfo*>::iterator ci;
1129         boost::shared_ptr<ChannelList> c = channels.reader();
1130         uint32_t n = 0;
1131         bool mark_write_completed = false;
1132
1133         finish_capture (c);
1134
1135         boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist> (_playlists[DataType::AUDIO]);
1136
1137         /* butler is already stopped, but there may be work to do
1138            to flush remaining data to disk.
1139         */
1140
1141         while (more_work && !err) {
1142                 switch (do_flush (TransportContext, true)) {
1143                 case 0:
1144                         more_work = false;
1145                         break;
1146                 case 1:
1147                         break;
1148                 case -1:
1149                         error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1150                         err++;
1151                 }
1152         }
1153
1154         /* XXX is there anything we can do if err != 0 ? */
1155         Glib::Threads::Mutex::Lock lm (capture_info_lock);
1156
1157         if (capture_info.empty()) {
1158                 return;
1159         }
1160
1161         if (abort_capture) {
1162
1163                 if (destructive()) {
1164                         goto outout;
1165                 }
1166
1167                 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1168
1169                         if ((*chan)->write_source) {
1170
1171                                 (*chan)->write_source->mark_for_remove ();
1172                                 (*chan)->write_source->drop_references ();
1173                                 (*chan)->write_source.reset ();
1174                         }
1175
1176                         /* new source set up in "out" below */
1177                 }
1178
1179                 goto out;
1180         }
1181
1182         for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1183                 total_capture += (*ci)->frames;
1184         }
1185
1186         /* figure out the name for this take */
1187
1188         for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1189
1190                 boost::shared_ptr<AudioFileSource> s = (*chan)->write_source;
1191
1192                 if (s) {
1193                         srcs.push_back (s);
1194                         s->update_header (capture_info.front()->start, when, twhen);
1195                         s->set_captured_for (_name.val());
1196                         s->mark_immutable ();
1197
1198                         if (Config->get_auto_analyse_audio()) {
1199                                 Analyser::queue_source_for_analysis (s, true);
1200                         }
1201
1202                         DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("newly captured source %1 length %2\n", s->path(), s->length (0)));
1203                 }
1204         }
1205
1206         if (!pl) {
1207                 goto midi;
1208         }
1209
1210         /* destructive tracks have a single, never changing region */
1211
1212         if (destructive()) {
1213
1214                 /* send a signal that any UI can pick up to do the right thing. there is
1215                    a small problem here in that a UI may need the peak data to be ready
1216                    for the data that was recorded and this isn't interlocked with that
1217                    process. this problem is deferred to the UI.
1218                  */
1219
1220                 pl->LayeringChanged(); // XXX this may not get the UI to do the right thing
1221
1222         } else {
1223
1224                 string whole_file_region_name;
1225                 whole_file_region_name = region_name_from_path (c->front()->write_source->name(), true);
1226
1227                 /* Register a new region with the Session that
1228                    describes the entire source. Do this first
1229                    so that any sub-regions will obviously be
1230                    children of this one (later!)
1231                 */
1232
1233                 try {
1234                         PropertyList plist;
1235
1236                         plist.add (Properties::start, c->front()->write_source->last_capture_start_frame());
1237                         plist.add (Properties::length, total_capture);
1238                         plist.add (Properties::name, whole_file_region_name);
1239                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1240                         rx->set_automatic (true);
1241                         rx->set_whole_file (true);
1242
1243                         region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1244                         region->special_set_position (capture_info.front()->start);
1245                 }
1246
1247
1248                 catch (failed_constructor& err) {
1249                         error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1250                         /* XXX what now? */
1251                 }
1252
1253                 _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1254
1255                 pl->clear_changes ();
1256                 pl->set_capture_insertion_in_progress (true);
1257                 pl->freeze ();
1258
1259                 const framepos_t preroll_off = _session.preroll_record_trim_len ();
1260                 for (buffer_position = c->front()->write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1261
1262                         string region_name;
1263
1264                         RegionFactory::region_name (region_name, whole_file_region_name, false);
1265
1266                         DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture bufpos %5 start @ %2 length %3 add new region %4\n",
1267                                                                               _name, (*ci)->start, (*ci)->frames, region_name, buffer_position));
1268
1269                         try {
1270
1271                                 PropertyList plist;
1272
1273                                 plist.add (Properties::start, buffer_position);
1274                                 plist.add (Properties::length, (*ci)->frames);
1275                                 plist.add (Properties::name, region_name);
1276
1277                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1278                                 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1279                                 if (preroll_off > 0) {
1280                                         region->trim_front (buffer_position + preroll_off);
1281                                 }
1282                         }
1283
1284                         catch (failed_constructor& err) {
1285                                 error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1286                                 continue; /* XXX is this OK? */
1287                         }
1288
1289                         i_am_the_modifier++;
1290
1291                         pl->add_region (region, (*ci)->start + preroll_off, 1, non_layered());
1292                         pl->set_layer (region, DBL_MAX);
1293                         i_am_the_modifier--;
1294
1295                         buffer_position += (*ci)->frames;
1296                 }
1297
1298                 pl->thaw ();
1299                 pl->set_capture_insertion_in_progress (false);
1300                 _session.add_command (new StatefulDiffCommand (pl));
1301         }
1302
1303         mark_write_completed = true;
1304
1305   out:
1306         reset_write_sources (mark_write_completed);
1307
1308   outout:
1309
1310         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1311                 delete *ci;
1312         }
1313
1314         capture_info.clear ();
1315         capture_start_frame = 0;
1316
1317   midi:
1318         return;
1319 }
1320
1321 #if 0 // MIDI PART
1322 void
1323 DiskWriter::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
1324 {
1325         bool more_work = true;
1326         int err = 0;
1327         boost::shared_ptr<MidiRegion> region;
1328         MidiRegion::SourceList srcs;
1329         MidiRegion::SourceList::iterator src;
1330         vector<CaptureInfo*>::iterator ci;
1331
1332         finish_capture ();
1333
1334         /* butler is already stopped, but there may be work to do
1335            to flush remaining data to disk.
1336            */
1337
1338         while (more_work && !err) {
1339                 switch (do_flush (TransportContext, true)) {
1340                 case 0:
1341                         more_work = false;
1342                         break;
1343                 case 1:
1344                         break;
1345                 case -1:
1346                         error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1347                         err++;
1348                 }
1349         }
1350
1351         /* XXX is there anything we can do if err != 0 ? */
1352         Glib::Threads::Mutex::Lock lm (capture_info_lock);
1353
1354         if (capture_info.empty()) {
1355                 goto no_capture_stuff_to_do;
1356         }
1357
1358         if (abort_capture) {
1359
1360                 if (_write_source) {
1361                         _write_source->mark_for_remove ();
1362                         _write_source->drop_references ();
1363                         _write_source.reset();
1364                 }
1365
1366                 /* new source set up in "out" below */
1367
1368         } else {
1369
1370                 framecnt_t total_capture = 0;
1371                 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1372                         total_capture += (*ci)->frames;
1373                 }
1374
1375                 if (_write_source->length (capture_info.front()->start) != 0) {
1376
1377                         /* phew, we have data */
1378
1379                         Source::Lock source_lock(_write_source->mutex());
1380
1381                         /* figure out the name for this take */
1382
1383                         srcs.push_back (_write_source);
1384
1385                         _write_source->set_timeline_position (capture_info.front()->start);
1386                         _write_source->set_captured_for (_name);
1387
1388                         /* set length in beats to entire capture length */
1389
1390                         BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
1391                         const Evoral::Beats total_capture_beats = converter.from (total_capture);
1392                         _write_source->set_length_beats (total_capture_beats);
1393
1394                         /* flush to disk: this step differs from the audio path,
1395                            where all the data is already on disk.
1396                         */
1397
1398                         _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
1399
1400                         /* we will want to be able to keep (over)writing the source
1401                            but we don't want it to be removable. this also differs
1402                            from the audio situation, where the source at this point
1403                            must be considered immutable. luckily, we can rely on
1404                            MidiSource::mark_streaming_write_completed() to have
1405                            already done the necessary work for that.
1406                         */
1407
1408                         string whole_file_region_name;
1409                         whole_file_region_name = region_name_from_path (_write_source->name(), true);
1410
1411                         /* Register a new region with the Session that
1412                            describes the entire source. Do this first
1413                            so that any sub-regions will obviously be
1414                            children of this one (later!)
1415                         */
1416
1417                         try {
1418                                 PropertyList plist;
1419
1420                                 plist.add (Properties::name, whole_file_region_name);
1421                                 plist.add (Properties::whole_file, true);
1422                                 plist.add (Properties::automatic, true);
1423                                 plist.add (Properties::start, 0);
1424                                 plist.add (Properties::length, total_capture);
1425                                 plist.add (Properties::layer, 0);
1426
1427                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1428
1429                                 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1430                                 region->special_set_position (capture_info.front()->start);
1431                         }
1432
1433
1434                         catch (failed_constructor& err) {
1435                                 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1436                                 /* XXX what now? */
1437                         }
1438
1439                         _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1440
1441                         _playlist->clear_changes ();
1442                         _playlist->freeze ();
1443
1444                         /* Session frame time of the initial capture in this pass, which is where the source starts */
1445                         framepos_t initial_capture = 0;
1446                         if (!capture_info.empty()) {
1447                                 initial_capture = capture_info.front()->start;
1448                         }
1449
1450                         const framepos_t preroll_off = _session.preroll_record_trim_len ();
1451                         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1452
1453                                 string region_name;
1454
1455                                 RegionFactory::region_name (region_name, _write_source->name(), false);
1456
1457                                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1458                                                         _name, (*ci)->start, (*ci)->frames, region_name));
1459
1460
1461                                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1462
1463                                 try {
1464                                         PropertyList plist;
1465
1466                                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
1467                                         plist.add (Properties::start, (*ci)->start - initial_capture);
1468                                         plist.add (Properties::length, (*ci)->frames);
1469                                         plist.add (Properties::length_beats, converter.from((*ci)->frames).to_double());
1470                                         plist.add (Properties::name, region_name);
1471
1472                                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1473                                         region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1474                                         if (preroll_off > 0) {
1475                                                 region->trim_front ((*ci)->start - initial_capture + preroll_off);
1476                                         }
1477                                 }
1478
1479                                 catch (failed_constructor& err) {
1480                                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1481                                         continue; /* XXX is this OK? */
1482                                 }
1483
1484                                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1485
1486                                 i_am_the_modifier++;
1487                                 _playlist->add_region (region, (*ci)->start + preroll_off);
1488                                 i_am_the_modifier--;
1489                         }
1490
1491                         _playlist->thaw ();
1492                         _session.add_command (new StatefulDiffCommand(_playlist));
1493
1494                 } else {
1495
1496                         /* No data was recorded, so this capture will
1497                            effectively be aborted; do the same as we
1498                            do for an explicit abort.
1499                         */
1500
1501                         if (_write_source) {
1502                                 _write_source->mark_for_remove ();
1503                                 _write_source->drop_references ();
1504                                 _write_source.reset();
1505                         }
1506                 }
1507
1508         }
1509
1510         use_new_write_source (0);
1511
1512         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1513                 delete *ci;
1514         }
1515
1516         capture_info.clear ();
1517         capture_start_frame = 0;
1518
1519   no_capture_stuff_to_do:
1520
1521         reset_tracker ();
1522 }
1523 #endif
1524
1525 void
1526 DiskWriter::transport_looped (framepos_t transport_frame)
1527 {
1528         if (was_recording) {
1529                 // all we need to do is finish this capture, with modified capture length
1530                 boost::shared_ptr<ChannelList> c = channels.reader();
1531
1532                 finish_capture (c);
1533
1534                 // the next region will start recording via the normal mechanism
1535                 // we'll set the start position to the current transport pos
1536                 // no latency adjustment or capture offset needs to be made, as that already happened the first time
1537                 capture_start_frame = transport_frame;
1538                 first_recordable_frame = transport_frame; // mild lie
1539                 last_recordable_frame = max_framepos;
1540                 was_recording = true;
1541
1542                 if (recordable() && destructive()) {
1543                         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1544
1545                                 RingBufferNPT<CaptureTransition>::rw_vector transvec;
1546                                 (*chan)->capture_transition_buf->get_write_vector(&transvec);
1547
1548                                 if (transvec.len[0] > 0) {
1549                                         transvec.buf[0]->type = CaptureStart;
1550                                         transvec.buf[0]->capture_val = capture_start_frame;
1551                                         (*chan)->capture_transition_buf->increment_write_ptr(1);
1552                                 }
1553                                 else {
1554                                         // bad!
1555                                         fatal << X_("programming error: capture_transition_buf is full on rec loop!  inconceivable!")
1556                                               << endmsg;
1557                                 }
1558                         }
1559                 }
1560
1561         }
1562
1563         /* Here we only keep track of the number of captured loops so monotonic
1564            event times can be delivered to the write source in process().  Trying
1565            to be clever here is a world of trouble, it is better to simply record
1566            the input in a straightforward non-destructive way.  In the future when
1567            we want to implement more clever MIDI looping modes it should be done in
1568            the Source and/or entirely after the capture is finished.
1569         */
1570         if (was_recording) {
1571                 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1572         }
1573 }
1574
1575 void
1576 DiskWriter::setup_destructive_playlist ()
1577 {
1578         SourceList srcs;
1579         boost::shared_ptr<ChannelList> c = channels.reader();
1580
1581         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1582                 srcs.push_back ((*chan)->write_source);
1583         }
1584
1585         /* a single full-sized region */
1586
1587         assert (!srcs.empty ());
1588
1589         PropertyList plist;
1590         plist.add (Properties::name, _name.val());
1591         plist.add (Properties::start, 0);
1592         plist.add (Properties::length, max_framepos - srcs.front()->natural_position());
1593
1594         boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist));
1595         _playlists[DataType::AUDIO]->add_region (region, srcs.front()->natural_position());
1596
1597         /* apply region properties and update write sources */
1598         use_destructive_playlist();
1599 }
1600
1601 void
1602 DiskWriter::use_destructive_playlist ()
1603 {
1604         /* this is called from the XML-based constructor or ::set_destructive. when called,
1605            we already have a playlist and a region, but we need to
1606            set up our sources for write. we use the sources associated
1607            with the (presumed single, full-extent) region.
1608         */
1609
1610         boost::shared_ptr<Region> rp;
1611         {
1612                 const RegionList& rl (_playlists[DataType::AUDIO]->region_list_property().rlist());
1613                 if (rl.size() > 0) {
1614                         /* this can happen when dragging a region onto a tape track */
1615                         assert((rl.size() == 1));
1616                         rp = rl.front();
1617                 }
1618         }
1619
1620         if (!rp) {
1621                 reset_write_sources (false, true);
1622                 return;
1623         }
1624
1625         boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (rp);
1626
1627         if (region == 0) {
1628                 throw failed_constructor();
1629         }
1630
1631         /* be sure to stretch the region out to the maximum length (non-musical)*/
1632
1633         region->set_length (max_framepos - region->position(), 0);
1634
1635         uint32_t n;
1636         ChannelList::iterator chan;
1637         boost::shared_ptr<ChannelList> c = channels.reader();
1638
1639         for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1640                 (*chan)->write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
1641                 assert((*chan)->write_source);
1642                 (*chan)->write_source->set_allow_remove_if_empty (false);
1643
1644                 /* this might be false if we switched modes, so force it */
1645
1646 #ifdef XXX_OLD_DESTRUCTIVE_API_XXX
1647                 (*chan)->write_source->set_destructive (true);
1648 #else
1649                 // should be set when creating the source or loading the state
1650                 assert ((*chan)->write_source->destructive());
1651 #endif
1652         }
1653
1654         /* the source list will never be reset for a destructive track */
1655 }
1656
1657 void
1658 DiskWriter::adjust_buffering ()
1659 {
1660         boost::shared_ptr<ChannelList> c = channels.reader();
1661
1662         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1663                 (*chan)->resize (_session.butler()->audio_diskstream_capture_buffer_size());
1664         }
1665 }
1666
1667 void
1668 DiskWriter::realtime_handle_transport_stopped ()
1669 {
1670         realtime_speed_change ();
1671 }
1672
1673 bool
1674 DiskWriter::set_name (string const & str)
1675 {
1676         string my_name = X_("writer:");
1677         my_name += str;
1678
1679         if (_name != my_name) {
1680                 SessionObject::set_name (my_name);
1681         }
1682
1683         return true;
1684 }