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));
73 DiskWriter::default_chunk_frames ()
79 DiskWriter::set_write_source_name (string const & str)
81 _write_source_name = str;
86 DiskWriter::check_record_status (framepos_t transport_frame, bool can_record)
88 int possibly_recording;
91 const int transport_rolling = 0x4;
92 const int track_rec_enabled = 0x2;
93 const int global_rec_enabled = 0x1;
94 const int fully_rec_enabled = (transport_rolling|track_rec_enabled|global_rec_enabled);
96 /* merge together the 3 factors that affect record status, and compute
100 rolling = _session.transport_speed() != 0.0f;
101 possibly_recording = (rolling << 2) | ((int)record_enabled() << 1) | (int)can_record;
102 change = possibly_recording ^ last_possibly_recording;
104 if (possibly_recording == last_possibly_recording) {
108 const framecnt_t existing_material_offset = _session.worst_playback_latency();
110 if (possibly_recording == fully_rec_enabled) {
112 if (last_possibly_recording == fully_rec_enabled) {
116 capture_start_frame = _session.transport_frame();
117 first_recordable_frame = capture_start_frame + _capture_offset;
118 last_recordable_frame = max_framepos;
120 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: @ %7 (%9) FRF = %2 CSF = %4 CO = %5, EMO = %6 RD = %8 WOL %10 WTL %11\n",
121 name(), first_recordable_frame, last_recordable_frame, capture_start_frame,
123 existing_material_offset,
125 _session.transport_frame(),
126 _session.worst_output_latency(),
127 _session.worst_track_latency()));
130 if (_alignment_style == ExistingMaterial) {
131 first_recordable_frame += existing_material_offset;
132 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("\tshift FRF by EMO %1\n",
133 first_recordable_frame));
136 prepare_record_status (capture_start_frame);
140 if (last_possibly_recording == fully_rec_enabled) {
142 /* we were recording last time */
144 if (change & transport_rolling) {
146 /* transport-change (stopped rolling): last_recordable_frame was set in ::prepare_to_stop(). We
147 * had to set it there because we likely rolled past the stopping point to declick out,
148 * and then backed up.
154 last_recordable_frame = _session.transport_frame() + _capture_offset;
156 if (_alignment_style == ExistingMaterial) {
157 last_recordable_frame += existing_material_offset;
163 last_possibly_recording = possibly_recording;
167 DiskWriter::calculate_record_range (Evoral::OverlapType ot, framepos_t transport_frame, framecnt_t nframes,
168 framecnt_t & rec_nframes, framecnt_t & rec_offset)
171 case Evoral::OverlapNone:
175 case Evoral::OverlapInternal:
176 /* ---------- recrange
179 rec_nframes = nframes;
183 case Evoral::OverlapStart:
184 /* |--------| recrange
187 rec_nframes = transport_frame + nframes - first_recordable_frame;
189 rec_offset = first_recordable_frame - transport_frame;
193 case Evoral::OverlapEnd:
194 /* |--------| recrange
195 * |-------- transrange
197 rec_nframes = last_recordable_frame - transport_frame;
201 case Evoral::OverlapExternal:
202 /* |--------| recrange
203 * -------------- transrange
205 rec_nframes = last_recordable_frame - first_recordable_frame;
206 rec_offset = first_recordable_frame - transport_frame;
210 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 rec? %2 @ %3 (for %4) FRF %5 LRF %6 : rf %7 @ %8\n",
211 _name, enum_2_string (ot), transport_frame, nframes,
212 first_recordable_frame, last_recordable_frame, rec_nframes, rec_offset));
216 DiskWriter::prepare_to_stop (framepos_t transport_frame, framepos_t audible_frame)
218 switch (_alignment_style) {
219 case ExistingMaterial:
220 last_recordable_frame = transport_frame + _capture_offset;
221 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose("%1: prepare to stop sets last recordable frame to %2 + %3 = %4\n", _name, transport_frame, _capture_offset, last_recordable_frame));
225 last_recordable_frame = audible_frame; // note that capture_offset is zero
226 /* we may already have captured audio before the last_recordable_frame (audible frame),
229 if (last_recordable_frame > capture_start_frame) {
230 capture_captured = min (capture_captured, last_recordable_frame - capture_start_frame);
232 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose("%1: prepare to stop sets last recordable frame to audible frame @ %2\n", _name, audible_frame));
239 DiskWriter::engage_record_enable ()
241 g_atomic_int_set (&_record_enabled, 1);
245 DiskWriter::disengage_record_enable ()
247 g_atomic_int_set (&_record_enabled, 0);
251 DiskWriter::engage_record_safe ()
253 g_atomic_int_set (&_record_safe, 1);
257 DiskWriter::disengage_record_safe ()
259 g_atomic_int_set (&_record_safe, 0);
262 /** Get the start position (in session frames) of the nth capture in the current pass */
264 DiskWriter::get_capture_start_frame (uint32_t n) const
266 Glib::Threads::Mutex::Lock lm (capture_info_lock);
268 if (capture_info.size() > n) {
269 /* this is a completed capture */
270 return capture_info[n]->start;
272 /* this is the currently in-progress capture */
273 return capture_start_frame;
278 DiskWriter::get_captured_frames (uint32_t n) const
280 Glib::Threads::Mutex::Lock lm (capture_info_lock);
282 if (capture_info.size() > n) {
283 /* this is a completed capture */
284 return capture_info[n]->frames;
286 /* this is the currently in-progress capture */
287 return capture_captured;
292 DiskWriter::set_input_latency (framecnt_t l)
294 Processor::set_input_latency (l);
295 set_capture_offset ();
299 DiskWriter::set_capture_offset ()
301 switch (_alignment_style) {
302 case ExistingMaterial:
303 _capture_offset = _input_latency;
312 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: using input latency %4, capture offset set to %2 with style = %3\n", name(), _capture_offset, enum_2_string (_alignment_style), _input_latency));
317 DiskWriter::set_align_style (AlignStyle a, bool force)
319 if (record_enabled() && _session.actively_recording()) {
323 if ((a != _alignment_style) || force) {
324 _alignment_style = a;
325 set_capture_offset ();
326 AlignmentStyleChanged ();
331 DiskWriter::set_align_choice (AlignChoice a, bool force)
333 if (record_enabled() && _session.actively_recording()) {
337 if ((a != _alignment_choice) || force) {
338 _alignment_choice = a;
340 switch (_alignment_choice) {
341 case UseExistingMaterial:
342 set_align_style (ExistingMaterial);
345 set_align_style (CaptureTime);
348 error << string_compose (_("programming error: %1"), "DiskWriter: asked to use illegal alignment style") << endmsg;
355 DiskWriter::state (bool full)
357 XMLNode& node (DiskIOProcessor::state (full));
358 node.set_property (X_("type"), X_("diskwriter"));
359 node.set_property (X_("capture-alignment"), enum_2_string (_alignment_choice));
360 node.set_property (X_("record-safe"), (_record_safe ? X_("yes" : "no")));
365 DiskWriter::set_state (const XMLNode& node, int version)
367 if (DiskIOProcessor::set_state (node, version)) {
373 if (node.get_property (X_("capture-alignment"), ac)) {
374 set_align_choice (ac, true);
376 set_align_choice (Automatic, true);
379 if (!node.get_property (X_("record-safe"), _record_safe)) {
380 _record_safe = false;
383 reset_write_sources (false, true);
389 DiskWriter::non_realtime_locate (framepos_t position)
391 if (_midi_write_source) {
392 _midi_write_source->set_timeline_position (position);
395 DiskIOProcessor::non_realtime_locate (position);
400 DiskWriter::prepare_record_status(framepos_t capture_start_frame)
402 if (recordable() && destructive()) {
403 boost::shared_ptr<ChannelList> c = channels.reader();
404 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
406 RingBufferNPT<CaptureTransition>::rw_vector transitions;
407 (*chan)->capture_transition_buf->get_write_vector (&transitions);
409 if (transitions.len[0] > 0) {
410 transitions.buf[0]->type = CaptureStart;
411 transitions.buf[0]->capture_val = capture_start_frame;
412 (*chan)->capture_transition_buf->increment_write_ptr(1);
415 fatal << X_("programming error: capture_transition_buf is full on rec start! inconceivable!")
423 /** Do some record stuff [not described in this comment!]
426 * - Setup playback_distance with the nframes, or nframes adjusted
427 * for current varispeed, if appropriate.
428 * - Setup current_playback_buffer in each ChannelInfo to point to data
429 * that someone can read playback_distance worth of data from.
432 DiskWriter::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
433 double speed, pframes_t nframes, bool result_required)
436 boost::shared_ptr<ChannelList> c = channels.reader();
437 ChannelList::iterator chan;
438 framecnt_t rec_offset = 0;
439 framecnt_t rec_nframes = 0;
440 bool nominally_recording;
441 bool re = record_enabled ();
442 bool can_record = _session.actively_recording ();
445 if (!_pending_active) {
450 if (_pending_active) {
457 _need_butler = false;
459 check_record_status (start_frame, can_record);
465 nominally_recording = (can_record && re);
467 // Safeguard against situations where process() goes haywire when autopunching
468 // and last_recordable_frame < first_recordable_frame
470 if (last_recordable_frame < first_recordable_frame) {
471 last_recordable_frame = max_framepos;
474 const Location* const loop_loc = loop_location;
475 framepos_t loop_start = 0;
476 framepos_t loop_end = 0;
477 framepos_t loop_length = 0;
480 get_location_times (loop_loc, &loop_start, &loop_end, &loop_length);
483 adjust_capture_position = 0;
485 if (nominally_recording || (re && was_recording && _session.get_record_enabled() && (_session.config.get_punch_in() || _session.preroll_record_punch_enabled()))) {
487 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, start_frame, end_frame);
488 // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
489 // XXX also, first_recordable_frame & last_recordable_frame may both be == max_framepos: coverage() will return OverlapNone in that case. Is thak OK?
490 calculate_record_range (ot, start_frame, nframes, rec_nframes, rec_offset);
492 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: this time record %2 of %3 frames, offset %4\n", _name, rec_nframes, nframes, rec_offset));
494 if (rec_nframes && !was_recording) {
495 capture_captured = 0;
498 /* Loop recording, so pretend the capture started at the loop
499 start rgardless of what time it is now, so the source starts
500 at the loop start and can handle time wrapping around.
501 Otherwise, start the source right now as usual.
503 capture_captured = start_frame - loop_start;
504 capture_start_frame = loop_start;
507 if (_midi_write_source) {
508 _midi_write_source->mark_write_starting_now (capture_start_frame, capture_captured, loop_length);
511 g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
512 g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
514 was_recording = true;
518 /* For audio: not writing frames to the capture ringbuffer offsets
519 * the recording. For midi: we need to keep track of the record range
520 * and subtract the accumulated difference from the event time.
523 _accumulated_capture_offset += rec_offset;
525 _accumulated_capture_offset += nframes;
530 if (can_record && !_last_capture_sources.empty()) {
531 _last_capture_sources.clear ();
538 const size_t n_buffers = bufs.count().n_audio();
540 for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
542 ChannelInfo* chaninfo (*chan);
543 AudioBuffer& buf (bufs.get_audio (n%n_buffers));
545 chaninfo->buf->get_write_vector (&chaninfo->rw_vector);
547 if (rec_nframes <= (framecnt_t) chaninfo->rw_vector.len[0]) {
549 Sample *incoming = buf.data (rec_offset);
550 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * rec_nframes);
554 framecnt_t total = chaninfo->rw_vector.len[0] + chaninfo->rw_vector.len[1];
556 if (rec_nframes > total) {
557 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 overrun in %2, rec_nframes = %3 total space = %4\n",
558 DEBUG_THREAD_SELF, name(), rec_nframes, total));
563 Sample *incoming = buf.data (rec_offset);
564 framecnt_t first = chaninfo->rw_vector.len[0];
566 memcpy (chaninfo->rw_vector.buf[0], incoming, sizeof (Sample) * first);
567 memcpy (chaninfo->rw_vector.buf[1], incoming + first, sizeof (Sample) * (rec_nframes - first));
570 chaninfo->buf->increment_write_ptr (rec_nframes);
576 // Pump entire port buffer into the ring buffer (TODO: split cycles?)
577 MidiBuffer& buf = bufs.get_midi (0);
578 boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
579 MidiChannelFilter* filter = mt ? &mt->capture_filter() : 0;
581 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
582 Evoral::Event<MidiBuffer::TimeType> ev(*i, false);
583 if (ev.time() + rec_offset > rec_nframes) {
587 if (DEBUG_ENABLED(DEBUG::MidiIO)) {
588 const uint8_t* __data = ev.buffer();
590 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), start_frame, ev.size()));
591 for (size_t i=0; i < ev.size(); ++i) {
592 DEBUG_STR_APPEND(a,hex);
593 DEBUG_STR_APPEND(a,"0x");
594 DEBUG_STR_APPEND(a,(int)__data[i]);
595 DEBUG_STR_APPEND(a,' ');
597 DEBUG_STR_APPEND(a,'\n');
598 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
601 /* Write events to the capture buffer in frames from session start,
602 but ignoring looping so event time progresses monotonically.
603 The source knows the loop length so it knows exactly where the
604 event occurs in the series of recorded loops and can implement
605 any desirable behaviour. We don't want to send event with
606 transport time here since that way the source can not
607 reconstruct their actual time; future clever MIDI looping should
608 probably be implemented in the source instead of here.
610 const framecnt_t loop_offset = _num_captured_loops * loop_length;
611 const framepos_t event_time = start_frame + loop_offset - _accumulated_capture_offset + ev.time();
612 if (event_time < 0 || event_time < first_recordable_frame) {
613 /* Event out of range, skip */
617 if (!filter || !filter->filter(ev.buffer(), ev.size())) {
618 _midi_buf->write (event_time, ev.event_type(), ev.size(), ev.buffer());
621 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
623 if (buf.size() != 0) {
624 Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
627 /* Copy this data into our GUI feed buffer and tell the GUI
628 that it can read it if it likes.
630 _gui_feed_buffer.clear ();
632 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
633 /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
634 the end of the world if it does.
636 _gui_feed_buffer.push_back ((*i).time() + start_frame, (*i).size(), (*i).buffer());
640 DataRecorded (_midi_write_source); /* EMIT SIGNAL */
643 capture_captured += rec_nframes;
644 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 now captured %2 (by %3)\n", name(), capture_captured, rec_nframes));
648 /* not recording this time, but perhaps we were before .. */
652 _accumulated_capture_offset = 0;
656 /* AUDIO BUTLER REQUIRED CODE */
658 if (_playlists[DataType::AUDIO] && !c->empty()) {
659 if (((framecnt_t) c->front()->buf->read_space() >= _chunk_frames)) {
664 /* MIDI BUTLER REQUIRED CODE */
666 if (_playlists[DataType::MIDI] && (_midi_buf->read_space() < _midi_buf->bufsize() / 2)) {
670 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 writer run, needs butler = %2\n", name(), _need_butler));
674 DiskWriter::finish_capture (boost::shared_ptr<ChannelList> c)
676 was_recording = false;
677 first_recordable_frame = max_framepos;
678 last_recordable_frame = max_framepos;
680 if (capture_captured == 0) {
684 if (recordable() && destructive()) {
685 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
687 RingBufferNPT<CaptureTransition>::rw_vector transvec;
688 (*chan)->capture_transition_buf->get_write_vector(&transvec);
690 if (transvec.len[0] > 0) {
691 transvec.buf[0]->type = CaptureEnd;
692 transvec.buf[0]->capture_val = capture_captured;
693 (*chan)->capture_transition_buf->increment_write_ptr(1);
697 fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record! inconceivable!")) << endmsg;
703 CaptureInfo* ci = new CaptureInfo;
705 ci->start = capture_start_frame;
706 ci->frames = capture_captured;
708 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("Finish capture, add new CI, %1 + %2\n", ci->start, ci->frames));
710 /* XXX theoretical race condition here. Need atomic exchange ?
711 However, the circumstances when this is called right
712 now (either on record-disable or transport_stopped)
713 mean that no actual race exists. I think ...
714 We now have a capture_info_lock, but it is only to be used
715 to synchronize in the transport_stop and the capture info
716 accessors, so that invalidation will not occur (both non-realtime).
719 capture_info.push_back (ci);
720 capture_captured = 0;
722 /* now we've finished a capture, reset first_recordable_frame for next time */
723 first_recordable_frame = max_framepos;
727 DiskWriter::set_record_enabled (bool yn)
729 if (!recordable() || !_session.record_enabling_legal() || record_safe ()) {
733 /* can't rec-enable in destructive mode if transport is before start */
735 if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
739 /* yes, i know that this not proof against race conditions, but its
740 good enough. i think.
743 if (record_enabled() != yn) {
745 engage_record_enable ();
747 disengage_record_enable ();
750 RecordEnableChanged (); /* EMIT SIGNAL */
755 DiskWriter::set_record_safe (bool yn)
757 if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty()) {
761 /* can't rec-safe in destructive mode if transport is before start ????
764 if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
768 /* yes, i know that this not proof against race conditions, but its
769 good enough. i think.
772 if (record_safe () != yn) {
774 engage_record_safe ();
776 disengage_record_safe ();
779 RecordSafeChanged (); /* EMIT SIGNAL */
784 DiskWriter::prep_record_enable ()
786 if (!recordable() || !_session.record_enabling_legal() || channels.reader()->empty() || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
790 /* can't rec-enable in destructive mode if transport is before start */
792 if (destructive() && _session.transport_frame() < _session.current_start_frame()) {
796 boost::shared_ptr<ChannelList> c = channels.reader();
798 capturing_sources.clear ();
800 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
801 capturing_sources.push_back ((*chan)->write_source);
802 Source::Lock lock((*chan)->write_source->mutex());
803 (*chan)->write_source->mark_streaming_write_started (lock);
810 DiskWriter::prep_record_disable ()
812 capturing_sources.clear ();
817 DiskWriter::buffer_load () const
819 boost::shared_ptr<ChannelList> c = channels.reader();
825 return (float) ((double) c->front()->buf->write_space()/
826 (double) c->front()->buf->bufsize());
830 DiskWriter::set_note_mode (NoteMode m)
834 boost::shared_ptr<MidiPlaylist> mp = boost::dynamic_pointer_cast<MidiPlaylist> (_playlists[DataType::MIDI]);
837 mp->set_note_mode (m);
840 if (_midi_write_source && _midi_write_source->model())
841 _midi_write_source->model()->set_note_mode(m);
845 DiskWriter::seek (framepos_t frame, bool complete_refill)
848 ChannelList::iterator chan;
849 boost::shared_ptr<ChannelList> c = channels.reader();
851 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
852 (*chan)->buf->reset ();
856 g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
857 g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
859 /* can't rec-enable in destructive mode if transport is before start */
861 if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
862 disengage_record_enable ();
865 playback_sample = frame;
872 DiskWriter::do_flush (RunContext ctxt, bool force_flush)
876 RingBufferNPT<Sample>::rw_vector vector;
877 RingBufferNPT<CaptureTransition>::rw_vector transvec;
885 boost::shared_ptr<ChannelList> c = channels.reader();
886 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
888 (*chan)->buf->get_read_vector (&vector);
890 total = vector.len[0] + vector.len[1];
892 if (total == 0 || (total < _chunk_frames && !force_flush && was_recording)) {
896 /* if there are 2+ chunks of disk i/o possible for
897 this track, let the caller know so that it can arrange
898 for us to be called again, ASAP.
900 if we are forcing a flush, then if there is* any* extra
901 work, let the caller know.
903 if we are no longer recording and there is any extra work,
904 let the caller know too.
907 if (total >= 2 * _chunk_frames || ((force_flush || !was_recording) && total > _chunk_frames)) {
911 to_write = min (_chunk_frames, (framecnt_t) vector.len[0]);
913 // check the transition buffer when recording destructive
914 // important that we get this after the capture buf
917 (*chan)->capture_transition_buf->get_read_vector(&transvec);
918 size_t transcount = transvec.len[0] + transvec.len[1];
921 for (ti=0; ti < transcount; ++ti) {
922 CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
924 if (captrans.type == CaptureStart) {
925 // by definition, the first data we got above represents the given capture pos
927 (*chan)->write_source->mark_capture_start (captrans.capture_val);
928 (*chan)->curr_capture_cnt = 0;
930 } else if (captrans.type == CaptureEnd) {
932 // capture end, the capture_val represents total frames in capture
934 if (captrans.capture_val <= (*chan)->curr_capture_cnt + to_write) {
936 // shorten to make the write a perfect fit
937 uint32_t nto_write = (captrans.capture_val - (*chan)->curr_capture_cnt);
939 if (nto_write < to_write) {
940 ret = 1; // should we?
942 to_write = nto_write;
944 (*chan)->write_source->mark_capture_end ();
946 // increment past this transition, but go no further
951 // actually ends just beyond this chunk, so force more work
959 (*chan)->capture_transition_buf->increment_read_ptr(ti);
963 if ((!(*chan)->write_source) || (*chan)->write_source->write (vector.buf[0], to_write) != to_write) {
964 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
968 (*chan)->buf->increment_read_ptr (to_write);
969 (*chan)->curr_capture_cnt += to_write;
971 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < _chunk_frames) && !destructive()) {
973 /* we wrote all of vector.len[0] but it wasn't an entire
974 disk_write_chunk_frames of data, so arrange for some part
975 of vector.len[1] to be flushed to disk as well.
978 to_write = min ((framecnt_t)(_chunk_frames - to_write), (framecnt_t) vector.len[1]);
980 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 additional write of %2\n", name(), to_write));
982 if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) {
983 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
987 (*chan)->buf->increment_read_ptr (to_write);
988 (*chan)->curr_capture_cnt += to_write;
994 if (_midi_write_source) {
996 const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
999 _midi_buf->read_space() == 0 ||
1000 (!force_flush && (total < _chunk_frames) && was_recording)) {
1004 /* if there are 2+ chunks of disk i/o possible for
1005 this track), let the caller know so that it can arrange
1006 for us to be called again, ASAP.
1008 if we are forcing a flush, then if there is* any* extra
1009 work, let the caller know.
1011 if we are no longer recording and there is any extra work,
1012 let the caller know too.
1015 if (total >= 2 * _chunk_frames || ((force_flush || !was_recording) && total > _chunk_frames)) {
1020 /* push out everything we have, right now */
1021 to_write = UINT32_MAX;
1023 to_write = _chunk_frames;
1026 if (record_enabled() && ((total > _chunk_frames) || force_flush)) {
1027 Source::Lock lm(_midi_write_source->mutex());
1028 if (_midi_write_source->midi_write (lm, *_midi_buf, get_capture_start_frame (0), to_write) != to_write) {
1029 error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
1032 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
1042 DiskWriter::reset_write_sources (bool mark_write_complete, bool /*force*/)
1044 ChannelList::iterator chan;
1045 boost::shared_ptr<ChannelList> c = channels.reader();
1048 if (!_session.writable() || !recordable()) {
1052 capturing_sources.clear ();
1054 for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
1056 if (!destructive()) {
1058 if ((*chan)->write_source) {
1060 if (mark_write_complete) {
1061 Source::Lock lock((*chan)->write_source->mutex());
1062 (*chan)->write_source->mark_streaming_write_completed (lock);
1063 (*chan)->write_source->done_with_peakfile_writes ();
1066 if ((*chan)->write_source->removable()) {
1067 (*chan)->write_source->mark_for_remove ();
1068 (*chan)->write_source->drop_references ();
1071 (*chan)->write_source.reset ();
1074 use_new_write_source (DataType::AUDIO, n);
1076 if (record_enabled()) {
1077 capturing_sources.push_back ((*chan)->write_source);
1082 if ((*chan)->write_source == 0) {
1083 use_new_write_source (DataType::AUDIO, n);
1088 if (_midi_write_source) {
1089 if (mark_write_complete) {
1090 Source::Lock lm(_midi_write_source->mutex());
1091 _midi_write_source->mark_streaming_write_completed (lm);
1095 if (_playlists[DataType::MIDI]) {
1096 use_new_write_source (DataType::MIDI);
1099 if (destructive() && !c->empty ()) {
1101 /* we now have all our write sources set up, so create the
1102 playlist's single region.
1105 if (_playlists[DataType::MIDI]->empty()) {
1106 setup_destructive_playlist ();
1112 DiskWriter::use_new_write_source (DataType dt, uint32_t n)
1114 if (dt == DataType::MIDI) {
1116 _accumulated_capture_offset = 0;
1117 _midi_write_source.reset();
1120 _midi_write_source = boost::dynamic_pointer_cast<SMFSource>(
1121 _session.create_midi_source_for_session (write_source_name ()));
1123 if (!_midi_write_source) {
1124 throw failed_constructor();
1128 catch (failed_constructor &err) {
1129 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1130 _midi_write_source.reset();
1134 boost::shared_ptr<ChannelList> c = channels.reader();
1136 if (!recordable()) {
1140 if (n >= c->size()) {
1141 error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg;
1145 ChannelInfo* chan = (*c)[n];
1148 if ((chan->write_source = _session.create_audio_source_for_session (
1149 c->size(), write_source_name(), n, destructive())) == 0) {
1150 throw failed_constructor();
1154 catch (failed_constructor &err) {
1155 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1156 chan->write_source.reset ();
1160 /* do not remove destructive files even if they are empty */
1162 chan->write_source->set_allow_remove_if_empty (!destructive());
1169 DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abort_capture)
1171 bool more_work = true;
1173 framecnt_t total_capture;
1174 SourceList audio_srcs;
1175 SourceList midi_srcs;
1176 ChannelList::iterator chan;
1177 vector<CaptureInfo*>::iterator ci;
1178 boost::shared_ptr<ChannelList> c = channels.reader();
1180 bool mark_write_completed = false;
1185 /* butler is already stopped, but there may be work to do
1186 to flush remaining data to disk.
1189 while (more_work && !err) {
1190 switch (do_flush (TransportContext, true)) {
1197 error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1202 /* XXX is there anything we can do if err != 0 ? */
1203 Glib::Threads::Mutex::Lock lm (capture_info_lock);
1205 if (capture_info.empty()) {
1209 if (abort_capture) {
1211 if (destructive()) {
1215 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1217 if ((*chan)->write_source) {
1219 (*chan)->write_source->mark_for_remove ();
1220 (*chan)->write_source->drop_references ();
1221 (*chan)->write_source.reset ();
1224 /* new source set up in "out" below */
1227 if (_midi_write_source) {
1228 _midi_write_source->mark_for_remove ();
1229 _midi_write_source->drop_references ();
1230 _midi_write_source.reset();
1236 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1237 total_capture += (*ci)->frames;
1240 /* figure out the name for this take */
1242 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1244 boost::shared_ptr<AudioFileSource> as = (*chan)->write_source;
1247 audio_srcs.push_back (as);
1248 as->update_header (capture_info.front()->start, when, twhen);
1249 as->set_captured_for (_name.val());
1250 as->mark_immutable ();
1252 if (Config->get_auto_analyse_audio()) {
1253 Analyser::queue_source_for_analysis (as, true);
1256 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("newly captured source %1 length %2\n", as->path(), as->length (0)));
1259 if (_midi_write_source) {
1260 midi_srcs.push_back (_midi_write_source);
1267 if (_midi_write_source) {
1269 if (_midi_write_source->length (capture_info.front()->start) == 0) {
1270 /* No data was recorded, so this capture will
1271 effectively be aborted; do the same as we
1272 do for an explicit abort.
1274 if (_midi_write_source) {
1275 _midi_write_source->mark_for_remove ();
1276 _midi_write_source->drop_references ();
1277 _midi_write_source.reset();
1283 /* phew, we have data */
1285 Source::Lock source_lock(_midi_write_source->mutex());
1287 /* figure out the name for this take */
1289 midi_srcs.push_back (_midi_write_source);
1291 _midi_write_source->set_timeline_position (capture_info.front()->start);
1292 _midi_write_source->set_captured_for (_name);
1294 /* set length in beats to entire capture length */
1296 BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
1297 const Evoral::Beats total_capture_beats = converter.from (total_capture);
1298 _midi_write_source->set_length_beats (total_capture_beats);
1300 /* flush to disk: this step differs from the audio path,
1301 where all the data is already on disk.
1304 _midi_write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
1307 _last_capture_sources.insert (_last_capture_sources.end(), audio_srcs.begin(), audio_srcs.end());
1308 _last_capture_sources.insert (_last_capture_sources.end(), midi_srcs.begin(), midi_srcs.end());
1312 _route->use_captured_sources (audio_srcs, capture_info);
1313 _route->use_captured_sources (midi_srcs, capture_info);
1316 mark_write_completed = true;
1319 reset_write_sources (mark_write_completed);
1323 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1327 capture_info.clear ();
1328 capture_start_frame = 0;
1332 DiskWriter::transport_looped (framepos_t transport_frame)
1334 if (was_recording) {
1335 // all we need to do is finish this capture, with modified capture length
1336 boost::shared_ptr<ChannelList> c = channels.reader();
1340 // the next region will start recording via the normal mechanism
1341 // we'll set the start position to the current transport pos
1342 // no latency adjustment or capture offset needs to be made, as that already happened the first time
1343 capture_start_frame = transport_frame;
1344 first_recordable_frame = transport_frame; // mild lie
1345 last_recordable_frame = max_framepos;
1346 was_recording = true;
1348 if (recordable() && destructive()) {
1349 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1351 RingBufferNPT<CaptureTransition>::rw_vector transvec;
1352 (*chan)->capture_transition_buf->get_write_vector(&transvec);
1354 if (transvec.len[0] > 0) {
1355 transvec.buf[0]->type = CaptureStart;
1356 transvec.buf[0]->capture_val = capture_start_frame;
1357 (*chan)->capture_transition_buf->increment_write_ptr(1);
1361 fatal << X_("programming error: capture_transition_buf is full on rec loop! inconceivable!")
1369 /* Here we only keep track of the number of captured loops so monotonic
1370 event times can be delivered to the write source in process(). Trying
1371 to be clever here is a world of trouble, it is better to simply record
1372 the input in a straightforward non-destructive way. In the future when
1373 we want to implement more clever MIDI looping modes it should be done in
1374 the Source and/or entirely after the capture is finished.
1376 if (was_recording) {
1377 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1382 DiskWriter::setup_destructive_playlist ()
1385 boost::shared_ptr<ChannelList> c = channels.reader();
1387 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1388 srcs.push_back ((*chan)->write_source);
1391 /* a single full-sized region */
1393 assert (!srcs.empty ());
1396 plist.add (Properties::name, _name.val());
1397 plist.add (Properties::start, 0);
1398 plist.add (Properties::length, max_framepos - srcs.front()->natural_position());
1400 boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist));
1401 _playlists[DataType::AUDIO]->add_region (region, srcs.front()->natural_position());
1403 /* apply region properties and update write sources */
1404 use_destructive_playlist();
1408 DiskWriter::use_destructive_playlist ()
1410 /* this is called from the XML-based constructor or ::set_destructive. when called,
1411 we already have a playlist and a region, but we need to
1412 set up our sources for write. we use the sources associated
1413 with the (presumed single, full-extent) region.
1416 boost::shared_ptr<Region> rp;
1418 const RegionList& rl (_playlists[DataType::AUDIO]->region_list_property().rlist());
1419 if (rl.size() > 0) {
1420 /* this can happen when dragging a region onto a tape track */
1421 assert((rl.size() == 1));
1427 reset_write_sources (false, true);
1431 boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (rp);
1434 throw failed_constructor();
1437 /* be sure to stretch the region out to the maximum length (non-musical)*/
1439 region->set_length (max_framepos - region->position(), 0);
1442 ChannelList::iterator chan;
1443 boost::shared_ptr<ChannelList> c = channels.reader();
1445 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1446 (*chan)->write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
1447 assert((*chan)->write_source);
1448 (*chan)->write_source->set_allow_remove_if_empty (false);
1450 /* this might be false if we switched modes, so force it */
1452 #ifdef XXX_OLD_DESTRUCTIVE_API_XXX
1453 (*chan)->write_source->set_destructive (true);
1455 // should be set when creating the source or loading the state
1456 assert ((*chan)->write_source->destructive());
1460 /* the source list will never be reset for a destructive track */
1464 DiskWriter::adjust_buffering ()
1466 boost::shared_ptr<ChannelList> c = channels.reader();
1468 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1469 (*chan)->resize (_session.butler()->audio_diskstream_capture_buffer_size());
1474 DiskWriter::realtime_handle_transport_stopped ()
1476 realtime_speed_change ();
1480 DiskWriter::set_name (string const & str)
1482 string my_name = X_("writer:");
1485 if (_name != my_name) {
1486 SessionObject::set_name (my_name);
1493 DiskWriter::steal_write_source_name ()
1495 if (_playlists[DataType::MIDI]) {
1496 string our_old_name = _midi_write_source->name();
1498 /* this will bump the name of the current write source to the next one
1499 * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1500 * current write source name (e.g. "MIDI 1-1" available). See the
1501 * comments in Session::create_midi_source_by_stealing_name() about why
1506 string new_path = _session.new_midi_source_path (name());
1508 if (_midi_write_source->rename (new_path)) {
1515 return our_old_name;
1518 return std::string();
1522 DiskWriter::configure_io (ChanCount in, ChanCount out)
1524 if (!DiskIOProcessor::configure_io (in, out)) {
1528 reset_write_sources (false, true);