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.
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"
39 using namespace ARDOUR;
43 ARDOUR::framecnt_t DiskWriter::_chunk_frames = DiskWriter::default_chunk_frames ();
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_frame (0)
51 , capture_captured (0)
52 , was_recording (false)
53 , adjust_capture_position (0)
55 , first_recordable_frame (max_framepos)
56 , last_recordable_frame (max_framepos)
57 , last_possibly_recording (0)
58 , _alignment_style (ExistingMaterial)
59 , _alignment_choice (Automatic)
60 , _num_captured_loops (0)
61 , _accumulated_capture_offset (0)
62 , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
64 DiskIOProcessor::init ();
67 DiskWriter::~DiskWriter ()
69 DEBUG_TRACE (DEBUG::Destruction, string_compose ("DiskWriter %1 @ %2 deleted\n", _name, this));
71 boost::shared_ptr<ChannelList> c = channels.reader();
73 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
74 (*chan)->write_source.reset ();
79 DiskWriter::default_chunk_frames ()
85 DiskWriter::set_write_source_name (string const & str)
87 _write_source_name = str;
92 DiskWriter::check_record_status (framepos_t transport_frame, bool can_record)
94 int possibly_recording;
97 const int transport_rolling = 0x4;
98 const int track_rec_enabled = 0x2;
99 const int global_rec_enabled = 0x1;
100 const int fully_rec_enabled = (transport_rolling|track_rec_enabled|global_rec_enabled);
102 /* merge together the 3 factors that affect record status, and compute
106 rolling = _session.transport_speed() != 0.0f;
107 possibly_recording = (rolling << 2) | ((int)record_enabled() << 1) | (int)can_record;
108 change = possibly_recording ^ last_possibly_recording;
110 if (possibly_recording == last_possibly_recording) {
114 const framecnt_t existing_material_offset = _session.worst_playback_latency();
116 if (possibly_recording == fully_rec_enabled) {
118 if (last_possibly_recording == fully_rec_enabled) {
122 capture_start_frame = _session.transport_frame();
123 first_recordable_frame = capture_start_frame + _capture_offset;
124 last_recordable_frame = max_framepos;
126 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: @ %7 (%9) FRF = %2 CSF = %4 CO = %5, EMO = %6 RD = %8 WOL %10 WTL %11\n",
127 name(), first_recordable_frame, last_recordable_frame, capture_start_frame,
129 existing_material_offset,
131 _session.transport_frame(),
132 _session.worst_output_latency(),
133 _session.worst_track_latency()));
136 if (_alignment_style == ExistingMaterial) {
137 first_recordable_frame += existing_material_offset;
138 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("\tshift FRF by EMO %1\n",
139 first_recordable_frame));
142 prepare_record_status (capture_start_frame);
146 if (last_possibly_recording == fully_rec_enabled) {
148 /* we were recording last time */
150 if (change & transport_rolling) {
152 /* transport-change (stopped rolling): last_recordable_frame was set in ::prepare_to_stop(). We
153 * had to set it there because we likely rolled past the stopping point to declick out,
154 * and then backed up.
160 last_recordable_frame = _session.transport_frame() + _capture_offset;
162 if (_alignment_style == ExistingMaterial) {
163 last_recordable_frame += existing_material_offset;
169 last_possibly_recording = possibly_recording;
173 DiskWriter::calculate_record_range (Evoral::OverlapType ot, framepos_t transport_frame, framecnt_t nframes,
174 framecnt_t & rec_nframes, framecnt_t & rec_offset)
177 case Evoral::OverlapNone:
181 case Evoral::OverlapInternal:
182 /* ---------- recrange
185 rec_nframes = nframes;
189 case Evoral::OverlapStart:
190 /* |--------| recrange
193 rec_nframes = transport_frame + nframes - first_recordable_frame;
195 rec_offset = first_recordable_frame - transport_frame;
199 case Evoral::OverlapEnd:
200 /* |--------| recrange
201 * |-------- transrange
203 rec_nframes = last_recordable_frame - transport_frame;
207 case Evoral::OverlapExternal:
208 /* |--------| recrange
209 * -------------- transrange
211 rec_nframes = last_recordable_frame - first_recordable_frame;
212 rec_offset = first_recordable_frame - transport_frame;
216 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 rec? %2 @ %3 (for %4) FRF %5 LRF %6 : rf %7 @ %8\n",
217 _name, enum_2_string (ot), transport_frame, nframes,
218 first_recordable_frame, last_recordable_frame, rec_nframes, rec_offset));
222 DiskWriter::prepare_to_stop (framepos_t transport_frame, framepos_t audible_frame)
224 switch (_alignment_style) {
225 case ExistingMaterial:
226 last_recordable_frame = transport_frame + _capture_offset;
227 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));
231 last_recordable_frame = audible_frame; // note that capture_offset is zero
232 /* we may already have captured audio before the last_recordable_frame (audible frame),
235 if (last_recordable_frame > capture_start_frame) {
236 capture_captured = min (capture_captured, last_recordable_frame - capture_start_frame);
238 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose("%1: prepare to stop sets last recordable frame to audible frame @ %2\n", _name, audible_frame));
245 DiskWriter::engage_record_enable ()
247 g_atomic_int_set (&_record_enabled, 1);
251 DiskWriter::disengage_record_enable ()
253 g_atomic_int_set (&_record_enabled, 0);
257 DiskWriter::engage_record_safe ()
259 g_atomic_int_set (&_record_safe, 1);
263 DiskWriter::disengage_record_safe ()
265 g_atomic_int_set (&_record_safe, 0);
268 /** Get the start position (in session frames) of the nth capture in the current pass */
270 DiskWriter::get_capture_start_frame (uint32_t n) const
272 Glib::Threads::Mutex::Lock lm (capture_info_lock);
274 if (capture_info.size() > n) {
275 /* this is a completed capture */
276 return capture_info[n]->start;
278 /* this is the currently in-progress capture */
279 return capture_start_frame;
284 DiskWriter::get_captured_frames (uint32_t n) const
286 Glib::Threads::Mutex::Lock lm (capture_info_lock);
288 if (capture_info.size() > n) {
289 /* this is a completed capture */
290 return capture_info[n]->frames;
292 /* this is the currently in-progress capture */
293 return capture_captured;
298 DiskWriter::set_input_latency (framecnt_t l)
300 Processor::set_input_latency (l);
301 set_capture_offset ();
305 DiskWriter::set_capture_offset ()
307 switch (_alignment_style) {
308 case ExistingMaterial:
309 _capture_offset = _input_latency;
318 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: using input latency %4, capture offset set to %2 with style = %3\n", name(), _capture_offset, enum_2_string (_alignment_style), _input_latency));
323 DiskWriter::set_align_style (AlignStyle a, bool force)
325 if (record_enabled() && _session.actively_recording()) {
329 if ((a != _alignment_style) || force) {
330 _alignment_style = a;
331 set_capture_offset ();
332 AlignmentStyleChanged ();
337 DiskWriter::set_align_choice (AlignChoice a, bool force)
339 if (record_enabled() && _session.actively_recording()) {
343 if ((a != _alignment_choice) || force) {
344 _alignment_choice = a;
346 switch (_alignment_choice) {
347 case UseExistingMaterial:
348 set_align_style (ExistingMaterial);
351 set_align_style (CaptureTime);
354 error << string_compose (_("programming error: %1"), "DiskWriter: asked to use illegal alignment style") << endmsg;
361 DiskWriter::state (bool full)
363 XMLNode& node (DiskIOProcessor::state (full));
364 node.set_property (X_("type"), X_("diskwriter"));
365 node.set_property (X_("capture-alignment"), enum_2_string (_alignment_choice));
366 node.set_property (X_("record-safe"), (_record_safe ? X_("yes" : "no")));
371 DiskWriter::set_state (const XMLNode& node, int version)
373 if (DiskIOProcessor::set_state (node, version)) {
379 if (node.get_property (X_("capture-alignment"), ac)) {
380 set_align_choice (ac, true);
382 set_align_choice (Automatic, true);
385 if (!node.get_property (X_("record-safe"), _record_safe)) {
386 _record_safe = false;
389 reset_write_sources (false, true);
395 DiskWriter::non_realtime_locate (framepos_t position)
397 if (_midi_write_source) {
398 _midi_write_source->set_timeline_position (position);
401 DiskIOProcessor::non_realtime_locate (position);
406 DiskWriter::prepare_record_status(framepos_t capture_start_frame)
408 if (recordable() && destructive()) {
409 boost::shared_ptr<ChannelList> c = channels.reader();
410 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
412 RingBufferNPT<CaptureTransition>::rw_vector transitions;
413 (*chan)->capture_transition_buf->get_write_vector (&transitions);
415 if (transitions.len[0] > 0) {
416 transitions.buf[0]->type = CaptureStart;
417 transitions.buf[0]->capture_val = capture_start_frame;
418 (*chan)->capture_transition_buf->increment_write_ptr(1);
421 fatal << X_("programming error: capture_transition_buf is full on rec start! inconceivable!")
429 /** Do some record stuff [not described in this comment!]
432 * - Setup playback_distance with the nframes, or nframes adjusted
433 * for current varispeed, if appropriate.
434 * - Setup current_playback_buffer in each ChannelInfo to point to data
435 * that someone can read playback_distance worth of data from.
438 DiskWriter::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
439 double speed, pframes_t nframes, bool result_required)
442 boost::shared_ptr<ChannelList> c = channels.reader();
443 ChannelList::iterator chan;
444 framecnt_t rec_offset = 0;
445 framecnt_t rec_nframes = 0;
446 bool nominally_recording;
447 bool re = record_enabled ();
448 bool can_record = _session.actively_recording ();
451 if (!_pending_active) {
456 if (_pending_active) {
463 _need_butler = false;
465 check_record_status (start_frame, can_record);
471 nominally_recording = (can_record && re);
473 // Safeguard against situations where process() goes haywire when autopunching
474 // and last_recordable_frame < first_recordable_frame
476 if (last_recordable_frame < first_recordable_frame) {
477 last_recordable_frame = max_framepos;
480 const Location* const loop_loc = loop_location;
481 framepos_t loop_start = 0;
482 framepos_t loop_end = 0;
483 framepos_t loop_length = 0;
486 get_location_times (loop_loc, &loop_start, &loop_end, &loop_length);
489 adjust_capture_position = 0;
491 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && (_session.config.get_punch_in() || _session.preroll_record_punch_enabled()))) {
493 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, start_frame, end_frame);
494 // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
495 // XXX also, first_recordable_frame & last_recordable_frame may both be == max_framepos: coverage() will return OverlapNone in that case. Is thak OK?
496 calculate_record_range (ot, start_frame, nframes, rec_nframes, rec_offset);
498 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: this time record %2 of %3 frames, offset %4\n", _name, rec_nframes, nframes, rec_offset));
500 if (rec_nframes && !was_recording) {
501 capture_captured = 0;
504 /* Loop recording, so pretend the capture started at the loop
505 start rgardless of what time it is now, so the source starts
506 at the loop start and can handle time wrapping around.
507 Otherwise, start the source right now as usual.
509 capture_captured = start_frame - loop_start;
510 capture_start_frame = loop_start;
513 if (_midi_write_source) {
514 _midi_write_source->mark_write_starting_now (capture_start_frame, capture_captured, loop_length);
517 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
518 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
520 was_recording = true;
524 /* For audio: not writing frames to the capture ringbuffer offsets
525 * the recording. For midi: we need to keep track of the record range
526 * and subtract the accumulated difference from the event time.
529 _accumulated_capture_offset += rec_offset;
531 _accumulated_capture_offset += nframes;
536 if (can_record && !_last_capture_sources.empty()) {
537 _last_capture_sources.clear ();
544 const size_t n_buffers = bufs.count().n_audio();
546 for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
548 ChannelInfo* chaninfo (*chan);
549 AudioBuffer& buf (bufs.get_audio (n%n_buffers));
551 chaninfo->buf->get_write_vector (&chaninfo->rw_vector);
553 if (rec_nframes <= (framecnt_t) chaninfo->rw_vector.len[0]) {
555 Sample *incoming = buf.data (rec_offset);
556 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * rec_nframes);
560 framecnt_t total = chaninfo->rw_vector.len[0] + chaninfo->rw_vector.len[1];
562 if (rec_nframes > total) {
563 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 overrun in %2, rec_nframes = %3 total space = %4\n",
564 DEBUG_THREAD_SELF, name(), rec_nframes, total));
569 Sample *incoming = buf.data (rec_offset);
570 framecnt_t first = chaninfo->rw_vector.len[0];
572 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * first);
573 memcpy (chaninfo->rw_vector.buf[1], incoming + first, sizeof (Sample) * (rec_nframes - first));
576 chaninfo->buf->increment_write_ptr (rec_nframes);
582 // Pump entire port buffer into the ring buffer (TODO: split cycles?)
583 MidiBuffer& buf = bufs.get_midi (0);
584 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
585 MidiChannelFilter* filter = mt ? &mt->capture_filter() : 0;
587 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
588 Evoral::Event<MidiBuffer::TimeType> ev(*i, false);
589 if (ev.time() + rec_offset > rec_nframes) {
593 if (DEBUG_ENABLED(DEBUG::MidiIO)) {
594 const uint8_t* __data = ev.buffer();
596 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), start_frame, ev.size()));
597 for (size_t i=0; i < ev.size(); ++i) {
598 DEBUG_STR_APPEND(a,hex);
599 DEBUG_STR_APPEND(a,"0x");
600 DEBUG_STR_APPEND(a,(int)__data[i]);
601 DEBUG_STR_APPEND(a,' ');
603 DEBUG_STR_APPEND(a,'\n');
604 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
607 /* Write events to the capture buffer in frames from session start,
608 but ignoring looping so event time progresses monotonically.
609 The source knows the loop length so it knows exactly where the
610 event occurs in the series of recorded loops and can implement
611 any desirable behaviour. We don't want to send event with
612 transport time here since that way the source can not
613 reconstruct their actual time; future clever MIDI looping should
614 probably be implemented in the source instead of here.
616 const framecnt_t loop_offset = _num_captured_loops * loop_length;
617 const framepos_t event_time = start_frame + loop_offset - _accumulated_capture_offset + ev.time();
618 if (event_time < 0 || event_time < first_recordable_frame) {
619 /* Event out of range, skip */
623 if (!filter || !filter->filter(ev.buffer(), ev.size())) {
624 _midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
627 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
629 if (buf.size() != 0) {
630 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
633 /* Copy this data into our GUI feed buffer and tell the GUI
634 that it can read it if it likes.
636 _gui_feed_buffer.clear ();
638 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
639 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
640 the end of the world if it does.
642 _gui_feed_buffer.push_back ((*i).time() + start_frame, (*i).size(), (*i).buffer());
646 DataRecorded (_midi_write_source); /* EMIT SIGNAL */
649 capture_captured += rec_nframes;
650 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 now captured %2 (by %3)\n", name(), capture_captured, rec_nframes));
654 /* not recording this time, but perhaps we were before .. */
658 _accumulated_capture_offset = 0;
662 /* AUDIO BUTLER REQUIRED CODE */
664 if (_playlists[DataType::AUDIO] && !c->empty()) {
665 if (((framecnt_t) c->front()->buf->read_space() >= _chunk_frames)) {
670 /* MIDI BUTLER REQUIRED CODE */
672 if (_playlists[DataType::MIDI] && (_midi_buf->read_space() < _midi_buf->bufsize() / 2)) {
676 // DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 writer run, needs butler = %2\n", name(), _need_butler));
680 DiskWriter::finish_capture (boost::shared_ptr<ChannelList> c)
682 was_recording = false;
683 first_recordable_frame = max_framepos;
684 last_recordable_frame = max_framepos;
686 if (capture_captured == 0) {
690 if (recordable() && destructive()) {
691 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
693 RingBufferNPT<CaptureTransition>::rw_vector transvec;
694 (*chan)->capture_transition_buf->get_write_vector(&transvec);
696 if (transvec.len[0] > 0) {
697 transvec.buf[0]->type = CaptureEnd;
698 transvec.buf[0]->capture_val = capture_captured;
699 (*chan)->capture_transition_buf->increment_write_ptr(1);
703 fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record! inconceivable!")) << endmsg;
709 CaptureInfo* ci = new CaptureInfo;
711 ci->start = capture_start_frame;
712 ci->frames = capture_captured;
714 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("Finish capture, add new CI, %1 + %2\n", ci->start, ci->frames));
716 /* XXX theoretical race condition here. Need atomic exchange ?
717 However, the circumstances when this is called right
718 now (either on record-disable or transport_stopped)
719 mean that no actual race exists. I think ...
720 We now have a capture_info_lock, but it is only to be used
721 to synchronize in the transport_stop and the capture info
722 accessors, so that invalidation will not occur (both non-realtime).
725 capture_info.push_back (ci);
726 capture_captured = 0;
728 /* now we've finished a capture, reset first_recordable_frame for next time */
729 first_recordable_frame = max_framepos;
733 DiskWriter::set_record_enabled (bool yn)
735 if (!recordable() || !_session.record_enabling_legal() || record_safe ()) {
739 /* can't rec-enable in destructive mode if transport is before start */
741 if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
745 /* yes, i know that this not proof against race conditions, but its
746 good enough. i think.
749 if (record_enabled() != yn) {
751 engage_record_enable ();
753 disengage_record_enable ();
756 RecordEnableChanged (); /* EMIT SIGNAL */
761 DiskWriter::set_record_safe (bool yn)
763 if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty()) {
767 /* can't rec-safe in destructive mode if transport is before start ????
770 if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
774 /* yes, i know that this not proof against race conditions, but its
775 good enough. i think.
778 if (record_safe () != yn) {
780 engage_record_safe ();
782 disengage_record_safe ();
785 RecordSafeChanged (); /* EMIT SIGNAL */
790 DiskWriter::prep_record_enable ()
792 if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty() || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
796 /* can't rec-enable in destructive mode if transport is before start */
798 if (destructive() && _session.transport_frame() < _session.current_start_frame()) {
802 boost::shared_ptr<ChannelList> c = channels.reader();
804 capturing_sources.clear ();
806 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
807 capturing_sources.push_back ((*chan)->write_source);
808 Source::Lock lock((*chan)->write_source->mutex());
809 (*chan)->write_source->mark_streaming_write_started (lock);
816 DiskWriter::prep_record_disable ()
818 capturing_sources.clear ();
823 DiskWriter::buffer_load () const
825 boost::shared_ptr<ChannelList> c = channels.reader();
831 return (float) ((double) c->front()->buf->write_space()/
832 (double) c->front()->buf->bufsize());
836 DiskWriter::set_note_mode (NoteMode m)
840 boost::shared_ptr<MidiPlaylist> mp = boost::dynamic_pointer_cast<MidiPlaylist> (_playlists[DataType::MIDI]);
843 mp->set_note_mode (m);
846 if (_midi_write_source && _midi_write_source->model())
847 _midi_write_source->model()->set_note_mode(m);
851 DiskWriter::seek (framepos_t frame, bool complete_refill)
854 ChannelList::iterator chan;
855 boost::shared_ptr<ChannelList> c = channels.reader();
857 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
858 (*chan)->buf->reset ();
862 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
863 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
865 /* can't rec-enable in destructive mode if transport is before start */
867 if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
868 disengage_record_enable ();
871 playback_sample = frame;
878 DiskWriter::do_flush (RunContext ctxt, bool force_flush)
882 RingBufferNPT<Sample>::rw_vector vector;
883 RingBufferNPT<CaptureTransition>::rw_vector transvec;
891 boost::shared_ptr<ChannelList> c = channels.reader();
892 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
894 (*chan)->buf->get_read_vector (&vector);
896 total = vector.len[0] + vector.len[1];
898 if (total == 0 || (total < _chunk_frames && !force_flush && was_recording)) {
902 /* if there are 2+ chunks of disk i/o possible for
903 this track, let the caller know so that it can arrange
904 for us to be called again, ASAP.
906 if we are forcing a flush, then if there is* any* extra
907 work, let the caller know.
909 if we are no longer recording and there is any extra work,
910 let the caller know too.
913 if (total >= 2 * _chunk_frames || ((force_flush || !was_recording) && total > _chunk_frames)) {
917 to_write = min (_chunk_frames, (framecnt_t) vector.len[0]);
919 // check the transition buffer when recording destructive
920 // important that we get this after the capture buf
923 (*chan)->capture_transition_buf->get_read_vector(&transvec);
924 size_t transcount = transvec.len[0] + transvec.len[1];
927 for (ti=0; ti < transcount; ++ti) {
928 CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
930 if (captrans.type == CaptureStart) {
931 // by definition, the first data we got above represents the given capture pos
933 (*chan)->write_source->mark_capture_start (captrans.capture_val);
934 (*chan)->curr_capture_cnt = 0;
936 } else if (captrans.type == CaptureEnd) {
938 // capture end, the capture_val represents total frames in capture
940 if (captrans.capture_val <= (*chan)->curr_capture_cnt + to_write) {
942 // shorten to make the write a perfect fit
943 uint32_t nto_write = (captrans.capture_val - (*chan)->curr_capture_cnt);
945 if (nto_write < to_write) {
946 ret = 1; // should we?
948 to_write = nto_write;
950 (*chan)->write_source->mark_capture_end ();
952 // increment past this transition, but go no further
957 // actually ends just beyond this chunk, so force more work
965 (*chan)->capture_transition_buf->increment_read_ptr(ti);
969 if ((!(*chan)->write_source) || (*chan)->write_source->write (vector.buf[0], to_write) != to_write) {
970 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
974 (*chan)->buf->increment_read_ptr (to_write);
975 (*chan)->curr_capture_cnt += to_write;
977 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < _chunk_frames) && !destructive()) {
979 /* we wrote all of vector.len[0] but it wasn't an entire
980 disk_write_chunk_frames of data, so arrange for some part
981 of vector.len[1] to be flushed to disk as well.
984 to_write = min ((framecnt_t)(_chunk_frames - to_write), (framecnt_t) vector.len[1]);
986 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 additional write of %2\n", name(), to_write));
988 if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) {
989 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
993 (*chan)->buf->increment_read_ptr (to_write);
994 (*chan)->curr_capture_cnt += to_write;
1000 if (_midi_write_source) {
1002 const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
1005 _midi_buf->read_space() == 0 ||
1006 (!force_flush && (total < _chunk_frames) && was_recording)) {
1010 /* if there are 2+ chunks of disk i/o possible for
1011 this track), let the caller know so that it can arrange
1012 for us to be called again, ASAP.
1014 if we are forcing a flush, then if there is* any* extra
1015 work, let the caller know.
1017 if we are no longer recording and there is any extra work,
1018 let the caller know too.
1021 if (total >= 2 * _chunk_frames || ((force_flush || !was_recording) && total > _chunk_frames)) {
1026 /* push out everything we have, right now */
1027 to_write = UINT32_MAX;
1029 to_write = _chunk_frames;
1032 if (record_enabled() && ((total > _chunk_frames) || force_flush)) {
1033 Source::Lock lm(_midi_write_source->mutex());
1034 if (_midi_write_source->midi_write (lm, *_midi_buf, get_capture_start_frame (0), to_write) != to_write) {
1035 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
1038 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
1048 DiskWriter::reset_write_sources (bool mark_write_complete, bool /*force*/)
1050 ChannelList::iterator chan;
1051 boost::shared_ptr<ChannelList> c = channels.reader();
1054 if (!_session.writable() || !recordable()) {
1058 capturing_sources.clear ();
1060 for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
1062 if (!destructive()) {
1064 if ((*chan)->write_source) {
1066 if (mark_write_complete) {
1067 Source::Lock lock((*chan)->write_source->mutex());
1068 (*chan)->write_source->mark_streaming_write_completed (lock);
1069 (*chan)->write_source->done_with_peakfile_writes ();
1072 if ((*chan)->write_source->removable()) {
1073 (*chan)->write_source->mark_for_remove ();
1074 (*chan)->write_source->drop_references ();
1077 (*chan)->write_source.reset ();
1080 use_new_write_source (DataType::AUDIO, n);
1082 if (record_enabled()) {
1083 capturing_sources.push_back ((*chan)->write_source);
1088 if ((*chan)->write_source == 0) {
1089 use_new_write_source (DataType::AUDIO, n);
1094 if (_midi_write_source) {
1095 if (mark_write_complete) {
1096 Source::Lock lm(_midi_write_source->mutex());
1097 _midi_write_source->mark_streaming_write_completed (lm);
1101 if (_playlists[DataType::MIDI]) {
1102 use_new_write_source (DataType::MIDI);
1105 if (destructive() && !c->empty ()) {
1107 /* we now have all our write sources set up, so create the
1108 playlist's single region.
1111 if (_playlists[DataType::MIDI]->empty()) {
1112 setup_destructive_playlist ();
1118 DiskWriter::use_new_write_source (DataType dt, uint32_t n)
1120 if (dt == DataType::MIDI) {
1122 _accumulated_capture_offset = 0;
1123 _midi_write_source.reset();
1126 _midi_write_source = boost::dynamic_pointer_cast<SMFSource>(
1127 _session.create_midi_source_for_session (write_source_name ()));
1129 if (!_midi_write_source) {
1130 throw failed_constructor();
1134 catch (failed_constructor &err) {
1135 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1136 _midi_write_source.reset();
1140 boost::shared_ptr<ChannelList> c = channels.reader();
1142 if (!recordable()) {
1146 if (n >= c->size()) {
1147 error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg;
1151 ChannelInfo* chan = (*c)[n];
1154 if ((chan->write_source = _session.create_audio_source_for_session (
1155 c->size(), write_source_name(), n, destructive())) == 0) {
1156 throw failed_constructor();
1160 catch (failed_constructor &err) {
1161 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1162 chan->write_source.reset ();
1166 /* do not remove destructive files even if they are empty */
1168 chan->write_source->set_allow_remove_if_empty (!destructive());
1175 DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abort_capture)
1177 bool more_work = true;
1179 framecnt_t total_capture;
1180 SourceList audio_srcs;
1181 SourceList midi_srcs;
1182 ChannelList::iterator chan;
1183 vector<CaptureInfo*>::iterator ci;
1184 boost::shared_ptr<ChannelList> c = channels.reader();
1186 bool mark_write_completed = false;
1191 /* butler is already stopped, but there may be work to do
1192 to flush remaining data to disk.
1195 while (more_work && !err) {
1196 switch (do_flush (TransportContext, true)) {
1203 error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1208 /* XXX is there anything we can do if err != 0 ? */
1209 Glib::Threads::Mutex::Lock lm (capture_info_lock);
1211 if (capture_info.empty()) {
1215 if (abort_capture) {
1217 if (destructive()) {
1221 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1223 if ((*chan)->write_source) {
1225 (*chan)->write_source->mark_for_remove ();
1226 (*chan)->write_source->drop_references ();
1227 (*chan)->write_source.reset ();
1230 /* new source set up in "out" below */
1233 if (_midi_write_source) {
1234 _midi_write_source->mark_for_remove ();
1235 _midi_write_source->drop_references ();
1236 _midi_write_source.reset();
1242 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1243 total_capture += (*ci)->frames;
1246 /* figure out the name for this take */
1248 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1250 boost::shared_ptr<AudioFileSource> as = (*chan)->write_source;
1253 audio_srcs.push_back (as);
1254 as->update_header (capture_info.front()->start, when, twhen);
1255 as->set_captured_for (_name.val());
1256 as->mark_immutable ();
1258 if (Config->get_auto_analyse_audio()) {
1259 Analyser::queue_source_for_analysis (as, true);
1262 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("newly captured source %1 length %2\n", as->path(), as->length (0)));
1265 if (_midi_write_source) {
1266 midi_srcs.push_back (_midi_write_source);
1273 if (_midi_write_source) {
1275 if (_midi_write_source->length (capture_info.front()->start) == 0) {
1276 /* No data was recorded, so this capture will
1277 effectively be aborted; do the same as we
1278 do for an explicit abort.
1280 if (_midi_write_source) {
1281 _midi_write_source->mark_for_remove ();
1282 _midi_write_source->drop_references ();
1283 _midi_write_source.reset();
1289 /* phew, we have data */
1291 Source::Lock source_lock(_midi_write_source->mutex());
1293 /* figure out the name for this take */
1295 midi_srcs.push_back (_midi_write_source);
1297 _midi_write_source->set_timeline_position (capture_info.front()->start);
1298 _midi_write_source->set_captured_for (_name);
1300 /* set length in beats to entire capture length */
1302 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
1303 const Evoral::Beats total_capture_beats = converter.from (total_capture);
1304 _midi_write_source->set_length_beats (total_capture_beats);
1306 /* flush to disk: this step differs from the audio path,
1307 where all the data is already on disk.
1310 _midi_write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
1313 _last_capture_sources.insert (_last_capture_sources.end(), audio_srcs.begin(), audio_srcs.end());
1314 _last_capture_sources.insert (_last_capture_sources.end(), midi_srcs.begin(), midi_srcs.end());
1318 _route->use_captured_sources (audio_srcs, capture_info);
1319 _route->use_captured_sources (midi_srcs, capture_info);
1322 mark_write_completed = true;
1325 reset_write_sources (mark_write_completed);
1329 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1333 capture_info.clear ();
1334 capture_start_frame = 0;
1338 DiskWriter::transport_looped (framepos_t transport_frame)
1340 if (was_recording) {
1341 // all we need to do is finish this capture, with modified capture length
1342 boost::shared_ptr<ChannelList> c = channels.reader();
1346 // the next region will start recording via the normal mechanism
1347 // we'll set the start position to the current transport pos
1348 // no latency adjustment or capture offset needs to be made, as that already happened the first time
1349 capture_start_frame = transport_frame;
1350 first_recordable_frame = transport_frame; // mild lie
1351 last_recordable_frame = max_framepos;
1352 was_recording = true;
1354 if (recordable() && destructive()) {
1355 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1357 RingBufferNPT<CaptureTransition>::rw_vector transvec;
1358 (*chan)->capture_transition_buf->get_write_vector(&transvec);
1360 if (transvec.len[0] > 0) {
1361 transvec.buf[0]->type = CaptureStart;
1362 transvec.buf[0]->capture_val = capture_start_frame;
1363 (*chan)->capture_transition_buf->increment_write_ptr(1);
1367 fatal << X_("programming error: capture_transition_buf is full on rec loop! inconceivable!")
1375 /* Here we only keep track of the number of captured loops so monotonic
1376 event times can be delivered to the write source in process(). Trying
1377 to be clever here is a world of trouble, it is better to simply record
1378 the input in a straightforward non-destructive way. In the future when
1379 we want to implement more clever MIDI looping modes it should be done in
1380 the Source and/or entirely after the capture is finished.
1382 if (was_recording) {
1383 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1388 DiskWriter::setup_destructive_playlist ()
1391 boost::shared_ptr<ChannelList> c = channels.reader();
1393 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1394 srcs.push_back ((*chan)->write_source);
1397 /* a single full-sized region */
1399 assert (!srcs.empty ());
1402 plist.add (Properties::name, _name.val());
1403 plist.add (Properties::start, 0);
1404 plist.add (Properties::length, max_framepos - srcs.front()->natural_position());
1406 boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist));
1407 _playlists[DataType::AUDIO]->add_region (region, srcs.front()->natural_position());
1409 /* apply region properties and update write sources */
1410 use_destructive_playlist();
1414 DiskWriter::use_destructive_playlist ()
1416 /* this is called from the XML-based constructor or ::set_destructive. when called,
1417 we already have a playlist and a region, but we need to
1418 set up our sources for write. we use the sources associated
1419 with the (presumed single, full-extent) region.
1422 boost::shared_ptr<Region> rp;
1424 const RegionList& rl (_playlists[DataType::AUDIO]->region_list_property().rlist());
1425 if (rl.size() > 0) {
1426 /* this can happen when dragging a region onto a tape track */
1427 assert((rl.size() == 1));
1433 reset_write_sources (false, true);
1437 boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (rp);
1440 throw failed_constructor();
1443 /* be sure to stretch the region out to the maximum length (non-musical)*/
1445 region->set_length (max_framepos - region->position(), 0);
1448 ChannelList::iterator chan;
1449 boost::shared_ptr<ChannelList> c = channels.reader();
1451 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1452 (*chan)->write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
1453 assert((*chan)->write_source);
1454 (*chan)->write_source->set_allow_remove_if_empty (false);
1456 /* this might be false if we switched modes, so force it */
1458 #ifdef XXX_OLD_DESTRUCTIVE_API_XXX
1459 (*chan)->write_source->set_destructive (true);
1461 // should be set when creating the source or loading the state
1462 assert ((*chan)->write_source->destructive());
1466 /* the source list will never be reset for a destructive track */
1470 DiskWriter::adjust_buffering ()
1472 boost::shared_ptr<ChannelList> c = channels.reader();
1474 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1475 (*chan)->resize (_session.butler()->audio_diskstream_capture_buffer_size());
1480 DiskWriter::realtime_handle_transport_stopped ()
1482 realtime_speed_change ();
1486 DiskWriter::set_name (string const & str)
1488 string my_name = X_("recorder:");
1491 if (_name != my_name) {
1492 SessionObject::set_name (my_name);
1499 DiskWriter::steal_write_source_name ()
1501 if (_playlists[DataType::MIDI]) {
1502 string our_old_name = _midi_write_source->name();
1504 /* this will bump the name of the current write source to the next one
1505 * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1506 * current write source name (e.g. "MIDI 1-1" available). See the
1507 * comments in Session::create_midi_source_by_stealing_name() about why
1512 string new_path = _session.new_midi_source_path (name());
1514 if (_midi_write_source->rename (new_path)) {
1521 return our_old_name;
1524 return std::string();
1528 DiskWriter::configure_io (ChanCount in, ChanCount out)
1530 if (!DiskIOProcessor::configure_io (in, out)) {
1534 reset_write_sources (false, true);