2 Copyright (C) 2000-2003 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.
34 #include <pbd/error.h>
35 #include <pbd/basename.h>
36 #include <pbd/lockmonitor.h>
37 #include <pbd/xml++.h>
39 #include <ardour/ardour.h>
40 #include <ardour/audioengine.h>
41 #include <ardour/diskstream.h>
42 #include <ardour/utils.h>
43 #include <ardour/configuration.h>
44 #include <ardour/filesource.h>
45 #include <ardour/destructive_filesource.h>
46 #include <ardour/send.h>
47 #include <ardour/audioplaylist.h>
48 #include <ardour/cycle_timer.h>
49 #include <ardour/audioregion.h>
55 using namespace ARDOUR;
57 jack_nframes_t DiskStream::disk_io_chunk_frames;
59 sigc::signal<void,DiskStream*> DiskStream::DiskStreamCreated;
60 sigc::signal<void,DiskStream*> DiskStream::CannotRecordNoInput;
61 sigc::signal<void,list<Source*>*> DiskStream::DeleteSources;
62 sigc::signal<void> DiskStream::DiskOverrun;
63 sigc::signal<void> DiskStream::DiskUnderrun;
65 DiskStream::DiskStream (Session &sess, const string &name, Flag flag)
69 /* prevent any write sources from being created */
76 DiskStreamCreated (this); /* EMIT SIGNAL */
79 DiskStream::DiskStream (Session& sess, const XMLNode& node)
86 if (set_state (node)) {
88 throw failed_constructor();
93 DiskStreamCreated (this); /* EMIT SIGNAL */
97 DiskStream::init_channel (ChannelInfo &chan)
99 chan.playback_wrap_buffer = 0;
100 chan.capture_wrap_buffer = 0;
101 chan.speed_buffer = 0;
102 chan.peak_power = 0.0f;
103 chan.write_source = 0;
105 chan.current_capture_buffer = 0;
106 chan.current_playback_buffer = 0;
108 chan.playback_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
109 chan.capture_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
111 /* touch the ringbuffer buffers, which will cause
112 them to be mapped into locked physical RAM if
113 we're running with mlockall(). this doesn't do
116 memset (chan.playback_buf->buffer(), 0, sizeof (Sample) * chan.playback_buf->bufsize());
117 memset (chan.capture_buf->buffer(), 0, sizeof (Sample) * chan.capture_buf->bufsize());
122 DiskStream::init (Flag f)
128 _alignment_style = ExistingMaterial;
129 _persistent_alignment_style = ExistingMaterial;
130 first_input_change = true;
132 i_am_the_modifier = 0;
133 atomic_set (&_record_enabled, 0);
134 was_recording = false;
135 capture_start_frame = 0;
136 capture_captured = 0;
137 _visible_speed = 1.0f;
138 _actual_speed = 1.0f;
139 _buffer_reallocation_required = false;
140 _seek_required = false;
141 first_recordable_frame = max_frames;
142 last_recordable_frame = max_frames;
147 adjust_capture_position = 0;
148 last_possibly_recording = 0;
150 wrap_buffer_size = 0;
151 speed_buffer_size = 0;
153 phi = (uint64_t) (0x1000000);
156 playback_distance = 0;
157 _read_data_count = 0;
158 _write_data_count = 0;
159 deprecated_io_node = 0;
161 /* there are no channels at this point, so these
162 two calls just get speed_buffer_size and wrap_buffer
163 size setup without duplicating their code.
166 set_block_size (_session.get_block_size());
167 allocate_temporary_buffers ();
169 pending_overwrite = false;
171 overwrite_queued = false;
172 input_change_pending = NoChange;
179 DiskStream::destroy_channel (ChannelInfo &chan)
181 if (chan.write_source) {
182 chan.write_source->release ();
183 chan.write_source = 0;
186 if (chan.speed_buffer) {
187 delete [] chan.speed_buffer;
190 if (chan.playback_wrap_buffer) {
191 delete [] chan.playback_wrap_buffer;
193 if (chan.capture_wrap_buffer) {
194 delete [] chan.capture_wrap_buffer;
197 delete chan.playback_buf;
198 delete chan.capture_buf;
200 chan.playback_buf = 0;
201 chan.capture_buf = 0;
204 DiskStream::~DiskStream ()
206 LockMonitor lm (state_lock, __LINE__, __FILE__);
212 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
213 destroy_channel((*chan));
220 DiskStream::handle_input_change (IOChange change, void *src)
222 LockMonitor lm (state_lock, __LINE__, __FILE__);
224 if (!(input_change_pending & change)) {
225 input_change_pending = IOChange (input_change_pending|change);
226 _session.request_input_change_handling ();
231 DiskStream::non_realtime_input_change ()
234 LockMonitor lm (state_lock, __LINE__, __FILE__);
236 if (input_change_pending == NoChange) {
240 if (input_change_pending & ConfigurationChanged) {
242 if (_io->n_inputs() > _n_channels) {
244 // we need to add new channel infos
246 int diff = _io->n_inputs() - channels.size();
248 for (int i = 0; i < diff; ++i) {
252 } else if (_io->n_inputs() < _n_channels) {
254 // we need to get rid of channels
256 int diff = channels.size() - _io->n_inputs();
258 for (int i = 0; i < diff; ++i) {
264 get_input_sources ();
265 set_capture_offset ();
267 if (first_input_change) {
268 set_align_style (_persistent_alignment_style);
269 first_input_change = false;
271 set_align_style_from_io ();
274 input_change_pending = NoChange;
277 /* reset capture files */
279 reset_write_sources (false);
281 /* now refill channel buffers */
283 if (speed() != 1.0f || speed() != -1.0f) {
284 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()));
287 seek (_session.transport_frame());
292 DiskStream::get_input_sources ()
294 uint32_t ni = _io->n_inputs();
296 for (uint32_t n = 0; n < ni; ++n) {
298 const char **connections = _io->input(n)->get_connections ();
299 ChannelInfo& chan = channels[n];
301 if (connections == 0 || connections[0] == 0) {
304 // _source->disable_metering ();
310 chan.source = _session.engine().get_port_by_name (connections[0]);
320 DiskStream::find_and_use_playlist (const string& name)
323 AudioPlaylist* playlist;
325 if ((pl = _session.get_playlist (name)) == 0) {
326 error << string_compose(_("DiskStream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg;
330 if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
331 error << string_compose(_("DiskStream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
335 return use_playlist (playlist);
339 DiskStream::use_playlist (AudioPlaylist* playlist)
342 LockMonitor lm (state_lock, __LINE__, __FILE__);
344 if (playlist == _playlist) {
348 plstate_connection.disconnect();
349 plmod_connection.disconnect ();
350 plgone_connection.disconnect ();
356 _playlist = playlist;
359 if (!in_set_state && recordable()) {
360 reset_write_sources (false);
363 plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &DiskStream::playlist_changed));
364 plmod_connection = _playlist->Modified.connect (mem_fun (*this, &DiskStream::playlist_modified));
365 plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &DiskStream::playlist_deleted));
368 if (!overwrite_queued) {
369 _session.request_overwrite_buffer (this);
370 overwrite_queued = true;
373 PlaylistChanged (); /* EMIT SIGNAL */
374 _session.set_dirty ();
380 DiskStream::playlist_deleted (Playlist* pl)
382 /* this catches an ordering issue with session destruction. playlists
383 are destroyed before diskstreams. we have to invalidate any handles
384 we have to the playlist.
391 DiskStream::use_new_playlist ()
394 AudioPlaylist* playlist;
397 newname = Playlist::bump_name (_playlist->name(), _session);
399 newname = Playlist::bump_name (_name, _session);
402 if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) {
403 playlist->set_orig_diskstream_id (id());
404 return use_playlist (playlist);
411 DiskStream::use_copy_playlist ()
413 if (_playlist == 0) {
414 error << string_compose(_("DiskStream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
419 AudioPlaylist* playlist;
421 newname = Playlist::bump_name (_playlist->name(), _session);
423 if ((playlist = new AudioPlaylist (*_playlist, newname)) != 0) {
424 playlist->set_orig_diskstream_id (id());
425 return use_playlist (playlist);
432 DiskStream::set_io (IO& io)
435 set_align_style_from_io ();
439 DiskStream::set_name (string str, void *src)
442 _playlist->set_name (str);
445 if (!in_set_state && recordable()) {
447 /* open new capture files so that they have the correct name */
449 reset_write_sources (false);
455 DiskStream::set_speed (double sp)
457 _session.request_diskstream_speed (*this, sp);
459 /* to force a rebuffering at the right place */
464 DiskStream::realtime_set_speed (double sp, bool global)
466 bool changed = false;
467 double new_speed = sp * _session.transport_speed();
469 if (_visible_speed != sp) {
474 if (new_speed != _actual_speed) {
476 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() *
477 fabs (new_speed)) + 1;
479 if (required_wrap_size > wrap_buffer_size) {
480 _buffer_reallocation_required = true;
483 _actual_speed = new_speed;
484 phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
489 _seek_required = true;
491 speed_changed (); /* EMIT SIGNAL */
494 return _buffer_reallocation_required || _seek_required;
498 DiskStream::non_realtime_set_speed ()
500 if (_buffer_reallocation_required)
502 LockMonitor lm (state_lock, __LINE__, __FILE__);
503 allocate_temporary_buffers ();
505 _buffer_reallocation_required = false;
508 if (_seek_required) {
509 if (speed() != 1.0f || speed() != -1.0f) {
510 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
513 seek (_session.transport_frame(), true);
516 _seek_required = false;
521 DiskStream::prepare ()
524 playback_distance = 0;
528 DiskStream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
530 int possibly_recording;
533 const int transport_rolling = 0x4;
534 const int track_rec_enabled = 0x2;
535 const int global_rec_enabled = 0x1;
537 /* merge together the 3 factors that affect record status, and compute
541 rolling = _session.transport_speed() != 0.0f;
542 possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
543 change = possibly_recording ^ last_possibly_recording;
545 if (possibly_recording == last_possibly_recording) {
551 /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
553 if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) ||
554 ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
556 /* starting to record: compute first+last frames */
558 first_recordable_frame = transport_frame + _capture_offset;
559 last_recordable_frame = max_frames;
560 capture_start_frame = transport_frame;
562 if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) {
564 /* was stopped, now rolling (and recording) */
566 if (_alignment_style == ExistingMaterial) {
567 first_recordable_frame += _session.worst_output_latency();
569 first_recordable_frame += _roll_delay;
574 /* was rolling, but record state changed */
576 if (_alignment_style == ExistingMaterial) {
579 if (!_session.get_punch_in()) {
581 /* manual punch in happens at the correct transport frame
582 because the user hit a button. but to get alignment correct
583 we have to back up the position of the new region to the
584 appropriate spot given the roll delay.
587 capture_start_frame -= _roll_delay;
589 /* XXX paul notes (august 2005): i don't know why
593 first_recordable_frame += _capture_offset;
597 /* autopunch toggles recording at the precise
598 transport frame, and then the DS waits
599 to start recording for a time that depends
600 on the output latency.
603 first_recordable_frame += _session.worst_output_latency();
608 if (_session.get_punch_in()) {
609 first_recordable_frame += _roll_delay;
611 capture_start_frame -= _roll_delay;
617 if (_flags & Recordable) {
618 cerr << "START RECORD @ " << capture_start_frame << " = " << capture_start_frame * sizeof (Sample) << endl;
619 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
620 (*chan).write_source->mark_capture_start (capture_start_frame);
624 } else if (!record_enabled() || !can_record) {
628 last_recordable_frame = transport_frame + _capture_offset;
630 if (_alignment_style == ExistingMaterial) {
631 last_recordable_frame += _session.worst_output_latency();
633 last_recordable_frame += _roll_delay;
637 last_possibly_recording = possibly_recording;
641 DiskStream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input)
644 ChannelList::iterator c;
646 jack_nframes_t rec_offset = 0;
647 jack_nframes_t rec_nframes = 0;
648 bool nominally_recording;
649 bool re = record_enabled ();
650 bool collect_playback = false;
652 /* if we've already processed the frames corresponding to this call,
653 just return. this allows multiple routes that are taking input
654 from this diskstream to call our ::process() method, but have
655 this stuff only happen once. more commonly, it allows both
656 the AudioTrack that is using this DiskStream *and* the Session
657 to call process() without problems.
664 check_record_status (transport_frame, nframes, can_record);
666 nominally_recording = (can_record && re);
673 /* This lock is held until the end of DiskStream::commit, so these two functions
674 must always be called as a pair. The only exception is if this function
675 returns a non-zero value, in which case, ::commit should not be called.
678 if (pthread_mutex_trylock (state_lock.mutex())) {
682 adjust_capture_position = 0;
684 for (c = channels.begin(); c != channels.end(); ++c) {
685 (*c).current_capture_buffer = 0;
686 (*c).current_playback_buffer = 0;
689 if (nominally_recording || (_session.get_record_enabled() && _session.get_punch_in())) {
692 ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
699 case OverlapInternal:
700 /* ---------- recrange
703 rec_nframes = nframes;
708 /* |--------| recrange
711 rec_nframes = transport_frame + nframes - first_recordable_frame;
713 rec_offset = first_recordable_frame - transport_frame;
718 /* |--------| recrange
721 rec_nframes = last_recordable_frame - transport_frame;
725 case OverlapExternal:
726 /* |--------| recrange
727 -------------- transrange
729 rec_nframes = last_recordable_frame - last_recordable_frame;
730 rec_offset = first_recordable_frame - transport_frame;
734 if (rec_nframes && !was_recording) {
735 capture_captured = 0;
736 was_recording = true;
741 if (can_record && !_last_capture_regions.empty()) {
742 _last_capture_regions.clear ();
745 if (nominally_recording || rec_nframes) {
747 for (n = 0, c = channels.begin(); c != channels.end(); ++c, ++n) {
749 ChannelInfo& chan (*c);
751 chan.capture_buf->get_write_vector (&chan.capture_vector);
753 if (rec_nframes <= chan.capture_vector.len[0]) {
755 chan.current_capture_buffer = chan.capture_vector.buf[0];
757 /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use
761 memcpy (chan.current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes);
765 jack_nframes_t total = chan.capture_vector.len[0] + chan.capture_vector.len[1];
767 if (rec_nframes > total) {
772 Sample* buf = _io->input (n)->get_buffer (nframes) + offset;
773 jack_nframes_t first = chan.capture_vector.len[0];
775 memcpy (chan.capture_wrap_buffer, buf, sizeof (Sample) * first);
776 memcpy (chan.capture_vector.buf[0], buf, sizeof (Sample) * first);
777 memcpy (chan.capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first));
778 memcpy (chan.capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first));
780 chan.current_capture_buffer = chan.capture_wrap_buffer;
787 finish_capture (rec_monitors_input);
794 /* data will be written to disk */
796 if (rec_nframes == nframes && rec_offset == 0) {
798 for (c = channels.begin(); c != channels.end(); ++c) {
799 (*c).current_playback_buffer = (*c).current_capture_buffer;
802 playback_distance = nframes;
807 /* we can't use the capture buffer as the playback buffer, because
808 we recorded only a part of the current process' cycle data
812 collect_playback = true;
815 adjust_capture_position = rec_nframes;
817 } else if (nominally_recording) {
819 /* can't do actual capture yet - waiting for latency effects to finish before we start*/
821 for (c = channels.begin(); c != channels.end(); ++c) {
822 (*c).current_playback_buffer = (*c).current_capture_buffer;
825 playback_distance = nframes;
829 collect_playback = true;
832 if (collect_playback) {
834 /* we're doing playback */
836 jack_nframes_t necessary_samples;
838 /* no varispeed playback if we're recording, because the output .... TBD */
840 if (rec_nframes == 0 && _actual_speed != 1.0f) {
841 necessary_samples = (jack_nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
843 necessary_samples = nframes;
846 for (c = channels.begin(); c != channels.end(); ++c) {
847 (*c).playback_buf->get_read_vector (&(*c).playback_vector);
852 for (c = channels.begin(); c != channels.end(); ++c, ++n) {
854 ChannelInfo& chan (*c);
856 if (necessary_samples <= chan.playback_vector.len[0]) {
858 chan.current_playback_buffer = chan.playback_vector.buf[0];
861 jack_nframes_t total = chan.playback_vector.len[0] + chan.playback_vector.len[1];
863 if (necessary_samples > total) {
869 memcpy ((char *) chan.playback_wrap_buffer, chan.playback_vector.buf[0],
870 chan.playback_vector.len[0] * sizeof (Sample));
871 memcpy (chan.playback_wrap_buffer + chan.playback_vector.len[0], chan.playback_vector.buf[1],
872 (necessary_samples - chan.playback_vector.len[0]) * sizeof (Sample));
874 chan.current_playback_buffer = chan.playback_wrap_buffer;
879 if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
881 uint64_t phase = last_phase;
882 jack_nframes_t i = 0;
884 // Linearly interpolate into the alt buffer
885 // using 40.24 fixp maths (swh)
887 for (c = channels.begin(); c != channels.end(); ++c) {
890 ChannelInfo& chan (*c);
895 for (jack_nframes_t outsample = 0; outsample < nframes; ++outsample) {
897 fr = (phase & 0xFFFFFF) / 16777216.0f;
898 chan.speed_buffer[outsample] =
899 chan.current_playback_buffer[i] * (1.0f - fr) +
900 chan.current_playback_buffer[i+1] * fr;
904 chan.current_playback_buffer = chan.speed_buffer;
907 playback_distance = i + 1;
908 last_phase = (phase & 0xFFFFFF);
911 playback_distance = nframes;
923 /* we're exiting with failure, so ::commit will not
924 be called. unlock the state lock.
927 pthread_mutex_unlock (state_lock.mutex());
934 DiskStream::recover ()
936 pthread_mutex_unlock (state_lock.mutex());
941 DiskStream::commit (jack_nframes_t nframes)
943 bool need_butler = false;
945 if (_actual_speed < 0.0) {
946 playback_sample -= playback_distance;
948 playback_sample += playback_distance;
951 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
953 (*chan).playback_buf->increment_read_ptr (playback_distance);
955 if (adjust_capture_position) {
956 (*chan).capture_buf->increment_write_ptr (adjust_capture_position);
960 if (adjust_capture_position != 0) {
961 capture_captured += adjust_capture_position;
962 adjust_capture_position = 0;
966 need_butler = channels[0].playback_buf->write_space() >= channels[0].playback_buf->bufsize() / 2;
968 need_butler = channels[0].playback_buf->write_space() >= disk_io_chunk_frames
969 || channels[0].capture_buf->read_space() >= disk_io_chunk_frames;
972 pthread_mutex_unlock (state_lock.mutex());
980 DiskStream::set_pending_overwrite (bool yn)
982 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
984 pending_overwrite = yn;
986 overwrite_frame = playback_sample;
987 overwrite_offset = channels.front().playback_buf->get_read_ptr();
991 DiskStream::overwrite_existing_buffers ()
993 Sample* mixdown_buffer;
996 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
998 overwrite_queued = false;
1000 /* assume all are the same size */
1001 jack_nframes_t size = channels[0].playback_buf->bufsize();
1003 mixdown_buffer = new Sample[size];
1004 gain_buffer = new float[size];
1006 /* reduce size so that we can fill the buffer correctly. */
1010 jack_nframes_t start;
1012 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1014 start = overwrite_frame;
1015 jack_nframes_t cnt = size;
1017 /* to fill the buffer without resetting the playback sample, we need to
1018 do it one or two chunks (normally two).
1020 |----------------------------------------------------------------------|
1024 |<- second chunk->||<----------------- first chunk ------------------>|
1028 jack_nframes_t to_read = size - overwrite_offset;
1030 if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer,
1031 start, to_read, *chan, n, reversed)) {
1032 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1033 _id, size, playback_sample) << endmsg;
1037 if (cnt > to_read) {
1041 if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer,
1042 start, cnt, *chan, n, reversed)) {
1043 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1044 _id, size, playback_sample) << endmsg;
1053 pending_overwrite = false;
1054 delete [] gain_buffer;
1055 delete [] mixdown_buffer;
1060 DiskStream::seek (jack_nframes_t frame, bool complete_refill)
1062 LockMonitor lm (state_lock, __LINE__, __FILE__);
1065 ChannelList::iterator chan;
1067 for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1068 (*chan).playback_buf->reset ();
1069 (*chan).capture_buf->reset ();
1070 if ((*chan).write_source) {
1071 (*chan).write_source->seek (frame);
1075 playback_sample = frame;
1078 if (complete_refill) {
1079 while ((ret = do_refill (0, 0)) > 0);
1081 ret = do_refill (0, 0);
1088 DiskStream::can_internal_playback_seek (jack_nframes_t distance)
1090 ChannelList::iterator chan;
1092 for (chan = channels.begin(); chan != channels.end(); ++chan) {
1093 if ((*chan).playback_buf->read_space() < distance) {
1101 DiskStream::internal_playback_seek (jack_nframes_t distance)
1103 ChannelList::iterator chan;
1105 for (chan = channels.begin(); chan != channels.end(); ++chan) {
1106 (*chan).playback_buf->increment_read_ptr (distance);
1109 first_recordable_frame += distance;
1110 playback_sample += distance;
1116 DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, jack_nframes_t& start, jack_nframes_t cnt,
1118 ChannelInfo& channel_info, int channel, bool reversed)
1120 jack_nframes_t this_read = 0;
1121 bool reloop = false;
1122 jack_nframes_t loop_end = 0;
1123 jack_nframes_t loop_start = 0;
1124 jack_nframes_t loop_length = 0;
1125 jack_nframes_t offset = 0;
1129 /* Make the use of a Location atomic for this read operation.
1131 Note: Locations don't get deleted, so all we care about
1132 when I say "atomic" is that we are always pointing to
1133 the same one and using a start/length values obtained
1137 if ((loc = loop_location) != 0) {
1138 loop_start = loc->start();
1139 loop_end = loc->end();
1140 loop_length = loop_end - loop_start;
1143 /* if we are looping, ensure that the first frame we read is at the correct
1144 position within the loop.
1147 if (loc && start >= loop_end) {
1148 //cerr << "start adjusted from " << start;
1149 start = loop_start + ((start - loop_start) % loop_length);
1150 //cerr << "to " << start << endl;
1152 //cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
1157 /* take any loop into account. we can't read past the end of the loop. */
1159 if (loc && (loop_end - start < cnt)) {
1160 this_read = loop_end - start;
1161 //cerr << "reloop true: thisread: " << this_read << " cnt: " << cnt << endl;
1168 if (this_read == 0) {
1172 this_read = min(cnt,this_read);
1174 if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, start, this_read, channel) != this_read) {
1175 error << string_compose(_("DiskStream %1: cannot read %2 from playlist at frame %3"), _id, this_read,
1180 _read_data_count = _playlist->read_data_count();
1184 /* don't adjust start, since caller has already done that
1187 swap_by_ptr (buf, buf + this_read - 1);
1191 /* if we read to the end of the loop, go back to the beginning */
1201 offset += this_read;
1208 DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer)
1211 jack_nframes_t to_read;
1212 RingBufferNPT<Sample>::rw_vector vector;
1215 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1216 jack_nframes_t total_space;
1217 jack_nframes_t zero_fill;
1219 ChannelList::iterator i;
1222 channels.front().playback_buf->get_write_vector (&vector);
1224 if ((total_space = vector.len[0] + vector.len[1]) == 0) {
1228 /* if there are 2+ chunks of disk i/o possible for
1229 this track, let the caller know so that it can arrange
1230 for us to be called again, ASAP.
1233 if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) {
1237 /* if we're running close to normal speed and there isn't enough
1238 space to do disk_io_chunk_frames of I/O, then don't bother.
1240 at higher speeds, just do it because the sync between butler
1241 and audio thread may not be good enough.
1244 if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
1248 /* when slaved, don't try to get too close to the read pointer. this
1249 leaves space for the buffer reversal to have something useful to
1253 if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) {
1257 total_space = min (disk_io_chunk_frames, total_space);
1261 if (file_frame == 0) {
1263 /* at start: nothing to do but fill with silence */
1265 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1267 ChannelInfo& chan (*i);
1268 chan.playback_buf->get_write_vector (&vector);
1269 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1270 if (vector.len[1]) {
1271 memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1273 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1278 if (file_frame < total_space) {
1280 /* too close to the start: read what we can,
1281 and then zero fill the rest
1284 zero_fill = total_space - file_frame;
1285 total_space = file_frame;
1290 /* move read position backwards because we are going
1291 to reverse the data.
1294 file_frame -= total_space;
1300 if (file_frame == max_frames) {
1302 /* at end: nothing to do but fill with silence */
1304 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1306 ChannelInfo& chan (*i);
1307 chan.playback_buf->get_write_vector (&vector);
1308 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1309 if (vector.len[1]) {
1310 memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1312 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1317 if (file_frame > max_frames - total_space) {
1319 /* to close to the end: read what we can, and zero fill the rest */
1321 zero_fill = total_space - (max_frames - file_frame);
1322 total_space = max_frames - file_frame;
1329 /* Please note: the code to allocate buffers isn't run
1330 during normal butler thread operation. Its there
1331 for other times when we need to call do_refill()
1332 from somewhere other than the butler thread.
1335 if (mixdown_buffer == 0) {
1336 mixdown_buffer = new Sample[disk_io_chunk_frames];
1337 free_mixdown = true;
1339 free_mixdown = false;
1342 if (gain_buffer == 0) {
1343 gain_buffer = new float[disk_io_chunk_frames];
1349 jack_nframes_t file_frame_tmp = 0;
1351 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1353 ChannelInfo& chan (*i);
1356 jack_nframes_t len1, len2;
1358 chan.playback_buf->get_write_vector (&vector);
1361 file_frame_tmp = file_frame;
1364 buf1 = vector.buf[1];
1365 len1 = vector.len[1];
1366 buf2 = vector.buf[0];
1367 len2 = vector.len[0];
1369 buf1 = vector.buf[0];
1370 len1 = vector.len[0];
1371 buf2 = vector.buf[1];
1372 len2 = vector.len[1];
1376 to_read = min (ts, len1);
1377 to_read = min (to_read, disk_io_chunk_frames);
1381 if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1386 chan.playback_buf->increment_write_ptr (to_read);
1390 to_read = min (ts, len2);
1395 /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data,
1396 so read some or all of vector.len[1] as well.
1399 if (read (buf2, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1404 chan.playback_buf->increment_write_ptr (to_read);
1413 file_frame = file_frame_tmp;
1417 delete [] mixdown_buffer;
1420 delete [] gain_buffer;
1427 DiskStream::do_flush (bool force_flush)
1431 RingBufferNPT<Sample>::rw_vector vector;
1432 jack_nframes_t total;
1434 /* important note: this function will write *AT MOST*
1435 disk_io_chunk_frames of data to disk. it will never
1436 write more than that. if its writes that much and there
1437 is more than that waiting to be written, it will return 1,
1438 otherwise 0 on success or -1 on failure.
1440 if there is less than disk_io_chunk_frames to be written,
1441 no data will be written at all unless `force_flush' is true.
1444 _write_data_count = 0;
1446 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1448 (*chan).capture_buf->get_read_vector (&vector);
1450 total = vector.len[0] + vector.len[1];
1452 if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
1456 /* if there are 2+ chunks of disk i/o possible for
1457 this track, let the caller know so that it can arrange
1458 for us to be called again, ASAP.
1460 if we are forcing a flush, then if there is* any* extra
1461 work, let the caller know.
1463 if we are no longer recording and there is any extra work,
1464 let the caller know too.
1467 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
1471 to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
1473 if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write) != to_write) {
1474 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1478 (*chan).capture_buf->increment_read_ptr (to_write);
1480 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames)) {
1482 /* we wrote all of vector.len[0] but it wasn't an entire
1483 disk_io_chunk_frames of data, so arrange for some part
1484 of vector.len[1] to be flushed to disk as well.
1487 to_write = min ((jack_nframes_t)(disk_io_chunk_frames - to_write), (jack_nframes_t) vector.len[1]);
1489 if ((*chan).write_source->write (vector.buf[1], to_write) != to_write) {
1490 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1494 _write_data_count += (*chan).write_source->write_data_count();
1496 (*chan).capture_buf->increment_read_ptr (to_write);
1505 DiskStream::playlist_changed (Change ignored)
1507 playlist_modified ();
1511 DiskStream::playlist_modified ()
1513 if (!i_am_the_modifier && !overwrite_queued) {
1514 _session.request_overwrite_buffer (this);
1515 overwrite_queued = true;
1520 DiskStream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
1522 uint32_t buffer_position;
1523 bool more_work = true;
1525 AudioRegion* region = 0;
1526 jack_nframes_t total_capture;
1527 AudioRegion::SourceList srcs;
1528 AudioRegion::SourceList::iterator src;
1529 ChannelList::iterator chan;
1530 vector<CaptureInfo*>::iterator ci;
1532 list<Source*>* deletion_list;
1533 bool mark_write_completed = false;
1535 finish_capture (true);
1537 /* butler is already stopped, but there may be work to do
1538 to flush remaining data to disk.
1541 while (more_work && !err) {
1542 switch (do_flush (true)) {
1549 error << string_compose(_("DiskStream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1554 /* XXX is there anything we can do if err != 0 ? */
1555 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
1557 if (capture_info.empty()) {
1561 if (abort_capture) {
1563 ChannelList::iterator chan;
1565 deletion_list = new list<Source*>;
1567 for ( chan = channels.begin(); chan != channels.end(); ++chan) {
1569 if ((*chan).write_source) {
1571 (*chan).write_source->mark_for_remove ();
1572 (*chan).write_source->release ();
1574 deletion_list->push_back ((*chan).write_source);
1576 (*chan).write_source = 0;
1579 /* new source set up in "out" below */
1582 if (!deletion_list->empty()) {
1583 DeleteSources (deletion_list);
1585 delete deletion_list;
1591 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1592 total_capture += (*ci)->frames;
1595 /* figure out the name for this take */
1597 for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1599 Source* s = (*chan).write_source;
1607 if ((fsrc = dynamic_cast<FileSource *>(s)) != 0) {
1608 fsrc->update_header (capture_info.front()->start, when, twhen);
1611 s->set_captured_for (_name);
1616 /* Register a new region with the Session that
1617 describes the entire source. Do this first
1618 so that any sub-regions will obviously be
1619 children of this one (later!)
1623 region = new AudioRegion (srcs, channels[0].write_source->last_capture_start_frame(), total_capture,
1624 region_name_from_path (channels[0].write_source->name()),
1625 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
1627 region->special_set_position (capture_info.front()->start);
1630 catch (failed_constructor& err) {
1631 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1635 _last_capture_regions.push_back (region);
1637 // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
1639 _session.add_undo (_playlist->get_memento());
1640 _playlist->freeze ();
1642 for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1645 _session.region_name (region_name, _name, false);
1647 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1650 region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
1653 catch (failed_constructor& err) {
1654 error << _("DiskStream: could not create region for captured audio!") << endmsg;
1655 continue; /* XXX is this OK? */
1658 _last_capture_regions.push_back (region);
1660 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1662 i_am_the_modifier++;
1663 _playlist->add_region (*region, (*ci)->start);
1664 i_am_the_modifier--;
1666 buffer_position += (*ci)->frames;
1670 _session.add_redo_no_execute (_playlist->get_memento());
1672 mark_write_completed = true;
1674 reset_write_sources (mark_write_completed);
1677 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1681 capture_info.clear ();
1682 capture_start_frame = 0;
1686 DiskStream::finish_capture (bool rec_monitors_input)
1688 was_recording = false;
1690 if (_flags & Recordable) {
1691 cerr << "STOP CAPTURE\n";
1692 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1693 (*chan).write_source->mark_capture_end ();
1697 if (capture_captured == 0) {
1701 CaptureInfo* ci = new CaptureInfo;
1703 ci->start = capture_start_frame;
1704 ci->frames = capture_captured;
1706 /* XXX theoretical race condition here. Need atomic exchange ?
1707 However, the circumstances when this is called right
1708 now (either on record-disable or transport_stopped)
1709 mean that no actual race exists. I think ...
1710 We now have a capture_info_lock, but it is only to be used
1711 to synchronize in the transport_stop and the capture info
1712 accessors, so that invalidation will not occur (both non-realtime).
1715 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1717 capture_info.push_back (ci);
1718 capture_captured = 0;
1722 DiskStream::set_record_enabled (bool yn, void* src)
1724 bool rolling = _session.transport_speed() != 0.0f;
1726 if (!recordable() || !_session.record_enabling_legal()) {
1730 /* if we're turning on rec-enable, there needs to be an
1734 if (yn && channels[0].source == 0) {
1736 /* pick up connections not initiated *from* the IO object
1737 we're associated with.
1740 get_input_sources ();
1742 if (channels[0].source == 0) {
1745 CannotRecordNoInput (this); /* emit signal */
1751 /* yes, i know that this not proof against race conditions, but its
1752 good enough. i think.
1755 if (record_enabled() != yn) {
1757 atomic_set (&_record_enabled, 1);
1758 capturing_sources.clear ();
1759 if (Config->get_use_hardware_monitoring()) {
1760 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1761 if ((*chan).source) {
1762 (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
1764 capturing_sources.push_back ((*chan).write_source);
1767 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1768 capturing_sources.push_back ((*chan).write_source);
1773 atomic_set (&_record_enabled, 0);
1774 if (Config->get_use_hardware_monitoring()) {
1775 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1776 if ((*chan).source) {
1777 (*chan).source->request_monitor_input (false);
1781 capturing_sources.clear ();
1784 record_enable_changed (src); /* EMIT SIGNAL */
1789 DiskStream::get_state ()
1791 XMLNode* node = new XMLNode ("DiskStream");
1793 LocaleGuard lg (X_("POSIX"));
1795 if (destructive()) {
1796 node->add_property ("destructive", "true");
1799 snprintf (buf, sizeof(buf), "%zd", channels.size());
1800 node->add_property ("channels", buf);
1802 node->add_property ("playlist", _playlist->name());
1804 snprintf (buf, sizeof(buf), "%f", _visible_speed);
1805 node->add_property ("speed", buf);
1807 node->add_property("name", _name);
1808 snprintf (buf, sizeof(buf), "%" PRIu64, id());
1809 node->add_property("id", buf);
1811 if (!capturing_sources.empty() && _session.get_record_enabled()) {
1813 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1814 XMLNode* cs_grandchild;
1816 for (vector<FileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1817 cs_grandchild = new XMLNode (X_("file"));
1818 cs_grandchild->add_property (X_("path"), (*i)->path());
1819 cs_child->add_child_nocopy (*cs_grandchild);
1822 /* store the location where capture will start */
1826 if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1827 snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
1829 snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
1832 cs_child->add_property (X_("at"), buf);
1833 node->add_child_nocopy (*cs_child);
1837 node->add_child_copy (*_extra_xml);
1844 DiskStream::set_state (const XMLNode& node)
1846 const XMLProperty* prop;
1847 XMLNodeList nlist = node.children();
1848 XMLNodeIterator niter;
1849 uint32_t nchans = 1;
1850 XMLNode* capture_pending_node = 0;
1851 LocaleGuard lg (X_("POSIX"));
1853 in_set_state = true;
1855 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1856 if ((*niter)->name() == IO::state_node_name) {
1857 deprecated_io_node = new XMLNode (**niter);
1860 if ((*niter)->name() == X_("CapturingSources")) {
1861 capture_pending_node = *niter;
1865 /* prevent write sources from being created */
1867 in_set_state = true;
1869 if ((prop = node.property ("name")) != 0) {
1870 _name = prop->value();
1873 if ((prop = node.property ("destructive")) != 0) {
1874 if (prop->value() == "true") {
1875 _flags |= Destructive;
1879 if (deprecated_io_node) {
1880 if ((prop = deprecated_io_node->property ("id")) != 0) {
1881 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1884 if ((prop = node.property ("id")) != 0) {
1885 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1889 if ((prop = node.property ("channels")) != 0) {
1890 nchans = atoi (prop->value().c_str());
1893 // create necessary extra channels
1894 // we are always constructed with one
1895 // and we always need one
1897 if (nchans > _n_channels) {
1899 // we need to add new channel infos
1900 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1902 int diff = nchans - channels.size();
1904 for (int i=0; i < diff; ++i) {
1908 } else if (nchans < _n_channels) {
1910 // we need to get rid of channels
1911 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1913 int diff = channels.size() - nchans;
1915 for (int i = 0; i < diff; ++i) {
1920 if ((prop = node.property ("playlist")) == 0) {
1925 bool had_playlist = (_playlist != 0);
1927 if (find_and_use_playlist (prop->value())) {
1931 if (!had_playlist) {
1932 _playlist->set_orig_diskstream_id (_id);
1935 if (capture_pending_node) {
1936 use_pending_capture_data (*capture_pending_node);
1941 if ((prop = node.property ("speed")) != 0) {
1942 double sp = atof (prop->value().c_str());
1944 if (realtime_set_speed (sp, false)) {
1945 non_realtime_set_speed ();
1949 _n_channels = channels.size();
1951 in_set_state = false;
1953 /* now that we're all done with playlist+channel set up,
1954 go ahead and create write sources.
1958 capturing_sources.clear ();
1961 reset_write_sources (false);
1964 in_set_state = false;
1970 DiskStream::use_new_write_source (uint32_t n)
1972 if (!recordable()) {
1976 if (n >= channels.size()) {
1977 error << string_compose (_("DiskStream: channel %1 out of range"), n) << endmsg;
1981 ChannelInfo &chan = channels[n];
1983 if (chan.write_source) {
1985 if (FileSource::is_empty (chan.write_source->path())) {
1986 chan.write_source->mark_for_remove ();
1987 chan.write_source->release();
1988 delete chan.write_source;
1990 chan.write_source->release();
1991 chan.write_source = 0;
1996 if ((chan.write_source = _session.create_file_source (*this, n, destructive())) == 0) {
1997 throw failed_constructor();
2001 catch (failed_constructor &err) {
2002 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
2003 chan.write_source = 0;
2007 chan.write_source->use ();
2013 DiskStream::reset_write_sources (bool mark_write_complete, bool force)
2015 ChannelList::iterator chan;
2018 if (!recordable()) {
2022 if (!force && destructive()) {
2024 /* make sure we always have enough sources for the current channel count */
2026 for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2027 if ((*chan).write_source == 0) {
2032 if (chan == channels.end()) {
2036 /* some channels do not have a write source */
2039 capturing_sources.clear ();
2041 for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2042 if (mark_write_complete) {
2043 (*chan).write_source->mark_streaming_write_completed ();
2045 use_new_write_source (n);
2046 if (record_enabled()) {
2047 capturing_sources.push_back ((*chan).write_source);
2053 DiskStream::set_block_size (jack_nframes_t nframes)
2055 if (_session.get_block_size() > speed_buffer_size) {
2056 speed_buffer_size = _session.get_block_size();
2058 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2059 if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
2060 (*chan).speed_buffer = new Sample[speed_buffer_size];
2063 allocate_temporary_buffers ();
2067 DiskStream::allocate_temporary_buffers ()
2069 /* make sure the wrap buffer is at least large enough to deal
2070 with the speeds up to 1.2, to allow for micro-variation
2071 when slaving to MTC, SMPTE etc.
2074 double sp = max (fabsf (_actual_speed), 1.2f);
2075 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * sp) + 1;
2077 if (required_wrap_size > wrap_buffer_size) {
2079 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2080 if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
2081 (*chan).playback_wrap_buffer = new Sample[required_wrap_size];
2082 if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
2083 (*chan).capture_wrap_buffer = new Sample[required_wrap_size];
2086 wrap_buffer_size = required_wrap_size;
2091 DiskStream::monitor_input (bool yn)
2093 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2095 if ((*chan).source) {
2096 (*chan).source->request_monitor_input (yn);
2102 DiskStream::set_capture_offset ()
2105 /* can't capture, so forget it */
2109 _capture_offset = _io->input_latency();
2113 DiskStream::set_persistent_align_style (AlignStyle a)
2115 _persistent_alignment_style = a;
2119 DiskStream::set_align_style_from_io ()
2121 bool have_physical = false;
2127 get_input_sources ();
2129 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2130 if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
2131 have_physical = true;
2136 if (have_physical) {
2137 set_align_style (ExistingMaterial);
2139 set_align_style (CaptureTime);
2144 DiskStream::set_align_style (AlignStyle a)
2146 if (record_enabled() && _session.actively_recording()) {
2151 if (a != _alignment_style) {
2152 _alignment_style = a;
2153 AlignmentStyleChanged ();
2158 DiskStream::add_channel ()
2160 /* XXX need to take lock??? */
2164 init_channel (chan);
2166 chan.speed_buffer = new Sample[speed_buffer_size];
2167 chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
2168 chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
2170 channels.push_back (chan);
2172 _n_channels = channels.size();
2178 DiskStream::remove_channel ()
2180 if (channels.size() > 1) {
2181 /* XXX need to take lock??? */
2182 ChannelInfo & chan = channels.back();
2183 destroy_channel (chan);
2184 channels.pop_back();
2186 _n_channels = channels.size();
2194 DiskStream::playback_buffer_load () const
2196 return (float) ((double) channels.front().playback_buf->read_space()/
2197 (double) channels.front().playback_buf->bufsize());
2201 DiskStream::capture_buffer_load () const
2203 return (float) ((double) channels.front().capture_buf->write_space()/
2204 (double) channels.front().capture_buf->bufsize());
2208 DiskStream::set_loop (Location *location)
2211 if (location->start() >= location->end()) {
2212 error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
2217 loop_location = location;
2219 LoopSet (location); /* EMIT SIGNAL */
2224 DiskStream::get_capture_start_frame (uint32_t n)
2226 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2228 if (capture_info.size() > n) {
2229 return capture_info[n]->start;
2232 return capture_start_frame;
2237 DiskStream::get_captured_frames (uint32_t n)
2239 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2241 if (capture_info.size() > n) {
2242 return capture_info[n]->frames;
2245 return capture_captured;
2250 DiskStream::punch_in ()
2255 DiskStream::punch_out ()
2260 DiskStream::use_pending_capture_data (XMLNode& node)
2262 const XMLProperty* prop;
2263 XMLNodeList nlist = node.children();
2264 XMLNodeIterator niter;
2266 FileSource* first_fs = 0;
2267 AudioRegion::SourceList pending_sources;
2268 jack_nframes_t position;
2270 if ((prop = node.property (X_("at"))) == 0) {
2274 if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
2278 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2279 if ((*niter)->name() == X_("file")) {
2281 if ((prop = (*niter)->property (X_("path"))) == 0) {
2286 fs = new FileSource (prop->value(), _session.frame_rate(), true);
2289 catch (failed_constructor& err) {
2290 error << string_compose (_("%1: cannot restore pending capture source file %2"),
2291 _name, prop->value())
2296 pending_sources.push_back (fs);
2298 if (first_fs == 0) {
2302 fs->set_captured_for (_name);
2306 if (pending_sources.size() == 0) {
2307 /* nothing can be done */
2311 if (pending_sources.size() != _n_channels) {
2312 error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2317 AudioRegion* region;
2320 region = new AudioRegion (pending_sources, 0, first_fs->length(),
2321 region_name_from_path (first_fs->name()),
2322 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
2324 region->special_set_position (0);
2327 catch (failed_constructor& err) {
2328 error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
2336 region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
2339 catch (failed_constructor& err) {
2340 error << string_compose (_("%1: cannot create region from pending capture sources"),
2347 _playlist->add_region (*region, position);
2353 DiskStream::set_roll_delay (jack_nframes_t nframes)
2355 _roll_delay = nframes;
2359 DiskStream::set_destructive (bool yn)
2361 if (yn != destructive()) {
2362 reset_write_sources (true, true);
2364 _flags |= Destructive;
2366 _flags &= ~Destructive;