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 } else if (!record_enabled() || !can_record) {
621 last_recordable_frame = transport_frame + _capture_offset;
623 if (_alignment_style == ExistingMaterial) {
624 last_recordable_frame += _session.worst_output_latency();
626 last_recordable_frame += _roll_delay;
630 last_possibly_recording = possibly_recording;
634 DiskStream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input)
637 ChannelList::iterator c;
639 jack_nframes_t rec_offset = 0;
640 jack_nframes_t rec_nframes = 0;
641 bool nominally_recording;
642 bool re = record_enabled ();
643 bool collect_playback = false;
645 /* if we've already processed the frames corresponding to this call,
646 just return. this allows multiple routes that are taking input
647 from this diskstream to call our ::process() method, but have
648 this stuff only happen once. more commonly, it allows both
649 the AudioTrack that is using this DiskStream *and* the Session
650 to call process() without problems.
657 check_record_status (transport_frame, nframes, can_record);
659 nominally_recording = (can_record && re);
666 /* This lock is held until the end of DiskStream::commit, so these two functions
667 must always be called as a pair. The only exception is if this function
668 returns a non-zero value, in which case, ::commit should not be called.
671 if (pthread_mutex_trylock (state_lock.mutex())) {
675 adjust_capture_position = 0;
677 for (c = channels.begin(); c != channels.end(); ++c) {
678 (*c).current_capture_buffer = 0;
679 (*c).current_playback_buffer = 0;
682 if (nominally_recording || (_session.get_record_enabled() && _session.get_punch_in())) {
685 ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
692 case OverlapInternal:
693 /* ---------- recrange
696 rec_nframes = nframes;
701 /* |--------| recrange
704 rec_nframes = transport_frame + nframes - first_recordable_frame;
706 rec_offset = first_recordable_frame - transport_frame;
711 /* |--------| recrange
714 rec_nframes = last_recordable_frame - transport_frame;
718 case OverlapExternal:
719 /* |--------| recrange
720 -------------- transrange
722 rec_nframes = last_recordable_frame - last_recordable_frame;
723 rec_offset = first_recordable_frame - transport_frame;
727 if (rec_nframes && !was_recording) {
728 capture_captured = 0;
729 was_recording = true;
734 if (can_record && !_last_capture_regions.empty()) {
735 _last_capture_regions.clear ();
738 if (nominally_recording || rec_nframes) {
740 for (n = 0, c = channels.begin(); c != channels.end(); ++c, ++n) {
742 ChannelInfo& chan (*c);
744 chan.capture_buf->get_write_vector (&chan.capture_vector);
746 if (rec_nframes <= chan.capture_vector.len[0]) {
748 chan.current_capture_buffer = chan.capture_vector.buf[0];
750 /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use
754 memcpy (chan.current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes);
758 jack_nframes_t total = chan.capture_vector.len[0] + chan.capture_vector.len[1];
760 if (rec_nframes > total) {
765 Sample* buf = _io->input (n)->get_buffer (nframes) + offset;
766 jack_nframes_t first = chan.capture_vector.len[0];
768 memcpy (chan.capture_wrap_buffer, buf, sizeof (Sample) * first);
769 memcpy (chan.capture_vector.buf[0], buf, sizeof (Sample) * first);
770 memcpy (chan.capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first));
771 memcpy (chan.capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first));
773 chan.current_capture_buffer = chan.capture_wrap_buffer;
780 finish_capture (rec_monitors_input);
787 /* data will be written to disk */
789 if (rec_nframes == nframes && rec_offset == 0) {
791 for (c = channels.begin(); c != channels.end(); ++c) {
792 (*c).current_playback_buffer = (*c).current_capture_buffer;
795 playback_distance = nframes;
800 /* we can't use the capture buffer as the playback buffer, because
801 we recorded only a part of the current process' cycle data
805 collect_playback = true;
808 adjust_capture_position = rec_nframes;
810 } else if (nominally_recording) {
812 /* can't do actual capture yet - waiting for latency effects to finish before we start*/
814 for (c = channels.begin(); c != channels.end(); ++c) {
815 (*c).current_playback_buffer = (*c).current_capture_buffer;
818 playback_distance = nframes;
822 collect_playback = true;
825 if (collect_playback) {
827 /* we're doing playback */
829 jack_nframes_t necessary_samples;
831 /* no varispeed playback if we're recording, because the output .... TBD */
833 if (rec_nframes == 0 && _actual_speed != 1.0f) {
834 necessary_samples = (jack_nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
836 necessary_samples = nframes;
839 for (c = channels.begin(); c != channels.end(); ++c) {
840 (*c).playback_buf->get_read_vector (&(*c).playback_vector);
845 for (c = channels.begin(); c != channels.end(); ++c, ++n) {
847 ChannelInfo& chan (*c);
849 if (necessary_samples <= chan.playback_vector.len[0]) {
851 chan.current_playback_buffer = chan.playback_vector.buf[0];
854 jack_nframes_t total = chan.playback_vector.len[0] + chan.playback_vector.len[1];
856 if (necessary_samples > total) {
862 memcpy ((char *) chan.playback_wrap_buffer, chan.playback_vector.buf[0],
863 chan.playback_vector.len[0] * sizeof (Sample));
864 memcpy (chan.playback_wrap_buffer + chan.playback_vector.len[0], chan.playback_vector.buf[1],
865 (necessary_samples - chan.playback_vector.len[0]) * sizeof (Sample));
867 chan.current_playback_buffer = chan.playback_wrap_buffer;
872 if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
874 uint64_t phase = last_phase;
875 jack_nframes_t i = 0;
877 // Linearly interpolate into the alt buffer
878 // using 40.24 fixp maths (swh)
880 for (c = channels.begin(); c != channels.end(); ++c) {
883 ChannelInfo& chan (*c);
888 for (jack_nframes_t outsample = 0; outsample < nframes; ++outsample) {
890 fr = (phase & 0xFFFFFF) / 16777216.0f;
891 chan.speed_buffer[outsample] =
892 chan.current_playback_buffer[i] * (1.0f - fr) +
893 chan.current_playback_buffer[i+1] * fr;
897 chan.current_playback_buffer = chan.speed_buffer;
900 playback_distance = i + 1;
901 last_phase = (phase & 0xFFFFFF);
904 playback_distance = nframes;
916 /* we're exiting with failure, so ::commit will not
917 be called. unlock the state lock.
920 pthread_mutex_unlock (state_lock.mutex());
927 DiskStream::recover ()
929 pthread_mutex_unlock (state_lock.mutex());
934 DiskStream::commit (jack_nframes_t nframes)
936 bool need_butler = false;
938 if (_actual_speed < 0.0) {
939 playback_sample -= playback_distance;
941 playback_sample += playback_distance;
944 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
946 (*chan).playback_buf->increment_read_ptr (playback_distance);
948 if (adjust_capture_position) {
949 (*chan).capture_buf->increment_write_ptr (adjust_capture_position);
953 if (adjust_capture_position != 0) {
954 capture_captured += adjust_capture_position;
955 adjust_capture_position = 0;
959 need_butler = channels[0].playback_buf->write_space() >= channels[0].playback_buf->bufsize() / 2;
961 need_butler = channels[0].playback_buf->write_space() >= disk_io_chunk_frames
962 || channels[0].capture_buf->read_space() >= disk_io_chunk_frames;
965 pthread_mutex_unlock (state_lock.mutex());
973 DiskStream::set_pending_overwrite (bool yn)
975 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
977 pending_overwrite = yn;
979 overwrite_frame = playback_sample;
980 overwrite_offset = channels.front().playback_buf->get_read_ptr();
984 DiskStream::overwrite_existing_buffers ()
986 Sample* mixdown_buffer;
989 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
991 overwrite_queued = false;
993 /* assume all are the same size */
994 jack_nframes_t size = channels[0].playback_buf->bufsize();
996 mixdown_buffer = new Sample[size];
997 gain_buffer = new float[size];
999 /* reduce size so that we can fill the buffer correctly. */
1003 jack_nframes_t start;
1005 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1007 start = overwrite_frame;
1008 jack_nframes_t cnt = size;
1010 /* to fill the buffer without resetting the playback sample, we need to
1011 do it one or two chunks (normally two).
1013 |----------------------------------------------------------------------|
1017 |<- second chunk->||<----------------- first chunk ------------------>|
1021 jack_nframes_t to_read = size - overwrite_offset;
1023 if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer,
1024 start, to_read, *chan, n, reversed)) {
1025 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1026 _id, size, playback_sample) << endmsg;
1030 if (cnt > to_read) {
1034 if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer,
1035 start, cnt, *chan, n, reversed)) {
1036 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1037 _id, size, playback_sample) << endmsg;
1046 pending_overwrite = false;
1047 delete [] gain_buffer;
1048 delete [] mixdown_buffer;
1053 DiskStream::seek (jack_nframes_t frame, bool complete_refill)
1055 LockMonitor lm (state_lock, __LINE__, __FILE__);
1058 ChannelList::iterator chan;
1060 for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1061 (*chan).playback_buf->reset ();
1062 (*chan).capture_buf->reset ();
1063 if (destructive()) {
1064 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> ((*chan).write_source);
1069 playback_sample = frame;
1072 if (complete_refill) {
1073 while ((ret = do_refill (0, 0)) > 0);
1075 ret = do_refill (0, 0);
1082 DiskStream::can_internal_playback_seek (jack_nframes_t distance)
1084 ChannelList::iterator chan;
1086 for (chan = channels.begin(); chan != channels.end(); ++chan) {
1087 if ((*chan).playback_buf->read_space() < distance) {
1095 DiskStream::internal_playback_seek (jack_nframes_t distance)
1097 ChannelList::iterator chan;
1099 for (chan = channels.begin(); chan != channels.end(); ++chan) {
1100 (*chan).playback_buf->increment_read_ptr (distance);
1103 first_recordable_frame += distance;
1104 playback_sample += distance;
1110 DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, jack_nframes_t& start, jack_nframes_t cnt,
1112 ChannelInfo& channel_info, int channel, bool reversed)
1114 jack_nframes_t this_read = 0;
1115 bool reloop = false;
1116 jack_nframes_t loop_end = 0;
1117 jack_nframes_t loop_start = 0;
1118 jack_nframes_t loop_length = 0;
1119 jack_nframes_t offset = 0;
1123 /* Make the use of a Location atomic for this read operation.
1125 Note: Locations don't get deleted, so all we care about
1126 when I say "atomic" is that we are always pointing to
1127 the same one and using a start/length values obtained
1131 if ((loc = loop_location) != 0) {
1132 loop_start = loc->start();
1133 loop_end = loc->end();
1134 loop_length = loop_end - loop_start;
1137 /* if we are looping, ensure that the first frame we read is at the correct
1138 position within the loop.
1141 if (loc && start >= loop_end) {
1142 //cerr << "start adjusted from " << start;
1143 start = loop_start + ((start - loop_start) % loop_length);
1144 //cerr << "to " << start << endl;
1146 //cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
1151 /* take any loop into account. we can't read past the end of the loop. */
1153 if (loc && (loop_end - start < cnt)) {
1154 this_read = loop_end - start;
1155 //cerr << "reloop true: thisread: " << this_read << " cnt: " << cnt << endl;
1162 if (this_read == 0) {
1166 this_read = min(cnt,this_read);
1168 if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, start, this_read, channel) != this_read) {
1169 error << string_compose(_("DiskStream %1: cannot read %2 from playlist at frame %3"), _id, this_read,
1174 _read_data_count = _playlist->read_data_count();
1178 /* don't adjust start, since caller has already done that
1181 swap_by_ptr (buf, buf + this_read - 1);
1185 /* if we read to the end of the loop, go back to the beginning */
1195 offset += this_read;
1202 DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer)
1205 jack_nframes_t to_read;
1206 RingBufferNPT<Sample>::rw_vector vector;
1209 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1210 jack_nframes_t total_space;
1211 jack_nframes_t zero_fill;
1213 ChannelList::iterator i;
1216 channels.front().playback_buf->get_write_vector (&vector);
1218 if ((total_space = vector.len[0] + vector.len[1]) == 0) {
1222 /* if there are 2+ chunks of disk i/o possible for
1223 this track, let the caller know so that it can arrange
1224 for us to be called again, ASAP.
1227 if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) {
1231 /* if we're running close to normal speed and there isn't enough
1232 space to do disk_io_chunk_frames of I/O, then don't bother.
1234 at higher speeds, just do it because the sync between butler
1235 and audio thread may not be good enough.
1238 if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
1242 /* when slaved, don't try to get too close to the read pointer. this
1243 leaves space for the buffer reversal to have something useful to
1247 if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) {
1251 total_space = min (disk_io_chunk_frames, total_space);
1255 if (file_frame == 0) {
1257 /* at start: nothing to do but fill with silence */
1259 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1261 ChannelInfo& chan (*i);
1262 chan.playback_buf->get_write_vector (&vector);
1263 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1264 if (vector.len[1]) {
1265 memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1267 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1272 if (file_frame < total_space) {
1274 /* too close to the start: read what we can,
1275 and then zero fill the rest
1278 zero_fill = total_space - file_frame;
1279 total_space = file_frame;
1284 /* move read position backwards because we are going
1285 to reverse the data.
1288 file_frame -= total_space;
1294 if (file_frame == max_frames) {
1296 /* at end: nothing to do but fill with silence */
1298 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1300 ChannelInfo& chan (*i);
1301 chan.playback_buf->get_write_vector (&vector);
1302 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1303 if (vector.len[1]) {
1304 memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1306 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1311 if (file_frame > max_frames - total_space) {
1313 /* to close to the end: read what we can, and zero fill the rest */
1315 zero_fill = total_space - (max_frames - file_frame);
1316 total_space = max_frames - file_frame;
1323 /* Please note: the code to allocate buffers isn't run
1324 during normal butler thread operation. Its there
1325 for other times when we need to call do_refill()
1326 from somewhere other than the butler thread.
1329 if (mixdown_buffer == 0) {
1330 mixdown_buffer = new Sample[disk_io_chunk_frames];
1331 free_mixdown = true;
1333 free_mixdown = false;
1336 if (gain_buffer == 0) {
1337 gain_buffer = new float[disk_io_chunk_frames];
1343 jack_nframes_t file_frame_tmp = 0;
1345 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1347 ChannelInfo& chan (*i);
1350 jack_nframes_t len1, len2;
1352 chan.playback_buf->get_write_vector (&vector);
1355 file_frame_tmp = file_frame;
1358 buf1 = vector.buf[1];
1359 len1 = vector.len[1];
1360 buf2 = vector.buf[0];
1361 len2 = vector.len[0];
1363 buf1 = vector.buf[0];
1364 len1 = vector.len[0];
1365 buf2 = vector.buf[1];
1366 len2 = vector.len[1];
1370 to_read = min (ts, len1);
1371 to_read = min (to_read, disk_io_chunk_frames);
1375 if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1380 chan.playback_buf->increment_write_ptr (to_read);
1384 to_read = min (ts, len2);
1389 /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data,
1390 so read some or all of vector.len[1] as well.
1393 if (read (buf2, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1398 chan.playback_buf->increment_write_ptr (to_read);
1407 file_frame = file_frame_tmp;
1411 delete [] mixdown_buffer;
1414 delete [] gain_buffer;
1421 DiskStream::do_flush (bool force_flush)
1425 RingBufferNPT<Sample>::rw_vector vector;
1426 jack_nframes_t total;
1428 /* important note: this function will write *AT MOST*
1429 disk_io_chunk_frames of data to disk. it will never
1430 write more than that. if its writes that much and there
1431 is more than that waiting to be written, it will return 1,
1432 otherwise 0 on success or -1 on failure.
1434 if there is less than disk_io_chunk_frames to be written,
1435 no data will be written at all unless `force_flush' is true.
1438 _write_data_count = 0;
1440 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1442 (*chan).capture_buf->get_read_vector (&vector);
1444 total = vector.len[0] + vector.len[1];
1446 if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
1450 /* if there are 2+ chunks of disk i/o possible for
1451 this track, let the caller know so that it can arrange
1452 for us to be called again, ASAP.
1454 if we are forcing a flush, then if there is* any* extra
1455 work, let the caller know.
1457 if we are no longer recording and there is any extra work,
1458 let the caller know too.
1461 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
1465 to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
1467 if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write) != to_write) {
1468 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1472 (*chan).capture_buf->increment_read_ptr (to_write);
1474 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames)) {
1476 /* we wrote all of vector.len[0] but it wasn't an entire
1477 disk_io_chunk_frames of data, so arrange for some part
1478 of vector.len[1] to be flushed to disk as well.
1481 to_write = min ((jack_nframes_t)(disk_io_chunk_frames - to_write), (jack_nframes_t) vector.len[1]);
1483 if ((*chan).write_source->write (vector.buf[1], to_write) != to_write) {
1484 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1488 _write_data_count += (*chan).write_source->write_data_count();
1490 (*chan).capture_buf->increment_read_ptr (to_write);
1499 DiskStream::playlist_changed (Change ignored)
1501 playlist_modified ();
1505 DiskStream::playlist_modified ()
1507 if (!i_am_the_modifier && !overwrite_queued) {
1508 _session.request_overwrite_buffer (this);
1509 overwrite_queued = true;
1514 DiskStream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
1516 uint32_t buffer_position;
1517 bool more_work = true;
1519 AudioRegion* region = 0;
1520 jack_nframes_t total_capture;
1521 AudioRegion::SourceList srcs;
1522 AudioRegion::SourceList::iterator src;
1523 ChannelList::iterator chan;
1524 vector<CaptureInfo*>::iterator ci;
1526 list<Source*>* deletion_list;
1527 bool mark_write_completed = false;
1529 finish_capture (true);
1531 /* butler is already stopped, but there may be work to do
1532 to flush remaining data to disk.
1535 while (more_work && !err) {
1536 switch (do_flush (true)) {
1543 error << string_compose(_("DiskStream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1548 /* XXX is there anything we can do if err != 0 ? */
1549 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
1551 if (capture_info.empty()) {
1555 if (abort_capture) {
1557 ChannelList::iterator chan;
1559 deletion_list = new list<Source*>;
1561 for ( chan = channels.begin(); chan != channels.end(); ++chan) {
1563 if ((*chan).write_source) {
1565 (*chan).write_source->mark_for_remove ();
1566 (*chan).write_source->release ();
1568 deletion_list->push_back ((*chan).write_source);
1570 (*chan).write_source = 0;
1573 /* new source set up in "out" below */
1576 if (!deletion_list->empty()) {
1577 DeleteSources (deletion_list);
1579 delete deletion_list;
1585 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1586 total_capture += (*ci)->frames;
1589 /* figure out the name for this take */
1591 for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1593 Source* s = (*chan).write_source;
1601 if ((fsrc = dynamic_cast<FileSource *>(s)) != 0) {
1602 fsrc->update_header (capture_info.front()->start, when, twhen);
1605 s->set_captured_for (_name);
1610 /* Register a new region with the Session that
1611 describes the entire source. Do this first
1612 so that any sub-regions will obviously be
1613 children of this one (later!)
1617 region = new AudioRegion (srcs, 0, total_capture,
1618 region_name_from_path (channels[0].write_source->name()),
1619 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
1621 region->special_set_position (capture_info.front()->start);
1624 catch (failed_constructor& err) {
1625 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1629 _last_capture_regions.push_back (region);
1631 // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
1633 _session.add_undo (_playlist->get_memento());
1634 _playlist->freeze ();
1636 for (buffer_position = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1639 _session.region_name (region_name, _name, false);
1641 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1644 region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
1647 catch (failed_constructor& err) {
1648 error << _("DiskStream: could not create region for captured audio!") << endmsg;
1649 continue; /* XXX is this OK? */
1652 _last_capture_regions.push_back (region);
1654 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1656 i_am_the_modifier++;
1657 _playlist->add_region (*region, (*ci)->start);
1658 i_am_the_modifier--;
1660 buffer_position += (*ci)->frames;
1664 _session.add_redo_no_execute (_playlist->get_memento());
1666 mark_write_completed = true;
1668 reset_write_sources (mark_write_completed);
1671 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1675 capture_info.clear ();
1676 capture_start_frame = 0;
1680 DiskStream::finish_capture (bool rec_monitors_input)
1682 was_recording = false;
1684 if (capture_captured == 0) {
1688 CaptureInfo* ci = new CaptureInfo;
1690 ci->start = capture_start_frame;
1691 ci->frames = capture_captured;
1693 /* XXX theoretical race condition here. Need atomic exchange ?
1694 However, the circumstances when this is called right
1695 now (either on record-disable or transport_stopped)
1696 mean that no actual race exists. I think ...
1697 We now have a capture_info_lock, but it is only to be used
1698 to synchronize in the transport_stop and the capture info
1699 accessors, so that invalidation will not occur (both non-realtime).
1702 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1704 capture_info.push_back (ci);
1705 capture_captured = 0;
1709 DiskStream::set_record_enabled (bool yn, void* src)
1711 bool rolling = _session.transport_speed() != 0.0f;
1713 if (!recordable() || !_session.record_enabling_legal()) {
1717 /* if we're turning on rec-enable, there needs to be an
1721 if (yn && channels[0].source == 0) {
1723 /* pick up connections not initiated *from* the IO object
1724 we're associated with.
1727 get_input_sources ();
1729 if (channels[0].source == 0) {
1732 CannotRecordNoInput (this); /* emit signal */
1738 /* yes, i know that this not proof against race conditions, but its
1739 good enough. i think.
1742 if (record_enabled() != yn) {
1744 atomic_set (&_record_enabled, 1);
1745 capturing_sources.clear ();
1746 if (Config->get_use_hardware_monitoring()) {
1747 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1748 if ((*chan).source) {
1749 (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
1751 capturing_sources.push_back ((*chan).write_source);
1754 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1755 capturing_sources.push_back ((*chan).write_source);
1760 atomic_set (&_record_enabled, 0);
1761 if (Config->get_use_hardware_monitoring()) {
1762 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1763 if ((*chan).source) {
1764 (*chan).source->request_monitor_input (false);
1768 capturing_sources.clear ();
1771 record_enable_changed (src); /* EMIT SIGNAL */
1776 DiskStream::get_state ()
1778 XMLNode* node = new XMLNode ("DiskStream");
1780 LocaleGuard lg (X_("POSIX"));
1782 if (destructive()) {
1783 node->add_property ("destructive", "true");
1786 snprintf (buf, sizeof(buf), "%zd", channels.size());
1787 node->add_property ("channels", buf);
1789 node->add_property ("playlist", _playlist->name());
1791 snprintf (buf, sizeof(buf), "%f", _visible_speed);
1792 node->add_property ("speed", buf);
1794 node->add_property("name", _name);
1795 snprintf (buf, sizeof(buf), "%" PRIu64, id());
1796 node->add_property("id", buf);
1798 if (!capturing_sources.empty() && _session.get_record_enabled()) {
1800 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1801 XMLNode* cs_grandchild;
1803 for (vector<FileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1804 cs_grandchild = new XMLNode (X_("file"));
1805 cs_grandchild->add_property (X_("path"), (*i)->path());
1806 cs_child->add_child_nocopy (*cs_grandchild);
1809 /* store the location where capture will start */
1813 if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1814 snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
1816 snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
1819 cs_child->add_property (X_("at"), buf);
1820 node->add_child_nocopy (*cs_child);
1824 node->add_child_copy (*_extra_xml);
1831 DiskStream::set_state (const XMLNode& node)
1833 const XMLProperty* prop;
1834 XMLNodeList nlist = node.children();
1835 XMLNodeIterator niter;
1836 uint32_t nchans = 1;
1837 XMLNode* capture_pending_node = 0;
1838 LocaleGuard lg (X_("POSIX"));
1840 in_set_state = true;
1842 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1843 if ((*niter)->name() == IO::state_node_name) {
1844 deprecated_io_node = new XMLNode (**niter);
1847 if ((*niter)->name() == X_("CapturingSources")) {
1848 capture_pending_node = *niter;
1852 /* prevent write sources from being created */
1854 in_set_state = true;
1856 if ((prop = node.property ("name")) != 0) {
1857 _name = prop->value();
1860 if ((prop = node.property ("destructive")) != 0) {
1861 if (prop->value() == "true") {
1862 _flags |= Destructive;
1866 if (deprecated_io_node) {
1867 if ((prop = deprecated_io_node->property ("id")) != 0) {
1868 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1871 if ((prop = node.property ("id")) != 0) {
1872 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1876 if ((prop = node.property ("channels")) != 0) {
1877 nchans = atoi (prop->value().c_str());
1880 // create necessary extra channels
1881 // we are always constructed with one
1882 // and we always need one
1884 if (nchans > _n_channels) {
1886 // we need to add new channel infos
1887 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1889 int diff = nchans - channels.size();
1891 for (int i=0; i < diff; ++i) {
1895 } else if (nchans < _n_channels) {
1897 // we need to get rid of channels
1898 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1900 int diff = channels.size() - nchans;
1902 for (int i = 0; i < diff; ++i) {
1907 if ((prop = node.property ("playlist")) == 0) {
1912 bool had_playlist = (_playlist != 0);
1914 if (find_and_use_playlist (prop->value())) {
1918 if (!had_playlist) {
1919 _playlist->set_orig_diskstream_id (_id);
1922 if (capture_pending_node) {
1923 use_pending_capture_data (*capture_pending_node);
1928 if ((prop = node.property ("speed")) != 0) {
1929 double sp = atof (prop->value().c_str());
1931 if (realtime_set_speed (sp, false)) {
1932 non_realtime_set_speed ();
1936 _n_channels = channels.size();
1938 in_set_state = false;
1940 /* now that we're all done with playlist+channel set up,
1941 go ahead and create write sources.
1945 capturing_sources.clear ();
1948 reset_write_sources (false);
1951 in_set_state = false;
1957 DiskStream::use_new_write_source (uint32_t n)
1959 if (!recordable()) {
1963 if (n >= channels.size()) {
1964 error << string_compose (_("DiskStream: channel %1 out of range"), n) << endmsg;
1968 ChannelInfo &chan = channels[n];
1970 if (chan.write_source) {
1972 if (FileSource::is_empty (chan.write_source->path())) {
1973 chan.write_source->mark_for_remove ();
1974 chan.write_source->release();
1975 delete chan.write_source;
1977 chan.write_source->release();
1978 chan.write_source = 0;
1983 if ((chan.write_source = _session.create_file_source (*this, n, destructive())) == 0) {
1984 throw failed_constructor();
1988 catch (failed_constructor &err) {
1989 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1990 chan.write_source = 0;
1994 chan.write_source->use ();
2000 DiskStream::reset_write_sources (bool mark_write_complete, bool force)
2002 ChannelList::iterator chan;
2005 if (!recordable()) {
2009 if (!force && destructive()) {
2013 capturing_sources.clear ();
2015 for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2016 if (mark_write_complete) {
2017 (*chan).write_source->mark_streaming_write_completed ();
2019 use_new_write_source (n);
2020 if (record_enabled()) {
2021 capturing_sources.push_back ((*chan).write_source);
2027 DiskStream::set_block_size (jack_nframes_t nframes)
2029 if (_session.get_block_size() > speed_buffer_size) {
2030 speed_buffer_size = _session.get_block_size();
2032 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2033 if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
2034 (*chan).speed_buffer = new Sample[speed_buffer_size];
2037 allocate_temporary_buffers ();
2041 DiskStream::allocate_temporary_buffers ()
2043 /* make sure the wrap buffer is at least large enough to deal
2044 with the speeds up to 1.2, to allow for micro-variation
2045 when slaving to MTC, SMPTE etc.
2048 double sp = max (fabsf (_actual_speed), 1.2f);
2049 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * sp) + 1;
2051 if (required_wrap_size > wrap_buffer_size) {
2053 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2054 if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
2055 (*chan).playback_wrap_buffer = new Sample[required_wrap_size];
2056 if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
2057 (*chan).capture_wrap_buffer = new Sample[required_wrap_size];
2060 wrap_buffer_size = required_wrap_size;
2065 DiskStream::monitor_input (bool yn)
2067 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2069 if ((*chan).source) {
2070 (*chan).source->request_monitor_input (yn);
2076 DiskStream::set_capture_offset ()
2079 /* can't capture, so forget it */
2083 _capture_offset = _io->input_latency();
2087 DiskStream::set_persistent_align_style (AlignStyle a)
2089 _persistent_alignment_style = a;
2093 DiskStream::set_align_style_from_io ()
2095 bool have_physical = false;
2101 get_input_sources ();
2103 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2104 if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
2105 have_physical = true;
2110 if (have_physical) {
2111 set_align_style (ExistingMaterial);
2113 set_align_style (CaptureTime);
2118 DiskStream::set_align_style (AlignStyle a)
2120 if (record_enabled() && _session.actively_recording()) {
2125 if (a != _alignment_style) {
2126 _alignment_style = a;
2127 AlignmentStyleChanged ();
2132 DiskStream::add_channel ()
2134 /* XXX need to take lock??? */
2138 init_channel (chan);
2140 chan.speed_buffer = new Sample[speed_buffer_size];
2141 chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
2142 chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
2144 channels.push_back (chan);
2146 _n_channels = channels.size();
2152 DiskStream::remove_channel ()
2154 if (channels.size() > 1) {
2155 /* XXX need to take lock??? */
2156 ChannelInfo & chan = channels.back();
2157 destroy_channel (chan);
2158 channels.pop_back();
2160 _n_channels = channels.size();
2168 DiskStream::playback_buffer_load () const
2170 return (float) ((double) channels.front().playback_buf->read_space()/
2171 (double) channels.front().playback_buf->bufsize());
2175 DiskStream::capture_buffer_load () const
2177 return (float) ((double) channels.front().capture_buf->write_space()/
2178 (double) channels.front().capture_buf->bufsize());
2182 DiskStream::set_loop (Location *location)
2185 if (location->start() >= location->end()) {
2186 error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
2191 loop_location = location;
2193 LoopSet (location); /* EMIT SIGNAL */
2198 DiskStream::get_capture_start_frame (uint32_t n)
2200 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2202 if (capture_info.size() > n) {
2203 return capture_info[n]->start;
2206 return capture_start_frame;
2211 DiskStream::get_captured_frames (uint32_t n)
2213 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2215 if (capture_info.size() > n) {
2216 return capture_info[n]->frames;
2219 return capture_captured;
2224 DiskStream::punch_in ()
2229 DiskStream::punch_out ()
2234 DiskStream::use_pending_capture_data (XMLNode& node)
2236 const XMLProperty* prop;
2237 XMLNodeList nlist = node.children();
2238 XMLNodeIterator niter;
2240 FileSource* first_fs = 0;
2241 AudioRegion::SourceList pending_sources;
2242 jack_nframes_t position;
2244 if ((prop = node.property (X_("at"))) == 0) {
2248 if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
2252 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2253 if ((*niter)->name() == X_("file")) {
2255 if ((prop = (*niter)->property (X_("path"))) == 0) {
2260 fs = new FileSource (prop->value(), _session.frame_rate(), true);
2263 catch (failed_constructor& err) {
2264 error << string_compose (_("%1: cannot restore pending capture source file %2"),
2265 _name, prop->value())
2270 pending_sources.push_back (fs);
2272 if (first_fs == 0) {
2276 fs->set_captured_for (_name);
2280 if (pending_sources.size() == 0) {
2281 /* nothing can be done */
2285 if (pending_sources.size() != _n_channels) {
2286 error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2291 AudioRegion* region;
2294 region = new AudioRegion (pending_sources, 0, first_fs->length(),
2295 region_name_from_path (first_fs->name()),
2296 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
2298 region->special_set_position (0);
2301 catch (failed_constructor& err) {
2302 error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
2310 region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
2313 catch (failed_constructor& err) {
2314 error << string_compose (_("%1: cannot create region from pending capture sources"),
2321 _playlist->add_region (*region, position);
2327 DiskStream::set_roll_delay (jack_nframes_t nframes)
2329 _roll_delay = nframes;
2333 DiskStream::set_destructive (bool yn)
2335 if (yn != destructive()) {
2336 reset_write_sources (true, true);
2338 _flags |= Destructive;
2340 _flags &= ~Destructive;