2 Copyright (C) 2009-2016 Paul Davis
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.
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.
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.
20 #include "ardour/analyser.h"
21 #include "ardour/audioengine.h"
22 #include "ardour/audiofilesource.h"
23 #include "ardour/audio_buffer.h"
24 #include "ardour/audioplaylist.h"
25 #include "ardour/audioregion.h"
26 #include "ardour/butler.h"
27 #include "ardour/debug.h"
28 #include "ardour/disk_writer.h"
29 #include "ardour/midi_playlist.h"
30 #include "ardour/midi_source.h"
31 #include "ardour/midi_track.h"
32 #include "ardour/port.h"
33 #include "ardour/region_factory.h"
34 #include "ardour/session.h"
35 #include "ardour/smf_source.h"
39 using namespace ARDOUR;
43 ARDOUR::samplecnt_t DiskWriter::_chunk_samples = DiskWriter::default_chunk_samples ();
44 PBD::Signal0<void> DiskWriter::Overrun;
46 DiskWriter::DiskWriter (Session& s, string const & str, DiskIOProcessor::Flag f)
47 : DiskIOProcessor (s, str, f)
50 , capture_start_sample (0)
51 , capture_captured (0)
52 , was_recording (false)
53 , first_recordable_sample (max_samplepos)
54 , last_recordable_sample (max_samplepos)
55 , last_possibly_recording (0)
56 , _alignment_style (ExistingMaterial)
57 , _num_captured_loops (0)
58 , _accumulated_capture_offset (0)
59 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
61 DiskIOProcessor::init ();
64 DiskWriter::~DiskWriter ()
66 DEBUG_TRACE (DEBUG::Destruction, string_compose ("DiskWriter %1 @ %2 deleted\n", _name, this));
68 boost::shared_ptr<ChannelList> c = channels.reader();
70 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
71 (*chan)->write_source.reset ();
76 DiskWriter::default_chunk_samples ()
82 DiskWriter::WriterChannelInfo::resize (samplecnt_t bufsize)
84 if (!capture_transition_buf) {
85 capture_transition_buf = new RingBufferNPT<CaptureTransition> (256);
88 wbuf = new RingBufferNPT<Sample> (bufsize);
89 /* touch memory to lock it */
90 memset (wbuf->buffer(), 0, sizeof (Sample) * wbuf->bufsize());
94 DiskWriter::add_channel_to (boost::shared_ptr<ChannelList> c, uint32_t how_many)
97 c->push_back (new WriterChannelInfo (_session.butler()->audio_diskstream_capture_buffer_size()));
98 DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: new writer channel, write space = %2 read = %3\n",
100 c->back()->wbuf->write_space(),
101 c->back()->wbuf->read_space()));
110 DiskWriter::set_write_source_name (string const & str)
112 _write_source_name = str;
117 DiskWriter::check_record_status (samplepos_t transport_sample, double speed, bool can_record)
119 int possibly_recording;
120 const int transport_rolling = 0x4;
121 const int track_rec_enabled = 0x2;
122 const int global_rec_enabled = 0x1;
123 const int fully_rec_enabled = (transport_rolling |track_rec_enabled | global_rec_enabled);
125 /* merge together the 3 factors that affect record status, and compute what has changed. */
127 possibly_recording = (speed != 0.0f ? 4 : 0) | (record_enabled() ? 2 : 0) | (can_record ? 1 : 0);
129 if (possibly_recording == last_possibly_recording) {
133 if (possibly_recording == fully_rec_enabled) {
135 if (last_possibly_recording == fully_rec_enabled) {
140 if (_session.config.get_punch_in () && 0 != (loc = _session.locations()->auto_punch_location ())) {
141 capture_start_sample = loc->start ();
143 capture_start_sample = _session.transport_sample ();
146 first_recordable_sample = capture_start_sample;
148 if (_alignment_style == ExistingMaterial) {
149 first_recordable_sample += _capture_offset + _playback_offset;
152 if (_session.config.get_punch_out () && 0 != (loc = _session.locations()->auto_punch_location ())) {
153 /* this freezes the punch-out point when starting to record.
155 * We should allow to move it or at least allow to disable punch-out
158 last_recordable_sample = loc->end ();
159 if (_alignment_style == ExistingMaterial) {
160 last_recordable_sample += _capture_offset + _playback_offset;
163 last_recordable_sample = max_samplepos;
166 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: @ %2 (STS: %3) CS:%4 FRS: %5 IL: %7, OL: %8 CO: %r9 PO: %10 WOL: %11 WIL: %12\n",
169 _session.transport_sample(),
170 capture_start_sample,
171 first_recordable_sample,
172 last_recordable_sample,
177 _session.worst_output_latency(),
178 _session.worst_input_latency()));
181 prepare_record_status (capture_start_sample);
185 last_possibly_recording = possibly_recording;
189 DiskWriter::calculate_record_range (Evoral::OverlapType ot, samplepos_t transport_sample, samplecnt_t nframes, samplecnt_t & rec_nframes, samplecnt_t & rec_offset)
192 case Evoral::OverlapNone:
196 case Evoral::OverlapInternal:
197 /* ---------- recrange
200 rec_nframes = nframes;
204 case Evoral::OverlapStart:
205 /* |--------| recrange
208 rec_nframes = transport_sample + nframes - first_recordable_sample;
210 rec_offset = first_recordable_sample - transport_sample;
214 case Evoral::OverlapEnd:
215 /* |--------| recrange
216 * |-------- transrange
218 rec_nframes = last_recordable_sample - transport_sample;
222 case Evoral::OverlapExternal:
223 /* |--------| recrange
224 * -------------- transrange
226 rec_nframes = last_recordable_sample - first_recordable_sample;
227 rec_offset = first_recordable_sample - transport_sample;
231 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 rec? %2 @ %3 (for %4) FRF %5 LRF %6 : rf %7 @ %8\n",
232 _name, enum_2_string (ot), transport_sample, nframes,
233 first_recordable_sample, last_recordable_sample, rec_nframes, rec_offset));
237 DiskWriter::engage_record_enable ()
239 g_atomic_int_set (&_record_enabled, 1);
243 DiskWriter::disengage_record_enable ()
245 g_atomic_int_set (&_record_enabled, 0);
249 DiskWriter::engage_record_safe ()
251 g_atomic_int_set (&_record_safe, 1);
255 DiskWriter::disengage_record_safe ()
257 g_atomic_int_set (&_record_safe, 0);
260 /** Get the start position (in session samples) of the nth capture in the current pass */
262 DiskWriter::get_capture_start_sample (uint32_t n) const
264 Glib::Threads::Mutex::Lock lm (capture_info_lock);
266 if (capture_info.size() > n) {
267 /* this is a completed capture */
268 return capture_info[n]->start;
270 /* this is the currently in-progress capture */
271 return capture_start_sample;
276 DiskWriter::get_captured_samples (uint32_t n) const
278 Glib::Threads::Mutex::Lock lm (capture_info_lock);
280 if (capture_info.size() > n) {
281 /* this is a completed capture */
282 return capture_info[n]->samples;
284 /* this is the currently in-progress capture */
285 return capture_captured;
290 DiskWriter::set_align_style (AlignStyle a, bool force)
292 if (record_enabled() && _session.actively_recording()) {
296 if ((a != _alignment_style) || force) {
297 _alignment_style = a;
298 AlignmentStyleChanged ();
305 XMLNode& node (DiskIOProcessor::state ());
306 node.set_property (X_("type"), X_("diskwriter"));
307 node.set_property (X_("record-safe"), (_record_safe ? X_("yes" : "no")));
312 DiskWriter::set_state (const XMLNode& node, int version)
314 if (DiskIOProcessor::set_state (node, version)) {
318 if (!node.get_property (X_("record-safe"), _record_safe)) {
319 _record_safe = false;
322 reset_write_sources (false, true);
328 DiskWriter::non_realtime_locate (samplepos_t position)
330 if (_midi_write_source) {
331 _midi_write_source->set_timeline_position (position);
334 DiskIOProcessor::non_realtime_locate (position);
339 DiskWriter::prepare_record_status (samplepos_t capture_start_sample)
341 if (recordable() && destructive()) {
342 boost::shared_ptr<ChannelList> c = channels.reader ();
343 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
345 RingBufferNPT<CaptureTransition>::rw_vector transitions;
346 (*chan)->capture_transition_buf->get_write_vector (&transitions);
348 if (transitions.len[0] > 0) {
349 transitions.buf[0]->type = CaptureStart;
350 transitions.buf[0]->capture_val = capture_start_sample;
351 (*chan)->capture_transition_buf->increment_write_ptr(1);
354 fatal << X_("programming error: capture_transition_buf is full on rec start! inconceivable!")
362 /** Do some record stuff [not described in this comment!]
365 * - Setup playback_distance with the nframes, or nframes adjusted
366 * for current varispeed, if appropriate.
367 * - Setup current_playback_buffer in each ChannelInfo to point to data
368 * that someone can read playback_distance worth of data from.
371 DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample,
372 double speed, pframes_t nframes, bool result_required)
374 if (!_active && !_pending_active) {
377 _active = _pending_active;
380 boost::shared_ptr<ChannelList> c = channels.reader();
381 ChannelList::iterator chan;
383 samplecnt_t rec_offset = 0;
384 samplecnt_t rec_nframes = 0;
385 bool nominally_recording;
387 bool re = record_enabled ();
388 bool punch_in = _session.config.get_punch_in () && _session.locations()->auto_punch_location ();
389 bool can_record = _session.actively_recording ();
390 can_record |= speed != 0 && _session.get_record_enabled () && punch_in && _session.transport_sample () <= _session.locations()->auto_punch_location ()->start ();
392 _need_butler = false;
395 if (speed != 0 && re) {
396 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: run() start: %2 end: %3 NF: %4\n", _name, start_sample, end_sample, nframes));
400 check_record_status (start_sample, speed, can_record);
406 nominally_recording = (can_record && re);
408 // Safeguard against situations where process() goes haywire when autopunching
409 // and last_recordable_sample < first_recordable_sample
411 if (last_recordable_sample < first_recordable_sample) {
412 last_recordable_sample = max_samplepos;
415 const Location* const loop_loc = _loop_location;
416 samplepos_t loop_start = 0;
417 samplepos_t loop_end = 0;
418 samplepos_t loop_length = 0;
421 get_location_times (loop_loc, &loop_start, &loop_end, &loop_length);
424 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && punch_in)) {
426 Evoral::OverlapType ot = Evoral::coverage (first_recordable_sample, last_recordable_sample, start_sample, end_sample);
427 // XXX should this be transport_sample + nframes - 1 ? coverage() expects its parameter ranges to include their end points
428 // XXX also, first_recordable_sample & last_recordable_sample may both be == max_samplepos: coverage() will return OverlapNone in that case. Is thak OK?
429 calculate_record_range (ot, start_sample, nframes, rec_nframes, rec_offset);
431 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: this time record %2 of %3 samples, offset %4\n", _name, rec_nframes, nframes, rec_offset));
433 if (rec_nframes && !was_recording) {
434 capture_captured = 0;
437 /* Loop recording, so pretend the capture started at the loop
438 start rgardless of what time it is now, so the source starts
439 at the loop start and can handle time wrapping around.
440 Otherwise, start the source right now as usual.
442 capture_captured = start_sample - loop_start;
443 capture_start_sample = loop_start;
446 if (_midi_write_source) {
447 _midi_write_source->mark_write_starting_now (capture_start_sample, capture_captured, loop_length);
450 g_atomic_int_set (const_cast<gint*> (&_samples_pending_write), 0);
451 g_atomic_int_set (const_cast<gint*> (&_num_captured_loops), 0);
453 was_recording = true;
457 /* For audio: not writing samples to the capture ringbuffer offsets
458 * the recording. For midi: we need to keep track of the record range
459 * and subtract the accumulated difference from the event time.
462 _accumulated_capture_offset += rec_offset;
464 _accumulated_capture_offset += nframes;
469 if (can_record && !_last_capture_sources.empty ()) {
470 _last_capture_sources.clear ();
477 const size_t n_buffers = bufs.count().n_audio();
479 for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
481 ChannelInfo* chaninfo (*chan);
482 AudioBuffer& buf (bufs.get_audio (n%n_buffers));
484 chaninfo->wbuf->get_write_vector (&chaninfo->rw_vector);
486 if (rec_nframes <= (samplecnt_t) chaninfo->rw_vector.len[0]) {
488 Sample *incoming = buf.data (rec_offset);
489 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * rec_nframes);
493 samplecnt_t total = chaninfo->rw_vector.len[0] + chaninfo->rw_vector.len[1];
495 if (rec_nframes > total) {
496 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 overrun in %2, rec_nframes = %3 total space = %4\n",
497 DEBUG_THREAD_SELF, name(), rec_nframes, total));
502 Sample *incoming = buf.data (rec_offset);
503 samplecnt_t first = chaninfo->rw_vector.len[0];
505 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * first);
506 memcpy (chaninfo->rw_vector.buf[1], incoming + first, sizeof (Sample) * (rec_nframes - first));
509 chaninfo->wbuf->increment_write_ptr (rec_nframes);
515 // Pump entire port buffer into the ring buffer (TODO: split cycles?)
516 MidiBuffer& buf = bufs.get_midi (0);
517 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
518 MidiChannelFilter* filter = mt ? &mt->capture_filter() : 0;
520 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
521 Evoral::Event<MidiBuffer::TimeType> ev (*i, false);
522 if (ev.time() + rec_offset > rec_nframes) {
526 if (DEBUG_ENABLED(DEBUG::MidiIO)) {
527 const uint8_t* __data = ev.buffer();
529 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), start_sample, ev.size()));
530 for (size_t i=0; i < ev.size(); ++i) {
531 DEBUG_STR_APPEND(a,hex);
532 DEBUG_STR_APPEND(a,"0x");
533 DEBUG_STR_APPEND(a,(int)__data[i]);
534 DEBUG_STR_APPEND(a,' ');
536 DEBUG_STR_APPEND(a,'\n');
537 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
540 /* Write events to the capture buffer in samples from session start,
541 but ignoring looping so event time progresses monotonically.
542 The source knows the loop length so it knows exactly where the
543 event occurs in the series of recorded loops and can implement
544 any desirable behaviour. We don't want to send event with
545 transport time here since that way the source can not
546 reconstruct their actual time; future clever MIDI looping should
547 probably be implemented in the source instead of here.
549 const samplecnt_t loop_offset = _num_captured_loops * loop_length;
550 const samplepos_t event_time = start_sample + loop_offset - _accumulated_capture_offset + ev.time();
551 if (event_time < 0 || event_time < first_recordable_sample) {
552 /* Event out of range, skip */
556 bool skip_event = false;
558 /* skip injected immediate/out-of-band events */
559 MidiBuffer const& ieb (mt->immediate_event_buffer());
560 for (MidiBuffer::const_iterator j = ieb.begin(); j != ieb.end(); ++j) {
570 if (!filter || !filter->filter(ev.buffer(), ev.size())) {
571 _midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
574 g_atomic_int_add (const_cast<gint*>(&_samples_pending_write), nframes);
576 if (buf.size() != 0) {
577 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
580 /* Copy this data into our GUI feed buffer and tell the GUI
581 that it can read it if it likes.
583 _gui_feed_buffer.clear ();
585 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
586 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
587 the end of the world if it does.
589 _gui_feed_buffer.push_back ((*i).time() + start_sample, (*i).size(), (*i).buffer());
593 DataRecorded (_midi_write_source); /* EMIT SIGNAL */
596 capture_captured += rec_nframes;
597 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 now captured %2 (by %3)\n", name(), capture_captured, rec_nframes));
601 /* not recording this time, but perhaps we were before .. */
605 _accumulated_capture_offset = 0;
609 /* AUDIO BUTLER REQUIRED CODE */
611 if (_playlists[DataType::AUDIO] && !c->empty()) {
612 if (((samplecnt_t) c->front()->wbuf->read_space() >= _chunk_samples)) {
617 /* MIDI BUTLER REQUIRED CODE */
619 if (_playlists[DataType::MIDI] && (_midi_buf->read_space() < _midi_buf->bufsize() / 2)) {
623 // DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 writer run, needs butler = %2\n", name(), _need_butler));
627 DiskWriter::finish_capture (boost::shared_ptr<ChannelList> c)
629 was_recording = false;
630 first_recordable_sample = max_samplepos;
631 last_recordable_sample = max_samplepos;
633 if (capture_captured == 0) {
637 if (recordable() && destructive()) {
638 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
640 RingBufferNPT<CaptureTransition>::rw_vector transvec;
641 (*chan)->capture_transition_buf->get_write_vector(&transvec);
643 if (transvec.len[0] > 0) {
644 transvec.buf[0]->type = CaptureEnd;
645 transvec.buf[0]->capture_val = capture_captured;
646 (*chan)->capture_transition_buf->increment_write_ptr(1);
650 fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record! inconceivable!")) << endmsg;
656 CaptureInfo* ci = new CaptureInfo;
658 ci->start = capture_start_sample;
659 ci->samples = capture_captured;
661 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("Finish capture, add new CI, %1 + %2\n", ci->start, ci->samples));
663 /* XXX theoretical race condition here. Need atomic exchange ?
664 However, the circumstances when this is called right
665 now (either on record-disable or transport_stopped)
666 mean that no actual race exists. I think ...
667 We now have a capture_info_lock, but it is only to be used
668 to synchronize in the transport_stop and the capture info
669 accessors, so that invalidation will not occur (both non-realtime).
672 capture_info.push_back (ci);
673 capture_captured = 0;
675 /* now we've finished a capture, reset first_recordable_sample for next time */
676 first_recordable_sample = max_samplepos;
679 boost::shared_ptr<MidiBuffer>
680 DiskWriter::get_gui_feed_buffer () const
682 boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
684 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
685 b->copy (_gui_feed_buffer);
690 DiskWriter::set_record_enabled (bool yn)
692 if (!recordable() || !_session.record_enabling_legal() || record_safe ()) {
696 /* can't rec-enable in destructive mode if transport is before start */
698 if (destructive() && yn && _session.transport_sample() < _session.current_start_sample()) {
702 /* yes, i know that this not proof against race conditions, but its
703 good enough. i think.
706 if (record_enabled() != yn) {
708 engage_record_enable ();
710 disengage_record_enable ();
713 RecordEnableChanged (); /* EMIT SIGNAL */
718 DiskWriter::set_record_safe (bool yn)
720 if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty()) {
724 /* can't rec-safe in destructive mode if transport is before start ????
727 if (destructive() && yn && _session.transport_sample() < _session.current_start_sample()) {
731 /* yes, i know that this not proof against race conditions, but its
732 good enough. i think.
735 if (record_safe () != yn) {
737 engage_record_safe ();
739 disengage_record_safe ();
742 RecordSafeChanged (); /* EMIT SIGNAL */
747 DiskWriter::prep_record_enable ()
749 if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty() || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
753 /* can't rec-enable in destructive mode if transport is before start */
755 if (destructive() && _session.transport_sample() < _session.current_start_sample()) {
759 boost::shared_ptr<ChannelList> c = channels.reader();
761 capturing_sources.clear ();
763 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
764 capturing_sources.push_back ((*chan)->write_source);
765 Source::Lock lock((*chan)->write_source->mutex());
766 (*chan)->write_source->mark_streaming_write_started (lock);
773 DiskWriter::prep_record_disable ()
775 capturing_sources.clear ();
780 DiskWriter::buffer_load () const
782 boost::shared_ptr<ChannelList> c = channels.reader();
788 return (float) ((double) c->front()->wbuf->write_space()/
789 (double) c->front()->wbuf->bufsize());
793 DiskWriter::set_note_mode (NoteMode m)
797 boost::shared_ptr<MidiPlaylist> mp = boost::dynamic_pointer_cast<MidiPlaylist> (_playlists[DataType::MIDI]);
800 mp->set_note_mode (m);
803 if (_midi_write_source && _midi_write_source->model())
804 _midi_write_source->model()->set_note_mode(m);
808 DiskWriter::seek (samplepos_t sample, bool complete_refill)
811 ChannelList::iterator chan;
812 boost::shared_ptr<ChannelList> c = channels.reader();
814 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
815 (*chan)->wbuf->reset ();
819 g_atomic_int_set(&_samples_read_from_ringbuffer, 0);
820 g_atomic_int_set(&_samples_written_to_ringbuffer, 0);
822 /* can't rec-enable in destructive mode if transport is before start */
824 if (destructive() && record_enabled() && sample < _session.current_start_sample()) {
825 disengage_record_enable ();
828 playback_sample = sample;
834 DiskWriter::do_flush (RunContext ctxt, bool force_flush)
838 RingBufferNPT<Sample>::rw_vector vector;
839 RingBufferNPT<CaptureTransition>::rw_vector transvec;
847 boost::shared_ptr<ChannelList> c = channels.reader();
848 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
850 (*chan)->wbuf->get_read_vector (&vector);
852 total = vector.len[0] + vector.len[1];
854 if (total == 0 || (total < _chunk_samples && !force_flush && was_recording)) {
858 /* if there are 2+ chunks of disk i/o possible for
859 this track, let the caller know so that it can arrange
860 for us to be called again, ASAP.
862 if we are forcing a flush, then if there is* any* extra
863 work, let the caller know.
865 if we are no longer recording and there is any extra work,
866 let the caller know too.
869 if (total >= 2 * _chunk_samples || ((force_flush || !was_recording) && total > _chunk_samples)) {
873 to_write = min (_chunk_samples, (samplecnt_t) vector.len[0]);
875 // check the transition buffer when recording destructive
876 // important that we get this after the capture buf
879 (*chan)->capture_transition_buf->get_read_vector(&transvec);
880 size_t transcount = transvec.len[0] + transvec.len[1];
883 for (ti=0; ti < transcount; ++ti) {
884 CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
886 if (captrans.type == CaptureStart) {
887 // by definition, the first data we got above represents the given capture pos
889 (*chan)->write_source->mark_capture_start (captrans.capture_val);
890 (*chan)->curr_capture_cnt = 0;
892 } else if (captrans.type == CaptureEnd) {
894 // capture end, the capture_val represents total samples in capture
896 if (captrans.capture_val <= (*chan)->curr_capture_cnt + to_write) {
898 // shorten to make the write a perfect fit
899 uint32_t nto_write = (captrans.capture_val - (*chan)->curr_capture_cnt);
901 if (nto_write < to_write) {
902 ret = 1; // should we?
904 to_write = nto_write;
906 (*chan)->write_source->mark_capture_end ();
908 // increment past this transition, but go no further
913 // actually ends just beyond this chunk, so force more work
921 (*chan)->capture_transition_buf->increment_read_ptr(ti);
925 if ((!(*chan)->write_source) || (*chan)->write_source->write (vector.buf[0], to_write) != to_write) {
926 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
930 (*chan)->wbuf->increment_read_ptr (to_write);
931 (*chan)->curr_capture_cnt += to_write;
933 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < _chunk_samples) && !destructive()) {
935 /* we wrote all of vector.len[0] but it wasn't an entire
936 disk_write_chunk_samples of data, so arrange for some part
937 of vector.len[1] to be flushed to disk as well.
940 to_write = min ((samplecnt_t)(_chunk_samples - to_write), (samplecnt_t) vector.len[1]);
942 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 additional write of %2\n", name(), to_write));
944 if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) {
945 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
949 (*chan)->wbuf->increment_read_ptr (to_write);
950 (*chan)->curr_capture_cnt += to_write;
956 if (_midi_write_source) {
958 const samplecnt_t total = g_atomic_int_get(const_cast<gint*> (&_samples_pending_write));
961 _midi_buf->read_space() == 0 ||
962 (!force_flush && (total < _chunk_samples) && was_recording)) {
966 /* if there are 2+ chunks of disk i/o possible for
967 this track), let the caller know so that it can arrange
968 for us to be called again, ASAP.
970 if we are forcing a flush, then if there is* any* extra
971 work, let the caller know.
973 if we are no longer recording and there is any extra work,
974 let the caller know too.
977 if (total >= 2 * _chunk_samples || ((force_flush || !was_recording) && total > _chunk_samples)) {
982 /* push out everything we have, right now */
983 to_write = UINT32_MAX;
985 to_write = _chunk_samples;
988 if (record_enabled() && ((total > _chunk_samples) || force_flush)) {
989 Source::Lock lm(_midi_write_source->mutex());
990 if (_midi_write_source->midi_write (lm, *_midi_buf, get_capture_start_sample (0), to_write) != to_write) {
991 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
994 g_atomic_int_add(const_cast<gint*> (&_samples_pending_write), -to_write);
1004 DiskWriter::reset_write_sources (bool mark_write_complete, bool /*force*/)
1006 ChannelList::iterator chan;
1007 boost::shared_ptr<ChannelList> c = channels.reader();
1010 if (!_session.writable() || !recordable()) {
1014 capturing_sources.clear ();
1016 for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
1018 if (!destructive()) {
1020 if ((*chan)->write_source) {
1022 if (mark_write_complete) {
1023 Source::Lock lock((*chan)->write_source->mutex());
1024 (*chan)->write_source->mark_streaming_write_completed (lock);
1025 (*chan)->write_source->done_with_peakfile_writes ();
1028 if ((*chan)->write_source->removable()) {
1029 (*chan)->write_source->mark_for_remove ();
1030 (*chan)->write_source->drop_references ();
1033 (*chan)->write_source.reset ();
1036 use_new_write_source (DataType::AUDIO, n);
1038 if (record_enabled()) {
1039 capturing_sources.push_back ((*chan)->write_source);
1044 if ((*chan)->write_source == 0) {
1045 use_new_write_source (DataType::AUDIO, n);
1050 if (_midi_write_source) {
1051 if (mark_write_complete) {
1052 Source::Lock lm(_midi_write_source->mutex());
1053 _midi_write_source->mark_streaming_write_completed (lm);
1057 if (_playlists[DataType::MIDI]) {
1058 use_new_write_source (DataType::MIDI);
1061 if (destructive() && !c->empty ()) {
1063 /* we now have all our write sources set up, so create the
1064 playlist's single region.
1067 if (_playlists[DataType::MIDI]->empty()) {
1068 setup_destructive_playlist ();
1074 DiskWriter::use_new_write_source (DataType dt, uint32_t n)
1076 if (dt == DataType::MIDI) {
1078 _accumulated_capture_offset = 0;
1079 _midi_write_source.reset();
1082 _midi_write_source = boost::dynamic_pointer_cast<SMFSource>(
1083 _session.create_midi_source_for_session (write_source_name ()));
1085 if (!_midi_write_source) {
1086 throw failed_constructor();
1090 catch (failed_constructor &err) {
1091 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1092 _midi_write_source.reset();
1096 boost::shared_ptr<ChannelList> c = channels.reader();
1098 if (!recordable()) {
1102 if (n >= c->size()) {
1103 error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg;
1107 ChannelInfo* chan = (*c)[n];
1110 if ((chan->write_source = _session.create_audio_source_for_session (
1111 c->size(), write_source_name(), n, destructive())) == 0) {
1112 throw failed_constructor();
1116 catch (failed_constructor &err) {
1117 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1118 chan->write_source.reset ();
1122 /* do not remove destructive files even if they are empty */
1124 chan->write_source->set_allow_remove_if_empty (!destructive());
1131 DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abort_capture)
1133 bool more_work = true;
1135 samplecnt_t total_capture;
1136 SourceList audio_srcs;
1137 SourceList midi_srcs;
1138 ChannelList::iterator chan;
1139 vector<CaptureInfo*>::iterator ci;
1140 boost::shared_ptr<ChannelList> c = channels.reader();
1142 bool mark_write_completed = false;
1147 /* butler is already stopped, but there may be work to do
1148 to flush remaining data to disk.
1151 while (more_work && !err) {
1152 switch (do_flush (TransportContext, true)) {
1159 error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1164 /* XXX is there anything we can do if err != 0 ? */
1165 Glib::Threads::Mutex::Lock lm (capture_info_lock);
1167 if (capture_info.empty()) {
1171 if (abort_capture) {
1173 if (destructive()) {
1177 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1179 if ((*chan)->write_source) {
1181 (*chan)->write_source->mark_for_remove ();
1182 (*chan)->write_source->drop_references ();
1183 (*chan)->write_source.reset ();
1186 /* new source set up in "out" below */
1189 if (_midi_write_source) {
1190 _midi_write_source->mark_for_remove ();
1191 _midi_write_source->drop_references ();
1192 _midi_write_source.reset();
1198 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1199 total_capture += (*ci)->samples;
1202 /* figure out the name for this take */
1204 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1206 boost::shared_ptr<AudioFileSource> as = (*chan)->write_source;
1209 audio_srcs.push_back (as);
1210 as->update_header (capture_info.front()->start, when, twhen);
1211 as->set_captured_for (_name.val());
1212 as->mark_immutable ();
1214 if (Config->get_auto_analyse_audio()) {
1215 Analyser::queue_source_for_analysis (as, true);
1218 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("newly captured source %1 length %2\n", as->path(), as->length (0)));
1221 if (_midi_write_source) {
1222 midi_srcs.push_back (_midi_write_source);
1229 if (_midi_write_source) {
1231 if (_midi_write_source->length (capture_info.front()->start) == 0) {
1232 /* No data was recorded, so this capture will
1233 effectively be aborted; do the same as we
1234 do for an explicit abort.
1236 if (_midi_write_source) {
1237 _midi_write_source->mark_for_remove ();
1238 _midi_write_source->drop_references ();
1239 _midi_write_source.reset();
1245 /* phew, we have data */
1247 Source::Lock source_lock(_midi_write_source->mutex());
1249 /* figure out the name for this take */
1251 midi_srcs.push_back (_midi_write_source);
1253 _midi_write_source->set_timeline_position (capture_info.front()->start);
1254 _midi_write_source->set_captured_for (_name);
1256 /* set length in beats to entire capture length */
1258 BeatsSamplesConverter converter (_session.tempo_map(), capture_info.front()->start);
1259 const Temporal::Beats total_capture_beats = converter.from (total_capture);
1260 _midi_write_source->set_length_beats (total_capture_beats);
1262 /* flush to disk: this step differs from the audio path,
1263 where all the data is already on disk.
1266 _midi_write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Temporal::Beats>::ResolveStuckNotes, total_capture_beats);
1269 _last_capture_sources.insert (_last_capture_sources.end(), audio_srcs.begin(), audio_srcs.end());
1270 _last_capture_sources.insert (_last_capture_sources.end(), midi_srcs.begin(), midi_srcs.end());
1274 _route->use_captured_sources (audio_srcs, capture_info);
1275 _route->use_captured_sources (midi_srcs, capture_info);
1278 mark_write_completed = true;
1281 reset_write_sources (mark_write_completed);
1285 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1289 capture_info.clear ();
1290 capture_start_sample = 0;
1294 DiskWriter::transport_looped (samplepos_t transport_sample)
1296 if (was_recording) {
1297 // all we need to do is finish this capture, with modified capture length
1298 boost::shared_ptr<ChannelList> c = channels.reader();
1302 // the next region will start recording via the normal mechanism
1303 // we'll set the start position to the current transport pos
1304 // no latency adjustment or capture offset needs to be made, as that already happened the first time
1305 capture_start_sample = transport_sample;
1306 first_recordable_sample = transport_sample; // mild lie
1307 last_recordable_sample = max_samplepos;
1308 was_recording = true;
1310 if (recordable() && destructive()) {
1311 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1313 RingBufferNPT<CaptureTransition>::rw_vector transvec;
1314 (*chan)->capture_transition_buf->get_write_vector(&transvec);
1316 if (transvec.len[0] > 0) {
1317 transvec.buf[0]->type = CaptureStart;
1318 transvec.buf[0]->capture_val = capture_start_sample;
1319 (*chan)->capture_transition_buf->increment_write_ptr(1);
1323 fatal << X_("programming error: capture_transition_buf is full on rec loop! inconceivable!")
1331 /* Here we only keep track of the number of captured loops so monotonic
1332 event times can be delivered to the write source in process(). Trying
1333 to be clever here is a world of trouble, it is better to simply record
1334 the input in a straightforward non-destructive way. In the future when
1335 we want to implement more clever MIDI looping modes it should be done in
1336 the Source and/or entirely after the capture is finished.
1338 if (was_recording) {
1339 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1344 DiskWriter::setup_destructive_playlist ()
1347 boost::shared_ptr<ChannelList> c = channels.reader();
1349 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1350 srcs.push_back ((*chan)->write_source);
1353 /* a single full-sized region */
1355 assert (!srcs.empty ());
1358 plist.add (Properties::name, _name.val());
1359 plist.add (Properties::start, 0);
1360 plist.add (Properties::length, max_samplepos - srcs.front()->natural_position());
1362 boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist));
1363 _playlists[DataType::AUDIO]->add_region (region, srcs.front()->natural_position());
1365 /* apply region properties and update write sources */
1366 use_destructive_playlist();
1370 DiskWriter::use_destructive_playlist ()
1372 /* this is called from the XML-based constructor or ::set_destructive. when called,
1373 we already have a playlist and a region, but we need to
1374 set up our sources for write. we use the sources associated
1375 with the (presumed single, full-extent) region.
1378 boost::shared_ptr<Region> rp;
1380 const RegionList& rl (_playlists[DataType::AUDIO]->region_list_property().rlist());
1381 if (rl.size() > 0) {
1382 /* this can happen when dragging a region onto a tape track */
1383 assert((rl.size() == 1));
1389 reset_write_sources (false, true);
1393 boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (rp);
1396 throw failed_constructor();
1399 /* be sure to stretch the region out to the maximum length (non-musical)*/
1401 region->set_length (max_samplepos - region->position(), 0);
1404 ChannelList::iterator chan;
1405 boost::shared_ptr<ChannelList> c = channels.reader();
1407 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1408 (*chan)->write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
1409 assert((*chan)->write_source);
1410 (*chan)->write_source->set_allow_remove_if_empty (false);
1412 // should be set when creating the source or loading the state
1413 assert ((*chan)->write_source->destructive());
1416 /* the source list will never be reset for a destructive track */
1420 DiskWriter::adjust_buffering ()
1422 boost::shared_ptr<ChannelList> c = channels.reader();
1424 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1425 (*chan)->resize (_session.butler()->audio_diskstream_capture_buffer_size());
1430 DiskWriter::realtime_handle_transport_stopped ()
1435 DiskWriter::set_name (string const & str)
1437 string my_name = X_("recorder:");
1440 if (_name != my_name) {
1441 SessionObject::set_name (my_name);
1448 DiskWriter::steal_write_source_name ()
1450 if (_playlists[DataType::MIDI]) {
1451 string our_old_name = _midi_write_source->name();
1453 /* this will bump the name of the current write source to the next one
1454 * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1455 * current write source name (e.g. "MIDI 1-1" available). See the
1456 * comments in Session::create_midi_source_by_stealing_name() about why
1461 string new_path = _session.new_midi_source_path (name());
1463 if (_midi_write_source->rename (new_path)) {
1470 return our_old_name;
1473 return std::string();
1477 DiskWriter::configure_io (ChanCount in, ChanCount out)
1479 if (!DiskIOProcessor::configure_io (in, out)) {
1483 reset_write_sources (false, true);