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/send.h>
46 #include <ardour/audioplaylist.h>
47 #include <ardour/cycle_timer.h>
48 #include <ardour/audioregion.h>
54 using namespace ARDOUR;
56 jack_nframes_t DiskStream::disk_io_chunk_frames;
58 sigc::signal<void,DiskStream*> DiskStream::DiskStreamCreated;
59 sigc::signal<void,DiskStream*> DiskStream::CannotRecordNoInput;
60 sigc::signal<void,list<Source*>*> DiskStream::DeleteSources;
61 sigc::signal<void> DiskStream::DiskOverrun;
62 sigc::signal<void> DiskStream::DiskUnderrun;
64 DiskStream::DiskStream (Session &sess, const string &name, Flag flag)
68 /* prevent any write sources from being created */
75 DiskStreamCreated (this); /* EMIT SIGNAL */
78 DiskStream::DiskStream (Session& sess, const XMLNode& node)
85 if (set_state (node)) {
87 throw failed_constructor();
92 DiskStreamCreated (this); /* EMIT SIGNAL */
96 DiskStream::init_channel (ChannelInfo &chan)
98 chan.playback_wrap_buffer = 0;
99 chan.capture_wrap_buffer = 0;
100 chan.speed_buffer = 0;
101 chan.peak_power = 0.0f;
102 chan.fades_source = 0;
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;
131 rec_monitoring_off_for_roll = false;
133 i_am_the_modifier = 0;
134 atomic_set (&_record_enabled, 0);
135 was_recording = false;
136 capture_start_frame = 0;
137 capture_captured = 0;
138 _visible_speed = 1.0f;
139 _actual_speed = 1.0f;
140 _buffer_reallocation_required = false;
141 _seek_required = false;
142 first_recordable_frame = max_frames;
143 last_recordable_frame = max_frames;
148 adjust_capture_position = 0;
149 last_possibly_recording = 0;
151 wrap_buffer_size = 0;
152 speed_buffer_size = 0;
154 phi = (uint64_t) (0x1000000);
157 playback_distance = 0;
158 _read_data_count = 0;
159 _write_data_count = 0;
160 deprecated_io_node = 0;
162 /* there are no channels at this point, so these
163 two calls just get speed_buffer_size and wrap_buffer
164 size setup without duplicating their code.
167 set_block_size (_session.get_block_size());
168 allocate_temporary_buffers ();
170 pending_overwrite = false;
172 overwrite_queued = false;
173 input_change_pending = NoChange;
180 DiskStream::destroy_channel (ChannelInfo &chan)
182 if (chan.write_source) {
183 chan.write_source->release ();
184 chan.write_source = 0;
187 if (chan.speed_buffer) {
188 delete [] chan.speed_buffer;
191 if (chan.playback_wrap_buffer) {
192 delete [] chan.playback_wrap_buffer;
194 if (chan.capture_wrap_buffer) {
195 delete [] chan.capture_wrap_buffer;
198 delete chan.playback_buf;
199 delete chan.capture_buf;
201 chan.playback_buf = 0;
202 chan.capture_buf = 0;
205 DiskStream::~DiskStream ()
207 LockMonitor lm (state_lock, __LINE__, __FILE__);
213 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
214 destroy_channel((*chan));
221 DiskStream::handle_input_change (IOChange change, void *src)
223 LockMonitor lm (state_lock, __LINE__, __FILE__);
225 if (!(input_change_pending & change)) {
226 input_change_pending = IOChange (input_change_pending|change);
227 _session.request_input_change_handling ();
232 DiskStream::non_realtime_input_change ()
235 LockMonitor lm (state_lock, __LINE__, __FILE__);
237 if (input_change_pending == NoChange) {
241 if (input_change_pending & ConfigurationChanged) {
243 if (_io->n_inputs() > _n_channels) {
245 // we need to add new channel infos
247 int diff = _io->n_inputs() - channels.size();
249 for (int i = 0; i < diff; ++i) {
253 } else if (_io->n_inputs() < _n_channels) {
255 // we need to get rid of channels
257 int diff = channels.size() - _io->n_inputs();
259 for (int i = 0; i < diff; ++i) {
265 get_input_sources ();
266 set_capture_offset ();
268 if (first_input_change) {
269 set_align_style (_persistent_alignment_style);
270 first_input_change = false;
272 set_align_style_from_io ();
275 input_change_pending = NoChange;
278 /* reset capture files */
280 reset_write_sources (false);
282 /* now refill channel buffers */
284 if (speed() != 1.0f || speed() != -1.0f) {
285 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()));
288 seek (_session.transport_frame());
293 DiskStream::get_input_sources ()
295 uint32_t ni = _io->n_inputs();
297 for (uint32_t n = 0; n < ni; ++n) {
299 const char **connections = _io->input(n)->get_connections ();
300 ChannelInfo& chan = channels[n];
302 if (connections == 0 || connections[0] == 0) {
305 // _source->disable_metering ();
311 chan.source = _session.engine().get_port_by_name (connections[0]);
321 DiskStream::find_and_use_playlist (const string& name)
324 AudioPlaylist* playlist;
326 if ((pl = _session.get_playlist (name)) == 0) {
327 error << string_compose(_("DiskStream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg;
331 if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
332 error << string_compose(_("DiskStream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
336 return use_playlist (playlist);
340 DiskStream::use_playlist (AudioPlaylist* playlist)
343 LockMonitor lm (state_lock, __LINE__, __FILE__);
345 if (playlist == _playlist) {
349 plstate_connection.disconnect();
350 plmod_connection.disconnect ();
351 plgone_connection.disconnect ();
357 _playlist = playlist;
360 if (!in_set_state && recordable()) {
361 reset_write_sources (false);
364 plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &DiskStream::playlist_changed));
365 plmod_connection = _playlist->Modified.connect (mem_fun (*this, &DiskStream::playlist_modified));
366 plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &DiskStream::playlist_deleted));
369 if (!overwrite_queued) {
370 _session.request_overwrite_buffer (this);
371 overwrite_queued = true;
374 PlaylistChanged (); /* EMIT SIGNAL */
375 _session.set_dirty ();
381 DiskStream::playlist_deleted (Playlist* pl)
383 /* this catches an ordering issue with session destruction. playlists
384 are destroyed before diskstreams. we have to invalidate any handles
385 we have to the playlist.
392 DiskStream::use_new_playlist ()
395 AudioPlaylist* playlist;
398 newname = Playlist::bump_name (_playlist->name(), _session);
400 newname = Playlist::bump_name (_name, _session);
403 if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) {
404 playlist->set_orig_diskstream_id (id());
405 return use_playlist (playlist);
412 DiskStream::use_copy_playlist ()
414 if (_playlist == 0) {
415 error << string_compose(_("DiskStream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
420 AudioPlaylist* playlist;
422 newname = Playlist::bump_name (_playlist->name(), _session);
424 if ((playlist = new AudioPlaylist (*_playlist, newname)) != 0) {
425 playlist->set_orig_diskstream_id (id());
426 return use_playlist (playlist);
433 DiskStream::set_io (IO& io)
436 set_align_style_from_io ();
440 DiskStream::set_name (string str, void *src)
443 _playlist->set_name (str);
446 if (!in_set_state && recordable()) {
448 /* open new capture files so that they have the correct name */
450 reset_write_sources (false);
456 DiskStream::set_speed (float sp)
458 _session.request_diskstream_speed (*this, sp);
460 /* to force a rebuffering at the right place */
465 DiskStream::realtime_set_speed (float sp, bool global)
467 bool changed = false;
468 float new_speed = sp * _session.transport_speed();
470 if (_visible_speed != sp) {
475 if (new_speed != _actual_speed) {
477 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() *
478 fabs (new_speed)) + 1;
480 if (required_wrap_size > wrap_buffer_size) {
481 _buffer_reallocation_required = true;
484 _actual_speed = new_speed;
485 phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
490 _seek_required = true;
492 speed_changed (); /* EMIT SIGNAL */
495 return _buffer_reallocation_required || _seek_required;
499 DiskStream::non_realtime_set_speed ()
501 if (_buffer_reallocation_required)
503 LockMonitor lm (state_lock, __LINE__, __FILE__);
504 allocate_temporary_buffers ();
506 _buffer_reallocation_required = false;
509 if (_seek_required) {
510 if (speed() != 1.0f || speed() != -1.0f) {
511 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
514 seek (_session.transport_frame(), true);
517 _seek_required = false;
522 DiskStream::prepare ()
525 playback_distance = 0;
529 DiskStream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
531 int possibly_recording;
534 const int transport_rolling = 0x4;
535 const int track_rec_enabled = 0x2;
536 const int global_rec_enabled = 0x1;
538 /* merge together the 3 factors that affect record status, and compute
542 rolling = _session.transport_speed() != 0.0f;
543 possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
544 change = possibly_recording ^ last_possibly_recording;
546 if (possibly_recording == last_possibly_recording) {
552 /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
554 if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) ||
555 ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
557 /* starting to record: compute first+last frames */
559 first_recordable_frame = transport_frame + _capture_offset;
560 last_recordable_frame = max_frames;
561 capture_start_frame = transport_frame;
563 if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) {
565 /* was stopped, now rolling (and recording) */
567 if (_alignment_style == ExistingMaterial) {
568 first_recordable_frame += _session.worst_output_latency();
570 first_recordable_frame += _roll_delay;
575 /* was rolling, but record state changed */
577 if (_alignment_style == ExistingMaterial) {
580 if (!_session.get_punch_in()) {
582 /* manual punch in happens at the correct transport frame
583 because the user hit a button. but to get alignment correct
584 we have to back up the position of the new region to the
585 appropriate spot given the roll delay.
588 capture_start_frame -= _roll_delay;
590 /* XXX paul notes (august 2005): i don't know why
594 first_recordable_frame += _capture_offset;
598 /* autopunch toggles recording at the precise
599 transport frame, and then the DS waits
600 to start recording for a time that depends
601 on the output latency.
604 first_recordable_frame += _session.worst_output_latency();
609 if (_session.get_punch_in()) {
610 first_recordable_frame += _roll_delay;
612 capture_start_frame -= _roll_delay;
618 } else if (!record_enabled() || !can_record) {
622 last_recordable_frame = transport_frame + _capture_offset;
624 if (_alignment_style == ExistingMaterial) {
625 last_recordable_frame += _session.worst_output_latency();
627 last_recordable_frame += _roll_delay;
631 last_possibly_recording = possibly_recording;
635 DiskStream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input)
638 ChannelList::iterator c;
640 jack_nframes_t rec_offset = 0;
641 jack_nframes_t rec_nframes = 0;
642 bool nominally_recording;
643 bool re = record_enabled ();
644 bool collect_playback = false;
646 /* if we've already processed the frames corresponding to this call,
647 just return. this allows multiple routes that are taking input
648 from this diskstream to call our ::process() method, but have
649 this stuff only happen once. more commonly, it allows both
650 the AudioTrack that is using this DiskStream *and* the Session
651 to call process() without problems.
658 check_record_status (transport_frame, nframes, can_record);
660 nominally_recording = (can_record && re);
667 /* This lock is held until the end of DiskStream::commit, so these two functions
668 must always be called as a pair. The only exception is if this function
669 returns a non-zero value, in which case, ::commit should not be called.
672 if (pthread_mutex_trylock (state_lock.mutex())) {
676 adjust_capture_position = 0;
678 for (c = channels.begin(); c != channels.end(); ++c) {
679 (*c).current_capture_buffer = 0;
680 (*c).current_playback_buffer = 0;
683 if (nominally_recording || (_session.get_record_enabled() && _session.get_punch_in())) {
686 ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
693 case OverlapInternal:
694 /* ---------- recrange
697 rec_nframes = nframes;
702 /* |--------| recrange
705 rec_nframes = transport_frame + nframes - first_recordable_frame;
707 rec_offset = first_recordable_frame - transport_frame;
712 /* |--------| recrange
715 rec_nframes = last_recordable_frame - transport_frame;
719 case OverlapExternal:
720 /* |--------| recrange
721 -------------- transrange
723 rec_nframes = last_recordable_frame - last_recordable_frame;
724 rec_offset = first_recordable_frame - transport_frame;
728 if (rec_nframes && !was_recording) {
729 capture_captured = 0;
730 was_recording = true;
735 if (can_record && !_last_capture_regions.empty()) {
736 _last_capture_regions.clear ();
741 if (Config->get_use_hardware_monitoring() && re && rec_monitoring_off_for_roll && rec_monitors_input) {
742 for (c = channels.begin(); c != channels.end(); ++c) {
743 (*c).source->ensure_monitor_input (true);
745 rec_monitoring_off_for_roll = false;
749 if (nominally_recording || rec_nframes) {
751 for (n = 0, c = channels.begin(); c != channels.end(); ++c, ++n) {
753 ChannelInfo& chan (*c);
755 chan.capture_buf->get_write_vector (&chan.capture_vector);
757 if (rec_nframes <= chan.capture_vector.len[0]) {
759 chan.current_capture_buffer = chan.capture_vector.buf[0];
761 /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use
765 memcpy (chan.current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes);
769 jack_nframes_t total = chan.capture_vector.len[0] + chan.capture_vector.len[1];
771 if (rec_nframes > total) {
776 Sample* buf = _io->input (n)->get_buffer (nframes) + offset;
777 jack_nframes_t first = chan.capture_vector.len[0];
779 memcpy (chan.capture_wrap_buffer, buf, sizeof (Sample) * first);
780 memcpy (chan.capture_vector.buf[0], buf, sizeof (Sample) * first);
781 memcpy (chan.capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first));
782 memcpy (chan.capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first));
784 chan.current_capture_buffer = chan.capture_wrap_buffer;
791 finish_capture (rec_monitors_input);
798 /* data will be written to disk */
800 if (rec_nframes == nframes && rec_offset == 0) {
802 for (c = channels.begin(); c != channels.end(); ++c) {
803 (*c).current_playback_buffer = (*c).current_capture_buffer;
806 playback_distance = nframes;
810 /* we can't use the capture buffer as the playback buffer, because
811 we recorded only a part of the current process' cycle data
815 collect_playback = true;
818 adjust_capture_position = rec_nframes;
820 } else if (nominally_recording) {
822 /* can't do actual capture yet - waiting for latency effects to finish before we start*/
824 for (c = channels.begin(); c != channels.end(); ++c) {
825 (*c).current_playback_buffer = (*c).current_capture_buffer;
828 playback_distance = nframes;
832 collect_playback = true;
835 if (collect_playback) {
837 /* we're doing playback */
839 jack_nframes_t necessary_samples;
841 /* no varispeed playback if we're recording, because the output .... TBD */
843 if (rec_nframes == 0 && _actual_speed != 1.0f) {
844 necessary_samples = (jack_nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
846 necessary_samples = nframes;
849 for (c = channels.begin(); c != channels.end(); ++c) {
850 (*c).playback_buf->get_read_vector (&(*c).playback_vector);
855 for (c = channels.begin(); c != channels.end(); ++c, ++n) {
857 ChannelInfo& chan (*c);
859 if (necessary_samples <= chan.playback_vector.len[0]) {
861 chan.current_playback_buffer = chan.playback_vector.buf[0];
864 jack_nframes_t total = chan.playback_vector.len[0] + chan.playback_vector.len[1];
866 if (necessary_samples > total) {
872 memcpy ((char *) chan.playback_wrap_buffer, chan.playback_vector.buf[0],
873 chan.playback_vector.len[0] * sizeof (Sample));
874 memcpy (chan.playback_wrap_buffer + chan.playback_vector.len[0], chan.playback_vector.buf[1],
875 (necessary_samples - chan.playback_vector.len[0]) * sizeof (Sample));
877 chan.current_playback_buffer = chan.playback_wrap_buffer;
882 if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
884 uint64_t phase = last_phase;
885 jack_nframes_t i = 0;
887 // Linearly interpolate into the alt buffer
888 // using 40.24 fixp maths (swh)
890 for (c = channels.begin(); c != channels.end(); ++c) {
893 ChannelInfo& chan (*c);
898 for (jack_nframes_t outsample = 0; outsample < nframes; ++outsample) {
900 fr = (phase & 0xFFFFFF) / 16777216.0f;
901 chan.speed_buffer[outsample] =
902 chan.current_playback_buffer[i] * (1.0f - fr) +
903 chan.current_playback_buffer[i+1] * fr;
907 chan.current_playback_buffer = chan.speed_buffer;
910 playback_distance = i + 1;
911 last_phase = (phase & 0xFFFFFF);
914 playback_distance = nframes;
926 /* we're exiting with failure, so ::commit will not
927 be called. unlock the state lock.
930 pthread_mutex_unlock (state_lock.mutex());
937 DiskStream::recover ()
939 pthread_mutex_unlock (state_lock.mutex());
944 DiskStream::commit (jack_nframes_t nframes)
946 bool need_butler = false;
948 if (_actual_speed < 0.0) {
949 playback_sample -= playback_distance;
951 playback_sample += playback_distance;
954 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
956 (*chan).playback_buf->increment_read_ptr (playback_distance);
958 if (adjust_capture_position) {
959 (*chan).capture_buf->increment_write_ptr (adjust_capture_position);
963 if (adjust_capture_position != 0) {
964 capture_captured += adjust_capture_position;
965 adjust_capture_position = 0;
969 need_butler = channels[0].playback_buf->write_space() >= channels[0].playback_buf->bufsize() / 2;
971 need_butler = channels[0].playback_buf->write_space() >= disk_io_chunk_frames
972 || channels[0].capture_buf->read_space() >= disk_io_chunk_frames;
975 pthread_mutex_unlock (state_lock.mutex());
983 DiskStream::set_pending_overwrite (bool yn)
985 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
987 pending_overwrite = yn;
989 overwrite_frame = playback_sample;
990 overwrite_offset = channels.front().playback_buf->get_read_ptr();
994 DiskStream::overwrite_existing_buffers ()
996 Sample* mixdown_buffer;
999 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1001 overwrite_queued = false;
1003 /* assume all are the same size */
1004 jack_nframes_t size = channels[0].playback_buf->bufsize();
1006 mixdown_buffer = new Sample[size];
1007 gain_buffer = new float[size];
1009 /* reduce size so that we can fill the buffer correctly. */
1013 jack_nframes_t start;
1015 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1017 start = overwrite_frame;
1018 jack_nframes_t cnt = size;
1020 /* to fill the buffer without resetting the playback sample, we need to
1021 do it one or two chunks (normally two).
1023 |----------------------------------------------------------------------|
1027 |<- second chunk->||<----------------- first chunk ------------------>|
1031 jack_nframes_t to_read = size - overwrite_offset;
1033 if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer,
1034 start, to_read, *chan, n, reversed)) {
1035 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1036 _id, size, playback_sample) << endmsg;
1040 if (cnt > to_read) {
1044 if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer,
1045 start, cnt, *chan, n, reversed)) {
1046 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1047 _id, size, playback_sample) << endmsg;
1056 pending_overwrite = false;
1057 delete [] gain_buffer;
1058 delete [] mixdown_buffer;
1063 DiskStream::seek (jack_nframes_t frame, bool complete_refill)
1065 LockMonitor lm (state_lock, __LINE__, __FILE__);
1068 ChannelList::iterator chan;
1070 for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1071 (*chan).playback_buf->reset ();
1072 (*chan).capture_buf->reset ();
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, 0, 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 = 0, 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 if (Config->get_use_hardware_monitoring() && record_enabled()) {
1689 if (rec_monitors_input) {
1690 if (rec_monitoring_off_for_roll) {
1691 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1692 (*chan).source->ensure_monitor_input (true);
1694 rec_monitoring_off_for_roll = false;
1697 if (!rec_monitoring_off_for_roll) {
1698 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1699 (*chan).source->ensure_monitor_input (false);
1701 rec_monitoring_off_for_roll = true;
1706 was_recording = false;
1708 if (capture_captured == 0) {
1712 CaptureInfo* ci = new CaptureInfo;
1714 ci->start = capture_start_frame;
1715 ci->frames = capture_captured;
1717 /* XXX theoretical race condition here. Need atomic exchange ?
1718 However, the circumstances when this is called right
1719 now (either on record-disable or transport_stopped)
1720 mean that no actual race exists. I think ...
1721 We now have a capture_info_lock, but it is only to be used
1722 to synchronize in the transport_stop and the capture info
1723 accessors, so that invalidation will not occur (both non-realtime).
1726 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1728 capture_info.push_back (ci);
1729 capture_captured = 0;
1733 DiskStream::set_record_enabled (bool yn, void* src)
1735 if (!recordable() || !_session.record_enabling_legal()) {
1739 /* if we're turning on rec-enable, there needs to be an
1743 if (yn && channels[0].source == 0) {
1745 /* pick up connections not initiated *from* the IO object
1746 we're associated with.
1749 get_input_sources ();
1751 if (channels[0].source == 0) {
1754 CannotRecordNoInput (this); /* emit signal */
1760 /* yes, i know that this not proof against race conditions, but its
1761 good enough. i think.
1764 if (record_enabled() != yn) {
1766 atomic_set (&_record_enabled, 1);
1767 capturing_sources.clear ();
1768 if (Config->get_use_hardware_monitoring()) {
1769 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1770 if ((*chan).source) {
1771 (*chan).source->request_monitor_input (true);
1773 capturing_sources.push_back ((*chan).write_source);
1776 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1777 capturing_sources.push_back ((*chan).write_source);
1782 atomic_set (&_record_enabled, 0);
1783 if (Config->get_use_hardware_monitoring()) {
1784 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1785 if ((*chan).source) {
1786 (*chan).source->request_monitor_input (false);
1790 capturing_sources.clear ();
1793 record_enable_changed (src); /* EMIT SIGNAL */
1798 DiskStream::get_state ()
1800 XMLNode* node = new XMLNode ("DiskStream");
1802 LocaleGuard lg (X_("POSIX"));
1804 snprintf (buf, sizeof(buf), "%zd", channels.size());
1805 node->add_property ("channels", buf);
1807 node->add_property ("playlist", _playlist->name());
1809 snprintf (buf, sizeof(buf), "%f", _visible_speed);
1810 node->add_property ("speed", buf);
1812 node->add_property("name", _name);
1813 snprintf (buf, sizeof(buf), "%" PRIu64, id());
1814 node->add_property("id", buf);
1816 if (!capturing_sources.empty() && _session.get_record_enabled()) {
1818 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1819 XMLNode* cs_grandchild;
1821 for (vector<FileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1822 cs_grandchild = new XMLNode (X_("file"));
1823 cs_grandchild->add_property (X_("path"), (*i)->path());
1824 cs_child->add_child_nocopy (*cs_grandchild);
1827 /* store the location where capture will start */
1831 if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1832 snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
1834 snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
1837 cs_child->add_property (X_("at"), buf);
1838 node->add_child_nocopy (*cs_child);
1842 node->add_child_copy (*_extra_xml);
1849 DiskStream::set_state (const XMLNode& node)
1851 const XMLProperty* prop;
1852 XMLNodeList nlist = node.children();
1853 XMLNodeIterator niter;
1854 uint32_t nchans = 1;
1855 XMLNode* capture_pending_node = 0;
1856 LocaleGuard lg (X_("POSIX"));
1858 in_set_state = true;
1860 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1861 if ((*niter)->name() == IO::state_node_name) {
1862 deprecated_io_node = new XMLNode (**niter);
1865 if ((*niter)->name() == X_("CapturingSources")) {
1866 capture_pending_node = *niter;
1870 /* prevent write sources from being created */
1872 in_set_state = true;
1874 if ((prop = node.property ("name")) != 0) {
1875 _name = prop->value();
1878 if (deprecated_io_node) {
1879 if ((prop = deprecated_io_node->property ("id")) != 0) {
1880 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1883 if ((prop = node.property ("id")) != 0) {
1884 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1888 if ((prop = node.property ("channels")) != 0) {
1889 nchans = atoi (prop->value().c_str());
1892 // create necessary extra channels
1893 // we are always constructed with one
1894 // and we always need one
1896 if (nchans > _n_channels) {
1898 // we need to add new channel infos
1899 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1901 int diff = nchans - channels.size();
1903 for (int i=0; i < diff; ++i) {
1907 } else if (nchans < _n_channels) {
1909 // we need to get rid of channels
1910 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1912 int diff = channels.size() - nchans;
1914 for (int i = 0; i < diff; ++i) {
1919 if ((prop = node.property ("playlist")) == 0) {
1924 bool had_playlist = (_playlist != 0);
1926 if (find_and_use_playlist (prop->value())) {
1930 if (!had_playlist) {
1931 _playlist->set_orig_diskstream_id (_id);
1934 if (capture_pending_node) {
1935 use_pending_capture_data (*capture_pending_node);
1940 if ((prop = node.property ("speed")) != 0) {
1941 float sp = atof (prop->value().c_str());
1943 if (realtime_set_speed (sp, false)) {
1944 non_realtime_set_speed ();
1948 _n_channels = channels.size();
1950 in_set_state = false;
1952 /* now that we're all done with playlist+channel set up,
1953 go ahead and create write sources.
1957 capturing_sources.clear ();
1960 reset_write_sources (false);
1963 in_set_state = false;
1969 DiskStream::use_new_write_source (uint32_t n)
1971 if (!recordable()) {
1975 if (n >= channels.size()) {
1976 error << string_compose (_("DiskStream: channel %1 out of range"), n) << endmsg;
1980 ChannelInfo &chan = channels[n];
1982 if (chan.write_source) {
1984 if (FileSource::is_empty (chan.write_source->path())) {
1985 chan.write_source->mark_for_remove ();
1986 chan.write_source->release();
1987 delete chan.write_source;
1989 chan.write_source->release();
1990 chan.write_source = 0;
1995 if ((chan.write_source = _session.create_file_source (*this, n)) == 0) {
1996 throw failed_constructor();
2000 catch (failed_constructor &err) {
2001 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
2002 chan.write_source = 0;
2006 chan.write_source->use ();
2012 DiskStream::reset_write_sources (bool mark_write_complete)
2014 ChannelList::iterator chan;
2017 if (!recordable()) {
2021 capturing_sources.clear ();
2023 for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2024 if (mark_write_complete) {
2025 (*chan).write_source->mark_streaming_write_completed ();
2027 use_new_write_source (n);
2028 if (record_enabled()) {
2029 capturing_sources.push_back ((*chan).write_source);
2035 DiskStream::set_block_size (jack_nframes_t nframes)
2037 if (_session.get_block_size() > speed_buffer_size) {
2038 speed_buffer_size = _session.get_block_size();
2040 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2041 if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
2042 (*chan).speed_buffer = new Sample[speed_buffer_size];
2045 allocate_temporary_buffers ();
2049 DiskStream::allocate_temporary_buffers ()
2051 /* make sure the wrap buffer is at least large enough to deal
2052 with the speeds up to 1.2, to allow for micro-variation
2053 when slaving to MTC, SMPTE etc.
2056 float sp = max (fabsf (_actual_speed), 1.2f);
2057 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * sp) + 1;
2059 if (required_wrap_size > wrap_buffer_size) {
2061 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2062 if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
2063 (*chan).playback_wrap_buffer = new Sample[required_wrap_size];
2064 if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
2065 (*chan).capture_wrap_buffer = new Sample[required_wrap_size];
2068 wrap_buffer_size = required_wrap_size;
2073 DiskStream::monitor_input (bool yn)
2075 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2077 if ((*chan).source) {
2078 (*chan).source->request_monitor_input (yn);
2084 DiskStream::set_capture_offset ()
2087 /* can't capture, so forget it */
2091 _capture_offset = _io->input_latency();
2095 DiskStream::set_persistent_align_style (AlignStyle a)
2097 _persistent_alignment_style = a;
2101 DiskStream::set_align_style_from_io ()
2103 bool have_physical = false;
2109 get_input_sources ();
2111 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2112 if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
2113 have_physical = true;
2118 if (have_physical) {
2119 set_align_style (ExistingMaterial);
2121 set_align_style (CaptureTime);
2126 DiskStream::set_align_style (AlignStyle a)
2128 if (record_enabled() && _session.actively_recording()) {
2133 if (a != _alignment_style) {
2134 _alignment_style = a;
2135 AlignmentStyleChanged ();
2140 DiskStream::add_channel ()
2142 /* XXX need to take lock??? */
2146 init_channel (chan);
2148 chan.speed_buffer = new Sample[speed_buffer_size];
2149 chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
2150 chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
2152 channels.push_back (chan);
2154 _n_channels = channels.size();
2160 DiskStream::remove_channel ()
2162 if (channels.size() > 1) {
2163 /* XXX need to take lock??? */
2164 ChannelInfo & chan = channels.back();
2165 destroy_channel (chan);
2166 channels.pop_back();
2168 _n_channels = channels.size();
2176 DiskStream::playback_buffer_load () const
2178 return (float) ((double) channels.front().playback_buf->read_space()/
2179 (double) channels.front().playback_buf->bufsize());
2183 DiskStream::capture_buffer_load () const
2185 return (float) ((double) channels.front().capture_buf->write_space()/
2186 (double) channels.front().capture_buf->bufsize());
2190 DiskStream::set_loop (Location *location)
2193 if (location->start() >= location->end()) {
2194 error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
2199 loop_location = location;
2201 LoopSet (location); /* EMIT SIGNAL */
2206 DiskStream::get_capture_start_frame (uint32_t n)
2208 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2210 if (capture_info.size() > n) {
2211 return capture_info[n]->start;
2214 return capture_start_frame;
2219 DiskStream::get_captured_frames (uint32_t n)
2221 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2223 if (capture_info.size() > n) {
2224 return capture_info[n]->frames;
2227 return capture_captured;
2232 DiskStream::punch_in ()
2237 DiskStream::punch_out ()
2242 DiskStream::use_pending_capture_data (XMLNode& node)
2244 const XMLProperty* prop;
2245 XMLNodeList nlist = node.children();
2246 XMLNodeIterator niter;
2248 FileSource* first_fs = 0;
2249 AudioRegion::SourceList pending_sources;
2250 jack_nframes_t position;
2252 if ((prop = node.property (X_("at"))) == 0) {
2256 if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
2260 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2261 if ((*niter)->name() == X_("file")) {
2263 if ((prop = (*niter)->property (X_("path"))) == 0) {
2268 fs = new FileSource (prop->value(), _session.frame_rate(), true);
2271 catch (failed_constructor& err) {
2272 error << string_compose (_("%1: cannot restore pending capture source file %2"),
2273 _name, prop->value())
2278 pending_sources.push_back (fs);
2280 if (first_fs == 0) {
2284 fs->set_captured_for (_name);
2288 if (pending_sources.size() == 0) {
2289 /* nothing can be done */
2293 if (pending_sources.size() != _n_channels) {
2294 error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2299 AudioRegion* region;
2302 region = new AudioRegion (pending_sources, 0, first_fs->length(),
2303 region_name_from_path (first_fs->name()),
2304 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
2306 region->special_set_position (0);
2309 catch (failed_constructor& err) {
2310 error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
2318 region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
2321 catch (failed_constructor& err) {
2322 error << string_compose (_("%1: cannot create region from pending capture sources"),
2329 _playlist->add_region (*region, position);
2335 DiskStream::set_roll_delay (jack_nframes_t nframes)
2337 _roll_delay = nframes;