2 Copyright (C) 2000-2003 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 #include <pbd/error.h>
35 #include <pbd/basename.h>
36 #include <pbd/lockmonitor.h>
37 #include <pbd/xml++.h>
39 #include <ardour/ardour.h>
40 #include <ardour/audioengine.h>
41 #include <ardour/diskstream.h>
42 #include <ardour/utils.h>
43 #include <ardour/configuration.h>
44 #include <ardour/filesource.h>
45 #include <ardour/destructive_filesource.h>
46 #include <ardour/send.h>
47 #include <ardour/audioplaylist.h>
48 #include <ardour/cycle_timer.h>
49 #include <ardour/audioregion.h>
55 using namespace ARDOUR;
57 jack_nframes_t DiskStream::disk_io_chunk_frames;
59 sigc::signal<void,DiskStream*> DiskStream::DiskStreamCreated;
60 sigc::signal<void,DiskStream*> DiskStream::CannotRecordNoInput;
61 sigc::signal<void,list<Source*>*> DiskStream::DeleteSources;
62 sigc::signal<void> DiskStream::DiskOverrun;
63 sigc::signal<void> DiskStream::DiskUnderrun;
65 DiskStream::DiskStream (Session &sess, const string &name, Flag flag)
69 /* prevent any write sources from being created */
76 DiskStreamCreated (this); /* EMIT SIGNAL */
79 DiskStream::DiskStream (Session& sess, const XMLNode& node)
86 if (set_state (node)) {
88 throw failed_constructor();
93 DiskStreamCreated (this); /* EMIT SIGNAL */
97 DiskStream::init_channel (ChannelInfo &chan)
99 chan.playback_wrap_buffer = 0;
100 chan.capture_wrap_buffer = 0;
101 chan.speed_buffer = 0;
102 chan.peak_power = 0.0f;
103 chan.write_source = 0;
105 chan.current_capture_buffer = 0;
106 chan.current_playback_buffer = 0;
108 chan.playback_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
109 chan.capture_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
111 /* touch the ringbuffer buffers, which will cause
112 them to be mapped into locked physical RAM if
113 we're running with mlockall(). this doesn't do
116 memset (chan.playback_buf->buffer(), 0, sizeof (Sample) * chan.playback_buf->bufsize());
117 memset (chan.capture_buf->buffer(), 0, sizeof (Sample) * chan.capture_buf->bufsize());
122 DiskStream::init (Flag f)
128 _alignment_style = ExistingMaterial;
129 _persistent_alignment_style = ExistingMaterial;
130 first_input_change = true;
132 i_am_the_modifier = 0;
133 atomic_set (&_record_enabled, 0);
134 was_recording = false;
135 capture_start_frame = 0;
136 capture_captured = 0;
137 _visible_speed = 1.0f;
138 _actual_speed = 1.0f;
139 _buffer_reallocation_required = false;
140 _seek_required = false;
141 first_recordable_frame = max_frames;
142 last_recordable_frame = max_frames;
147 adjust_capture_position = 0;
148 last_possibly_recording = 0;
150 wrap_buffer_size = 0;
151 speed_buffer_size = 0;
153 phi = (uint64_t) (0x1000000);
156 playback_distance = 0;
157 _read_data_count = 0;
158 _write_data_count = 0;
159 deprecated_io_node = 0;
161 /* there are no channels at this point, so these
162 two calls just get speed_buffer_size and wrap_buffer
163 size setup without duplicating their code.
166 set_block_size (_session.get_block_size());
167 allocate_temporary_buffers ();
169 pending_overwrite = false;
171 overwrite_queued = false;
172 input_change_pending = NoChange;
179 DiskStream::destroy_channel (ChannelInfo &chan)
181 if (chan.write_source) {
182 chan.write_source->release ();
183 chan.write_source = 0;
186 if (chan.speed_buffer) {
187 delete [] chan.speed_buffer;
190 if (chan.playback_wrap_buffer) {
191 delete [] chan.playback_wrap_buffer;
193 if (chan.capture_wrap_buffer) {
194 delete [] chan.capture_wrap_buffer;
197 delete chan.playback_buf;
198 delete chan.capture_buf;
200 chan.playback_buf = 0;
201 chan.capture_buf = 0;
204 DiskStream::~DiskStream ()
206 LockMonitor lm (state_lock, __LINE__, __FILE__);
212 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
213 destroy_channel((*chan));
220 DiskStream::handle_input_change (IOChange change, void *src)
222 LockMonitor lm (state_lock, __LINE__, __FILE__);
224 if (!(input_change_pending & change)) {
225 input_change_pending = IOChange (input_change_pending|change);
226 _session.request_input_change_handling ();
231 DiskStream::non_realtime_input_change ()
234 LockMonitor lm (state_lock, __LINE__, __FILE__);
236 if (input_change_pending == NoChange) {
240 if (input_change_pending & ConfigurationChanged) {
242 if (_io->n_inputs() > _n_channels) {
244 // we need to add new channel infos
246 int diff = _io->n_inputs() - channels.size();
248 for (int i = 0; i < diff; ++i) {
252 } else if (_io->n_inputs() < _n_channels) {
254 // we need to get rid of channels
256 int diff = channels.size() - _io->n_inputs();
258 for (int i = 0; i < diff; ++i) {
264 get_input_sources ();
265 set_capture_offset ();
267 if (first_input_change) {
268 set_align_style (_persistent_alignment_style);
269 first_input_change = false;
271 set_align_style_from_io ();
274 input_change_pending = NoChange;
277 /* reset capture files */
279 reset_write_sources (false);
281 /* now refill channel buffers */
283 if (speed() != 1.0f || speed() != -1.0f) {
284 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()));
287 seek (_session.transport_frame());
292 DiskStream::get_input_sources ()
294 uint32_t ni = _io->n_inputs();
296 for (uint32_t n = 0; n < ni; ++n) {
298 const char **connections = _io->input(n)->get_connections ();
299 ChannelInfo& chan = channels[n];
301 if (connections == 0 || connections[0] == 0) {
304 // _source->disable_metering ();
310 chan.source = _session.engine().get_port_by_name (connections[0]);
320 DiskStream::find_and_use_playlist (const string& name)
323 AudioPlaylist* playlist;
325 if ((pl = _session.get_playlist (name)) == 0) {
326 error << string_compose(_("DiskStream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg;
330 if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
331 error << string_compose(_("DiskStream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
335 return use_playlist (playlist);
339 DiskStream::use_playlist (AudioPlaylist* playlist)
342 LockMonitor lm (state_lock, __LINE__, __FILE__);
344 if (playlist == _playlist) {
348 plstate_connection.disconnect();
349 plmod_connection.disconnect ();
350 plgone_connection.disconnect ();
356 _playlist = playlist;
359 if (!in_set_state && recordable()) {
360 reset_write_sources (false);
363 plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &DiskStream::playlist_changed));
364 plmod_connection = _playlist->Modified.connect (mem_fun (*this, &DiskStream::playlist_modified));
365 plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &DiskStream::playlist_deleted));
368 if (!overwrite_queued) {
369 _session.request_overwrite_buffer (this);
370 overwrite_queued = true;
373 PlaylistChanged (); /* EMIT SIGNAL */
374 _session.set_dirty ();
380 DiskStream::playlist_deleted (Playlist* pl)
382 /* this catches an ordering issue with session destruction. playlists
383 are destroyed before diskstreams. we have to invalidate any handles
384 we have to the playlist.
391 DiskStream::use_new_playlist ()
394 AudioPlaylist* playlist;
397 newname = Playlist::bump_name (_playlist->name(), _session);
399 newname = Playlist::bump_name (_name, _session);
402 if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) {
403 playlist->set_orig_diskstream_id (id());
404 return use_playlist (playlist);
411 DiskStream::use_copy_playlist ()
413 if (_playlist == 0) {
414 error << string_compose(_("DiskStream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
419 AudioPlaylist* playlist;
421 newname = Playlist::bump_name (_playlist->name(), _session);
423 if ((playlist = new AudioPlaylist (*_playlist, newname)) != 0) {
424 playlist->set_orig_diskstream_id (id());
425 return use_playlist (playlist);
432 DiskStream::set_io (IO& io)
435 set_align_style_from_io ();
439 DiskStream::set_name (string str, void *src)
442 _playlist->set_name (str);
445 if (!in_set_state && recordable()) {
447 /* open new capture files so that they have the correct name */
449 reset_write_sources (false);
455 DiskStream::set_speed (double sp)
457 _session.request_diskstream_speed (*this, sp);
459 /* to force a rebuffering at the right place */
464 DiskStream::realtime_set_speed (double sp, bool global)
466 bool changed = false;
467 double new_speed = sp * _session.transport_speed();
469 if (_visible_speed != sp) {
474 if (new_speed != _actual_speed) {
476 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() *
477 fabs (new_speed)) + 1;
479 if (required_wrap_size > wrap_buffer_size) {
480 _buffer_reallocation_required = true;
483 _actual_speed = new_speed;
484 phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
489 _seek_required = true;
491 speed_changed (); /* EMIT SIGNAL */
494 return _buffer_reallocation_required || _seek_required;
498 DiskStream::non_realtime_set_speed ()
500 if (_buffer_reallocation_required)
502 LockMonitor lm (state_lock, __LINE__, __FILE__);
503 allocate_temporary_buffers ();
505 _buffer_reallocation_required = false;
508 if (_seek_required) {
509 if (speed() != 1.0f || speed() != -1.0f) {
510 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
513 seek (_session.transport_frame(), true);
516 _seek_required = false;
521 DiskStream::prepare ()
524 playback_distance = 0;
528 DiskStream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
530 int possibly_recording;
533 const int transport_rolling = 0x4;
534 const int track_rec_enabled = 0x2;
535 const int global_rec_enabled = 0x1;
537 /* merge together the 3 factors that affect record status, and compute
541 rolling = _session.transport_speed() != 0.0f;
542 possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
543 change = possibly_recording ^ last_possibly_recording;
545 if (possibly_recording == last_possibly_recording) {
551 /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
553 if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) ||
554 ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
556 /* starting to record: compute first+last frames */
558 first_recordable_frame = transport_frame + _capture_offset;
559 last_recordable_frame = max_frames;
560 capture_start_frame = transport_frame;
562 if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) {
564 /* was stopped, now rolling (and recording) */
566 if (_alignment_style == ExistingMaterial) {
567 first_recordable_frame += _session.worst_output_latency();
569 first_recordable_frame += _roll_delay;
574 /* was rolling, but record state changed */
576 if (_alignment_style == ExistingMaterial) {
579 if (!_session.get_punch_in()) {
581 /* manual punch in happens at the correct transport frame
582 because the user hit a button. but to get alignment correct
583 we have to back up the position of the new region to the
584 appropriate spot given the roll delay.
587 capture_start_frame -= _roll_delay;
589 /* XXX paul notes (august 2005): i don't know why
593 first_recordable_frame += _capture_offset;
597 /* autopunch toggles recording at the precise
598 transport frame, and then the DS waits
599 to start recording for a time that depends
600 on the output latency.
603 first_recordable_frame += _session.worst_output_latency();
608 if (_session.get_punch_in()) {
609 first_recordable_frame += _roll_delay;
611 capture_start_frame -= _roll_delay;
617 if (_flags & Recordable) {
618 cerr << "START RECORD @ " << capture_start_frame << " = " << capture_start_frame * sizeof (Sample) << endl;
619 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
620 (*chan).write_source->mark_capture_start (capture_start_frame);
624 } else if (!record_enabled() || !can_record) {
628 last_recordable_frame = transport_frame + _capture_offset;
630 if (_alignment_style == ExistingMaterial) {
631 last_recordable_frame += _session.worst_output_latency();
633 last_recordable_frame += _roll_delay;
637 last_possibly_recording = possibly_recording;
641 DiskStream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input)
644 ChannelList::iterator c;
646 jack_nframes_t rec_offset = 0;
647 jack_nframes_t rec_nframes = 0;
648 bool nominally_recording;
649 bool re = record_enabled ();
650 bool collect_playback = false;
652 /* if we've already processed the frames corresponding to this call,
653 just return. this allows multiple routes that are taking input
654 from this diskstream to call our ::process() method, but have
655 this stuff only happen once. more commonly, it allows both
656 the AudioTrack that is using this DiskStream *and* the Session
657 to call process() without problems.
664 check_record_status (transport_frame, nframes, can_record);
666 nominally_recording = (can_record && re);
673 /* This lock is held until the end of DiskStream::commit, so these two functions
674 must always be called as a pair. The only exception is if this function
675 returns a non-zero value, in which case, ::commit should not be called.
678 if (pthread_mutex_trylock (state_lock.mutex())) {
682 adjust_capture_position = 0;
684 for (c = channels.begin(); c != channels.end(); ++c) {
685 (*c).current_capture_buffer = 0;
686 (*c).current_playback_buffer = 0;
689 if (nominally_recording || (_session.get_record_enabled() && _session.get_punch_in())) {
692 ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
699 case OverlapInternal:
700 /* ---------- recrange
703 rec_nframes = nframes;
708 /* |--------| recrange
711 rec_nframes = transport_frame + nframes - first_recordable_frame;
713 rec_offset = first_recordable_frame - transport_frame;
718 /* |--------| recrange
721 rec_nframes = last_recordable_frame - transport_frame;
725 case OverlapExternal:
726 /* |--------| recrange
727 -------------- transrange
729 rec_nframes = last_recordable_frame - last_recordable_frame;
730 rec_offset = first_recordable_frame - transport_frame;
734 if (rec_nframes && !was_recording) {
735 capture_captured = 0;
736 was_recording = true;
741 if (can_record && !_last_capture_regions.empty()) {
742 _last_capture_regions.clear ();
745 if (nominally_recording || rec_nframes) {
747 for (n = 0, c = channels.begin(); c != channels.end(); ++c, ++n) {
749 ChannelInfo& chan (*c);
751 chan.capture_buf->get_write_vector (&chan.capture_vector);
753 if (rec_nframes <= chan.capture_vector.len[0]) {
755 chan.current_capture_buffer = chan.capture_vector.buf[0];
757 /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use
761 memcpy (chan.current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes);
765 jack_nframes_t total = chan.capture_vector.len[0] + chan.capture_vector.len[1];
767 if (rec_nframes > total) {
772 Sample* buf = _io->input (n)->get_buffer (nframes) + offset;
773 jack_nframes_t first = chan.capture_vector.len[0];
775 memcpy (chan.capture_wrap_buffer, buf, sizeof (Sample) * first);
776 memcpy (chan.capture_vector.buf[0], buf, sizeof (Sample) * first);
777 memcpy (chan.capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first));
778 memcpy (chan.capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first));
780 chan.current_capture_buffer = chan.capture_wrap_buffer;
787 finish_capture (rec_monitors_input);
794 /* data will be written to disk */
796 if (rec_nframes == nframes && rec_offset == 0) {
798 for (c = channels.begin(); c != channels.end(); ++c) {
799 (*c).current_playback_buffer = (*c).current_capture_buffer;
802 playback_distance = nframes;
807 /* we can't use the capture buffer as the playback buffer, because
808 we recorded only a part of the current process' cycle data
812 collect_playback = true;
815 adjust_capture_position = rec_nframes;
817 } else if (nominally_recording) {
819 /* can't do actual capture yet - waiting for latency effects to finish before we start*/
821 for (c = channels.begin(); c != channels.end(); ++c) {
822 (*c).current_playback_buffer = (*c).current_capture_buffer;
825 playback_distance = nframes;
829 collect_playback = true;
832 if (collect_playback) {
834 /* we're doing playback */
836 jack_nframes_t necessary_samples;
838 /* no varispeed playback if we're recording, because the output .... TBD */
840 if (rec_nframes == 0 && _actual_speed != 1.0f) {
841 necessary_samples = (jack_nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
843 necessary_samples = nframes;
846 for (c = channels.begin(); c != channels.end(); ++c) {
847 (*c).playback_buf->get_read_vector (&(*c).playback_vector);
852 for (c = channels.begin(); c != channels.end(); ++c, ++n) {
854 ChannelInfo& chan (*c);
856 if (necessary_samples <= chan.playback_vector.len[0]) {
858 chan.current_playback_buffer = chan.playback_vector.buf[0];
861 jack_nframes_t total = chan.playback_vector.len[0] + chan.playback_vector.len[1];
863 if (necessary_samples > total) {
869 memcpy ((char *) chan.playback_wrap_buffer, chan.playback_vector.buf[0],
870 chan.playback_vector.len[0] * sizeof (Sample));
871 memcpy (chan.playback_wrap_buffer + chan.playback_vector.len[0], chan.playback_vector.buf[1],
872 (necessary_samples - chan.playback_vector.len[0]) * sizeof (Sample));
874 chan.current_playback_buffer = chan.playback_wrap_buffer;
879 if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
881 uint64_t phase = last_phase;
882 jack_nframes_t i = 0;
884 // Linearly interpolate into the alt buffer
885 // using 40.24 fixp maths (swh)
887 for (c = channels.begin(); c != channels.end(); ++c) {
890 ChannelInfo& chan (*c);
895 for (jack_nframes_t outsample = 0; outsample < nframes; ++outsample) {
897 fr = (phase & 0xFFFFFF) / 16777216.0f;
898 chan.speed_buffer[outsample] =
899 chan.current_playback_buffer[i] * (1.0f - fr) +
900 chan.current_playback_buffer[i+1] * fr;
904 chan.current_playback_buffer = chan.speed_buffer;
907 playback_distance = i + 1;
908 last_phase = (phase & 0xFFFFFF);
911 playback_distance = nframes;
923 /* we're exiting with failure, so ::commit will not
924 be called. unlock the state lock.
927 pthread_mutex_unlock (state_lock.mutex());
934 DiskStream::recover ()
936 pthread_mutex_unlock (state_lock.mutex());
941 DiskStream::commit (jack_nframes_t nframes)
943 bool need_butler = false;
945 if (_actual_speed < 0.0) {
946 playback_sample -= playback_distance;
948 playback_sample += playback_distance;
951 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
953 (*chan).playback_buf->increment_read_ptr (playback_distance);
955 if (adjust_capture_position) {
956 (*chan).capture_buf->increment_write_ptr (adjust_capture_position);
960 if (adjust_capture_position != 0) {
961 capture_captured += adjust_capture_position;
962 adjust_capture_position = 0;
966 need_butler = channels[0].playback_buf->write_space() >= channels[0].playback_buf->bufsize() / 2;
968 need_butler = channels[0].playback_buf->write_space() >= disk_io_chunk_frames
969 || channels[0].capture_buf->read_space() >= disk_io_chunk_frames;
972 pthread_mutex_unlock (state_lock.mutex());
980 DiskStream::set_pending_overwrite (bool yn)
982 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
984 pending_overwrite = yn;
986 overwrite_frame = playback_sample;
987 overwrite_offset = channels.front().playback_buf->get_read_ptr();
991 DiskStream::overwrite_existing_buffers ()
993 Sample* mixdown_buffer;
997 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
999 overwrite_queued = false;
1001 /* assume all are the same size */
1002 jack_nframes_t size = channels[0].playback_buf->bufsize();
1004 mixdown_buffer = new Sample[size];
1005 gain_buffer = new float[size];
1006 workbuf = new char[size*4];
1008 /* reduce size so that we can fill the buffer correctly. */
1012 jack_nframes_t start;
1014 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1016 start = overwrite_frame;
1017 jack_nframes_t cnt = size;
1019 /* to fill the buffer without resetting the playback sample, we need to
1020 do it one or two chunks (normally two).
1022 |----------------------------------------------------------------------|
1026 |<- second chunk->||<----------------- first chunk ------------------>|
1030 jack_nframes_t to_read = size - overwrite_offset;
1032 if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, workbuf,
1033 start, to_read, *chan, n, reversed)) {
1034 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1035 _id, size, playback_sample) << endmsg;
1039 if (cnt > to_read) {
1043 if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer, workbuf,
1044 start, cnt, *chan, n, reversed)) {
1045 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1046 _id, size, playback_sample) << endmsg;
1055 pending_overwrite = false;
1056 delete [] gain_buffer;
1057 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 ();
1073 if ((*chan).write_source) {
1074 (*chan).write_source->seek (frame);
1078 playback_sample = frame;
1081 if (complete_refill) {
1082 while ((ret = do_refill (0, 0, 0)) > 0);
1084 ret = do_refill (0, 0, 0);
1091 DiskStream::can_internal_playback_seek (jack_nframes_t distance)
1093 ChannelList::iterator chan;
1095 for (chan = channels.begin(); chan != channels.end(); ++chan) {
1096 if ((*chan).playback_buf->read_space() < distance) {
1104 DiskStream::internal_playback_seek (jack_nframes_t distance)
1106 ChannelList::iterator chan;
1108 for (chan = channels.begin(); chan != channels.end(); ++chan) {
1109 (*chan).playback_buf->increment_read_ptr (distance);
1112 first_recordable_frame += distance;
1113 playback_sample += distance;
1119 DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt,
1120 ChannelInfo& channel_info, int channel, bool reversed)
1122 jack_nframes_t this_read = 0;
1123 bool reloop = false;
1124 jack_nframes_t loop_end = 0;
1125 jack_nframes_t loop_start = 0;
1126 jack_nframes_t loop_length = 0;
1127 jack_nframes_t offset = 0;
1131 /* Make the use of a Location atomic for this read operation.
1133 Note: Locations don't get deleted, so all we care about
1134 when I say "atomic" is that we are always pointing to
1135 the same one and using a start/length values obtained
1139 if ((loc = loop_location) != 0) {
1140 loop_start = loc->start();
1141 loop_end = loc->end();
1142 loop_length = loop_end - loop_start;
1145 /* if we are looping, ensure that the first frame we read is at the correct
1146 position within the loop.
1149 if (loc && start >= loop_end) {
1150 //cerr << "start adjusted from " << start;
1151 start = loop_start + ((start - loop_start) % loop_length);
1152 //cerr << "to " << start << endl;
1154 //cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
1159 /* take any loop into account. we can't read past the end of the loop. */
1161 if (loc && (loop_end - start < cnt)) {
1162 this_read = loop_end - start;
1163 //cerr << "reloop true: thisread: " << this_read << " cnt: " << cnt << endl;
1170 if (this_read == 0) {
1174 this_read = min(cnt,this_read);
1176 if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
1177 error << string_compose(_("DiskStream %1: cannot read %2 from playlist at frame %3"), _id, this_read,
1182 _read_data_count = _playlist->read_data_count();
1186 /* don't adjust start, since caller has already done that
1189 swap_by_ptr (buf, buf + this_read - 1);
1193 /* if we read to the end of the loop, go back to the beginning */
1203 offset += this_read;
1210 DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
1213 jack_nframes_t to_read;
1214 RingBufferNPT<Sample>::rw_vector vector;
1218 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1219 jack_nframes_t total_space;
1220 jack_nframes_t zero_fill;
1222 ChannelList::iterator i;
1225 channels.front().playback_buf->get_write_vector (&vector);
1227 if ((total_space = vector.len[0] + vector.len[1]) == 0) {
1231 /* if there are 2+ chunks of disk i/o possible for
1232 this track, let the caller know so that it can arrange
1233 for us to be called again, ASAP.
1236 if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) {
1240 /* if we're running close to normal speed and there isn't enough
1241 space to do disk_io_chunk_frames of I/O, then don't bother.
1243 at higher speeds, just do it because the sync between butler
1244 and audio thread may not be good enough.
1247 if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
1251 /* when slaved, don't try to get too close to the read pointer. this
1252 leaves space for the buffer reversal to have something useful to
1256 if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) {
1260 total_space = min (disk_io_chunk_frames, total_space);
1264 if (file_frame == 0) {
1266 /* at start: nothing to do but fill with silence */
1268 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1270 ChannelInfo& chan (*i);
1271 chan.playback_buf->get_write_vector (&vector);
1272 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1273 if (vector.len[1]) {
1274 memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1276 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1281 if (file_frame < total_space) {
1283 /* too close to the start: read what we can,
1284 and then zero fill the rest
1287 zero_fill = total_space - file_frame;
1288 total_space = file_frame;
1293 /* move read position backwards because we are going
1294 to reverse the data.
1297 file_frame -= total_space;
1303 if (file_frame == max_frames) {
1305 /* at end: nothing to do but fill with silence */
1307 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1309 ChannelInfo& chan (*i);
1310 chan.playback_buf->get_write_vector (&vector);
1311 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1312 if (vector.len[1]) {
1313 memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1315 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1320 if (file_frame > max_frames - total_space) {
1322 /* to close to the end: read what we can, and zero fill the rest */
1324 zero_fill = total_space - (max_frames - file_frame);
1325 total_space = max_frames - file_frame;
1332 /* Please note: the code to allocate buffers isn't run
1333 during normal butler thread operation. Its there
1334 for other times when we need to call do_refill()
1335 from somewhere other than the butler thread.
1338 if (mixdown_buffer == 0) {
1339 mixdown_buffer = new Sample[disk_io_chunk_frames];
1340 free_mixdown = true;
1342 free_mixdown = false;
1345 if (gain_buffer == 0) {
1346 gain_buffer = new float[disk_io_chunk_frames];
1353 workbuf = new char[disk_io_chunk_frames * 4];
1354 free_workbuf = true;
1356 free_workbuf = false;
1359 jack_nframes_t file_frame_tmp = 0;
1361 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1363 ChannelInfo& chan (*i);
1366 jack_nframes_t len1, len2;
1368 chan.playback_buf->get_write_vector (&vector);
1371 file_frame_tmp = file_frame;
1374 buf1 = vector.buf[1];
1375 len1 = vector.len[1];
1376 buf2 = vector.buf[0];
1377 len2 = vector.len[0];
1379 buf1 = vector.buf[0];
1380 len1 = vector.len[0];
1381 buf2 = vector.buf[1];
1382 len2 = vector.len[1];
1386 to_read = min (ts, len1);
1387 to_read = min (to_read, disk_io_chunk_frames);
1391 if (read (buf1, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1396 chan.playback_buf->increment_write_ptr (to_read);
1400 to_read = min (ts, len2);
1405 /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data,
1406 so read some or all of vector.len[1] as well.
1409 if (read (buf2, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1414 chan.playback_buf->increment_write_ptr (to_read);
1423 file_frame = file_frame_tmp;
1427 delete [] mixdown_buffer;
1430 delete [] gain_buffer;
1440 DiskStream::do_flush (char * workbuf, bool force_flush)
1444 RingBufferNPT<Sample>::rw_vector vector;
1445 jack_nframes_t total;
1447 /* important note: this function will write *AT MOST*
1448 disk_io_chunk_frames of data to disk. it will never
1449 write more than that. if its writes that much and there
1450 is more than that waiting to be written, it will return 1,
1451 otherwise 0 on success or -1 on failure.
1453 if there is less than disk_io_chunk_frames to be written,
1454 no data will be written at all unless `force_flush' is true.
1457 _write_data_count = 0;
1459 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1461 (*chan).capture_buf->get_read_vector (&vector);
1463 total = vector.len[0] + vector.len[1];
1465 if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
1469 /* if there are 2+ chunks of disk i/o possible for
1470 this track, let the caller know so that it can arrange
1471 for us to be called again, ASAP.
1473 if we are forcing a flush, then if there is* any* extra
1474 work, let the caller know.
1476 if we are no longer recording and there is any extra work,
1477 let the caller know too.
1480 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
1484 to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
1486 if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write, workbuf) != to_write) {
1487 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1491 (*chan).capture_buf->increment_read_ptr (to_write);
1493 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames)) {
1495 /* we wrote all of vector.len[0] but it wasn't an entire
1496 disk_io_chunk_frames of data, so arrange for some part
1497 of vector.len[1] to be flushed to disk as well.
1500 to_write = min ((jack_nframes_t)(disk_io_chunk_frames - to_write), (jack_nframes_t) vector.len[1]);
1502 if ((*chan).write_source->write (vector.buf[1], to_write, workbuf) != to_write) {
1503 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1507 _write_data_count += (*chan).write_source->write_data_count();
1509 (*chan).capture_buf->increment_read_ptr (to_write);
1518 DiskStream::playlist_changed (Change ignored)
1520 playlist_modified ();
1524 DiskStream::playlist_modified ()
1526 if (!i_am_the_modifier && !overwrite_queued) {
1527 _session.request_overwrite_buffer (this);
1528 overwrite_queued = true;
1533 DiskStream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
1535 uint32_t buffer_position;
1536 bool more_work = true;
1538 AudioRegion* region = 0;
1539 jack_nframes_t total_capture;
1540 AudioRegion::SourceList srcs;
1541 AudioRegion::SourceList::iterator src;
1542 ChannelList::iterator chan;
1543 vector<CaptureInfo*>::iterator ci;
1545 list<Source*>* deletion_list;
1546 bool mark_write_completed = false;
1548 finish_capture (true);
1550 /* butler is already stopped, but there may be work to do
1551 to flush remaining data to disk.
1554 while (more_work && !err) {
1555 switch (do_flush ( _session.conversion_buffer(Session::TransportContext), true)) {
1562 error << string_compose(_("DiskStream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1567 /* XXX is there anything we can do if err != 0 ? */
1568 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
1570 if (capture_info.empty()) {
1574 if (abort_capture) {
1576 ChannelList::iterator chan;
1578 deletion_list = new list<Source*>;
1580 for ( chan = channels.begin(); chan != channels.end(); ++chan) {
1582 if ((*chan).write_source) {
1584 (*chan).write_source->mark_for_remove ();
1585 (*chan).write_source->release ();
1587 deletion_list->push_back ((*chan).write_source);
1589 (*chan).write_source = 0;
1592 /* new source set up in "out" below */
1595 if (!deletion_list->empty()) {
1596 DeleteSources (deletion_list);
1598 delete deletion_list;
1604 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1605 total_capture += (*ci)->frames;
1608 /* figure out the name for this take */
1610 for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1612 Source* s = (*chan).write_source;
1620 if ((fsrc = dynamic_cast<FileSource *>(s)) != 0) {
1621 fsrc->update_header (capture_info.front()->start, when, twhen);
1624 s->set_captured_for (_name);
1629 /* Register a new region with the Session that
1630 describes the entire source. Do this first
1631 so that any sub-regions will obviously be
1632 children of this one (later!)
1636 region = new AudioRegion (srcs, channels[0].write_source->last_capture_start_frame(), total_capture,
1637 region_name_from_path (channels[0].write_source->name()),
1638 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
1640 region->special_set_position (capture_info.front()->start);
1643 catch (failed_constructor& err) {
1644 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1648 _last_capture_regions.push_back (region);
1650 // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
1652 _session.add_undo (_playlist->get_memento());
1653 _playlist->freeze ();
1655 for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1658 _session.region_name (region_name, _name, false);
1660 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1663 region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
1666 catch (failed_constructor& err) {
1667 error << _("DiskStream: could not create region for captured audio!") << endmsg;
1668 continue; /* XXX is this OK? */
1671 _last_capture_regions.push_back (region);
1673 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1675 i_am_the_modifier++;
1676 _playlist->add_region (*region, (*ci)->start);
1677 i_am_the_modifier--;
1679 buffer_position += (*ci)->frames;
1683 _session.add_redo_no_execute (_playlist->get_memento());
1685 mark_write_completed = true;
1687 reset_write_sources (mark_write_completed);
1690 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1694 capture_info.clear ();
1695 capture_start_frame = 0;
1699 DiskStream::finish_capture (bool rec_monitors_input)
1701 was_recording = false;
1703 if (_flags & Recordable) {
1704 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1705 (*chan).write_source->mark_capture_end ();
1709 if (capture_captured == 0) {
1713 CaptureInfo* ci = new CaptureInfo;
1715 ci->start = capture_start_frame;
1716 ci->frames = capture_captured;
1718 /* XXX theoretical race condition here. Need atomic exchange ?
1719 However, the circumstances when this is called right
1720 now (either on record-disable or transport_stopped)
1721 mean that no actual race exists. I think ...
1722 We now have a capture_info_lock, but it is only to be used
1723 to synchronize in the transport_stop and the capture info
1724 accessors, so that invalidation will not occur (both non-realtime).
1727 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1729 capture_info.push_back (ci);
1730 capture_captured = 0;
1734 DiskStream::set_record_enabled (bool yn, void* src)
1736 bool rolling = _session.transport_speed() != 0.0f;
1738 if (!recordable() || !_session.record_enabling_legal()) {
1742 /* if we're turning on rec-enable, there needs to be an
1746 if (yn && channels[0].source == 0) {
1748 /* pick up connections not initiated *from* the IO object
1749 we're associated with.
1752 get_input_sources ();
1754 if (channels[0].source == 0) {
1757 CannotRecordNoInput (this); /* emit signal */
1763 /* yes, i know that this not proof against race conditions, but its
1764 good enough. i think.
1767 if (record_enabled() != yn) {
1769 atomic_set (&_record_enabled, 1);
1770 capturing_sources.clear ();
1771 if (Config->get_use_hardware_monitoring()) {
1772 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1773 if ((*chan).source) {
1774 (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
1776 capturing_sources.push_back ((*chan).write_source);
1779 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1780 capturing_sources.push_back ((*chan).write_source);
1785 atomic_set (&_record_enabled, 0);
1786 if (Config->get_use_hardware_monitoring()) {
1787 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1788 if ((*chan).source) {
1789 (*chan).source->request_monitor_input (false);
1793 capturing_sources.clear ();
1796 record_enable_changed (src); /* EMIT SIGNAL */
1801 DiskStream::get_state ()
1803 XMLNode* node = new XMLNode ("DiskStream");
1805 LocaleGuard lg (X_("POSIX"));
1807 if (destructive()) {
1808 node->add_property ("destructive", "true");
1811 snprintf (buf, sizeof(buf), "%zd", channels.size());
1812 node->add_property ("channels", buf);
1814 node->add_property ("playlist", _playlist->name());
1816 snprintf (buf, sizeof(buf), "%f", _visible_speed);
1817 node->add_property ("speed", buf);
1819 node->add_property("name", _name);
1820 snprintf (buf, sizeof(buf), "%" PRIu64, id());
1821 node->add_property("id", buf);
1823 if (!capturing_sources.empty() && _session.get_record_enabled()) {
1825 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1826 XMLNode* cs_grandchild;
1828 for (vector<FileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1829 cs_grandchild = new XMLNode (X_("file"));
1830 cs_grandchild->add_property (X_("path"), (*i)->path());
1831 cs_child->add_child_nocopy (*cs_grandchild);
1834 /* store the location where capture will start */
1838 if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1839 snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
1841 snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
1844 cs_child->add_property (X_("at"), buf);
1845 node->add_child_nocopy (*cs_child);
1849 node->add_child_copy (*_extra_xml);
1856 DiskStream::set_state (const XMLNode& node)
1858 const XMLProperty* prop;
1859 XMLNodeList nlist = node.children();
1860 XMLNodeIterator niter;
1861 uint32_t nchans = 1;
1862 XMLNode* capture_pending_node = 0;
1863 LocaleGuard lg (X_("POSIX"));
1865 in_set_state = true;
1867 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1868 if ((*niter)->name() == IO::state_node_name) {
1869 deprecated_io_node = new XMLNode (**niter);
1872 if ((*niter)->name() == X_("CapturingSources")) {
1873 capture_pending_node = *niter;
1877 /* prevent write sources from being created */
1879 in_set_state = true;
1881 if ((prop = node.property ("name")) != 0) {
1882 _name = prop->value();
1885 if ((prop = node.property ("destructive")) != 0) {
1886 if (prop->value() == "true") {
1887 _flags |= Destructive;
1891 if (deprecated_io_node) {
1892 if ((prop = deprecated_io_node->property ("id")) != 0) {
1893 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1896 if ((prop = node.property ("id")) != 0) {
1897 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1901 if ((prop = node.property ("channels")) != 0) {
1902 nchans = atoi (prop->value().c_str());
1905 // create necessary extra channels
1906 // we are always constructed with one
1907 // and we always need one
1909 if (nchans > _n_channels) {
1911 // we need to add new channel infos
1912 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1914 int diff = nchans - channels.size();
1916 for (int i=0; i < diff; ++i) {
1920 } else if (nchans < _n_channels) {
1922 // we need to get rid of channels
1923 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1925 int diff = channels.size() - nchans;
1927 for (int i = 0; i < diff; ++i) {
1932 if ((prop = node.property ("playlist")) == 0) {
1937 bool had_playlist = (_playlist != 0);
1939 if (find_and_use_playlist (prop->value())) {
1943 if (!had_playlist) {
1944 _playlist->set_orig_diskstream_id (_id);
1947 if (capture_pending_node) {
1948 use_pending_capture_data (*capture_pending_node);
1953 if ((prop = node.property ("speed")) != 0) {
1954 double sp = atof (prop->value().c_str());
1956 if (realtime_set_speed (sp, false)) {
1957 non_realtime_set_speed ();
1961 _n_channels = channels.size();
1963 in_set_state = false;
1965 /* now that we're all done with playlist+channel set up,
1966 go ahead and create write sources.
1970 capturing_sources.clear ();
1973 reset_write_sources (false);
1976 in_set_state = false;
1982 DiskStream::use_new_write_source (uint32_t n)
1984 if (!recordable()) {
1988 if (n >= channels.size()) {
1989 error << string_compose (_("DiskStream: channel %1 out of range"), n) << endmsg;
1993 ChannelInfo &chan = channels[n];
1995 if (chan.write_source) {
1997 if (FileSource::is_empty (chan.write_source->path())) {
1998 chan.write_source->mark_for_remove ();
1999 chan.write_source->release();
2000 delete chan.write_source;
2002 chan.write_source->release();
2003 chan.write_source = 0;
2008 if ((chan.write_source = _session.create_file_source (*this, n, destructive())) == 0) {
2009 throw failed_constructor();
2013 catch (failed_constructor &err) {
2014 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
2015 chan.write_source = 0;
2019 chan.write_source->use ();
2025 DiskStream::reset_write_sources (bool mark_write_complete, bool force)
2027 ChannelList::iterator chan;
2030 if (!recordable()) {
2034 if (!force && destructive()) {
2036 /* make sure we always have enough sources for the current channel count */
2038 for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2039 if ((*chan).write_source == 0) {
2044 if (chan == channels.end()) {
2048 /* some channels do not have a write source */
2051 capturing_sources.clear ();
2053 for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2054 if (mark_write_complete) {
2055 (*chan).write_source->mark_streaming_write_completed ();
2057 use_new_write_source (n);
2058 if (record_enabled()) {
2059 capturing_sources.push_back ((*chan).write_source);
2065 DiskStream::set_block_size (jack_nframes_t nframes)
2067 if (_session.get_block_size() > speed_buffer_size) {
2068 speed_buffer_size = _session.get_block_size();
2070 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2071 if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
2072 (*chan).speed_buffer = new Sample[speed_buffer_size];
2075 allocate_temporary_buffers ();
2079 DiskStream::allocate_temporary_buffers ()
2081 /* make sure the wrap buffer is at least large enough to deal
2082 with the speeds up to 1.2, to allow for micro-variation
2083 when slaving to MTC, SMPTE etc.
2086 double sp = max (fabsf (_actual_speed), 1.2f);
2087 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * sp) + 1;
2089 if (required_wrap_size > wrap_buffer_size) {
2091 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2092 if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
2093 (*chan).playback_wrap_buffer = new Sample[required_wrap_size];
2094 if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
2095 (*chan).capture_wrap_buffer = new Sample[required_wrap_size];
2098 wrap_buffer_size = required_wrap_size;
2103 DiskStream::monitor_input (bool yn)
2105 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2107 if ((*chan).source) {
2108 (*chan).source->request_monitor_input (yn);
2114 DiskStream::set_capture_offset ()
2117 /* can't capture, so forget it */
2121 _capture_offset = _io->input_latency();
2125 DiskStream::set_persistent_align_style (AlignStyle a)
2127 _persistent_alignment_style = a;
2131 DiskStream::set_align_style_from_io ()
2133 bool have_physical = false;
2139 get_input_sources ();
2141 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2142 if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
2143 have_physical = true;
2148 if (have_physical) {
2149 set_align_style (ExistingMaterial);
2151 set_align_style (CaptureTime);
2156 DiskStream::set_align_style (AlignStyle a)
2158 if (record_enabled() && _session.actively_recording()) {
2163 if (a != _alignment_style) {
2164 _alignment_style = a;
2165 AlignmentStyleChanged ();
2170 DiskStream::add_channel ()
2172 /* XXX need to take lock??? */
2176 init_channel (chan);
2178 chan.speed_buffer = new Sample[speed_buffer_size];
2179 chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
2180 chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
2182 channels.push_back (chan);
2184 _n_channels = channels.size();
2190 DiskStream::remove_channel ()
2192 if (channels.size() > 1) {
2193 /* XXX need to take lock??? */
2194 ChannelInfo & chan = channels.back();
2195 destroy_channel (chan);
2196 channels.pop_back();
2198 _n_channels = channels.size();
2206 DiskStream::playback_buffer_load () const
2208 return (float) ((double) channels.front().playback_buf->read_space()/
2209 (double) channels.front().playback_buf->bufsize());
2213 DiskStream::capture_buffer_load () const
2215 return (float) ((double) channels.front().capture_buf->write_space()/
2216 (double) channels.front().capture_buf->bufsize());
2220 DiskStream::set_loop (Location *location)
2223 if (location->start() >= location->end()) {
2224 error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
2229 loop_location = location;
2231 LoopSet (location); /* EMIT SIGNAL */
2236 DiskStream::get_capture_start_frame (uint32_t n)
2238 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2240 if (capture_info.size() > n) {
2241 return capture_info[n]->start;
2244 return capture_start_frame;
2249 DiskStream::get_captured_frames (uint32_t n)
2251 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2253 if (capture_info.size() > n) {
2254 return capture_info[n]->frames;
2257 return capture_captured;
2262 DiskStream::punch_in ()
2267 DiskStream::punch_out ()
2272 DiskStream::use_pending_capture_data (XMLNode& node)
2274 const XMLProperty* prop;
2275 XMLNodeList nlist = node.children();
2276 XMLNodeIterator niter;
2278 FileSource* first_fs = 0;
2279 AudioRegion::SourceList pending_sources;
2280 jack_nframes_t position;
2282 if ((prop = node.property (X_("at"))) == 0) {
2286 if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
2290 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2291 if ((*niter)->name() == X_("file")) {
2293 if ((prop = (*niter)->property (X_("path"))) == 0) {
2298 fs = new FileSource (prop->value(), _session.frame_rate(), true);
2301 catch (failed_constructor& err) {
2302 error << string_compose (_("%1: cannot restore pending capture source file %2"),
2303 _name, prop->value())
2308 pending_sources.push_back (fs);
2310 if (first_fs == 0) {
2314 fs->set_captured_for (_name);
2318 if (pending_sources.size() == 0) {
2319 /* nothing can be done */
2323 if (pending_sources.size() != _n_channels) {
2324 error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2329 AudioRegion* region;
2332 region = new AudioRegion (pending_sources, 0, first_fs->length(),
2333 region_name_from_path (first_fs->name()),
2334 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
2336 region->special_set_position (0);
2339 catch (failed_constructor& err) {
2340 error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
2348 region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
2351 catch (failed_constructor& err) {
2352 error << string_compose (_("%1: cannot create region from pending capture sources"),
2359 _playlist->add_region (*region, position);
2365 DiskStream::set_roll_delay (jack_nframes_t nframes)
2367 _roll_delay = nframes;
2371 DiskStream::set_destructive (bool yn)
2373 if (yn != destructive()) {
2374 reset_write_sources (true, true);
2376 _flags |= Destructive;
2378 _flags &= ~Destructive;