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;
107 chan.curr_capture_cnt = 0;
109 chan.playback_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
110 chan.capture_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
111 chan.capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
114 /* touch the ringbuffer buffers, which will cause
115 them to be mapped into locked physical RAM if
116 we're running with mlockall(). this doesn't do
119 memset (chan.playback_buf->buffer(), 0, sizeof (Sample) * chan.playback_buf->bufsize());
120 memset (chan.capture_buf->buffer(), 0, sizeof (Sample) * chan.capture_buf->bufsize());
121 memset (chan.capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * chan.capture_transition_buf->bufsize());
126 DiskStream::init (Flag f)
132 _alignment_style = ExistingMaterial;
133 _persistent_alignment_style = ExistingMaterial;
134 first_input_change = true;
136 i_am_the_modifier = 0;
137 atomic_set (&_record_enabled, 0);
138 was_recording = false;
139 capture_start_frame = 0;
140 capture_captured = 0;
141 _visible_speed = 1.0f;
142 _actual_speed = 1.0f;
143 _buffer_reallocation_required = false;
144 _seek_required = false;
145 first_recordable_frame = max_frames;
146 last_recordable_frame = max_frames;
151 adjust_capture_position = 0;
152 last_possibly_recording = 0;
154 wrap_buffer_size = 0;
155 speed_buffer_size = 0;
157 phi = (uint64_t) (0x1000000);
160 playback_distance = 0;
161 _read_data_count = 0;
162 _write_data_count = 0;
163 deprecated_io_node = 0;
165 /* there are no channels at this point, so these
166 two calls just get speed_buffer_size and wrap_buffer
167 size setup without duplicating their code.
170 set_block_size (_session.get_block_size());
171 allocate_temporary_buffers ();
173 pending_overwrite = false;
175 overwrite_queued = false;
176 input_change_pending = NoChange;
183 DiskStream::destroy_channel (ChannelInfo &chan)
185 if (chan.write_source) {
186 chan.write_source->release ();
187 chan.write_source = 0;
190 if (chan.speed_buffer) {
191 delete [] chan.speed_buffer;
194 if (chan.playback_wrap_buffer) {
195 delete [] chan.playback_wrap_buffer;
197 if (chan.capture_wrap_buffer) {
198 delete [] chan.capture_wrap_buffer;
201 delete chan.playback_buf;
202 delete chan.capture_buf;
203 delete chan.capture_transition_buf;
205 chan.playback_buf = 0;
206 chan.capture_buf = 0;
209 DiskStream::~DiskStream ()
211 LockMonitor lm (state_lock, __LINE__, __FILE__);
217 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
218 destroy_channel((*chan));
225 DiskStream::handle_input_change (IOChange change, void *src)
227 LockMonitor lm (state_lock, __LINE__, __FILE__);
229 if (!(input_change_pending & change)) {
230 input_change_pending = IOChange (input_change_pending|change);
231 _session.request_input_change_handling ();
236 DiskStream::non_realtime_input_change ()
239 LockMonitor lm (state_lock, __LINE__, __FILE__);
241 if (input_change_pending == NoChange) {
245 if (input_change_pending & ConfigurationChanged) {
247 if (_io->n_inputs() > _n_channels) {
249 // we need to add new channel infos
251 int diff = _io->n_inputs() - channels.size();
253 for (int i = 0; i < diff; ++i) {
257 } else if (_io->n_inputs() < _n_channels) {
259 // we need to get rid of channels
261 int diff = channels.size() - _io->n_inputs();
263 for (int i = 0; i < diff; ++i) {
269 get_input_sources ();
270 set_capture_offset ();
272 if (first_input_change) {
273 set_align_style (_persistent_alignment_style);
274 first_input_change = false;
276 set_align_style_from_io ();
279 input_change_pending = NoChange;
282 /* reset capture files */
284 reset_write_sources (false);
286 /* now refill channel buffers */
288 if (speed() != 1.0f || speed() != -1.0f) {
289 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()));
292 seek (_session.transport_frame());
297 DiskStream::get_input_sources ()
299 uint32_t ni = _io->n_inputs();
301 for (uint32_t n = 0; n < ni; ++n) {
303 const char **connections = _io->input(n)->get_connections ();
304 ChannelInfo& chan = channels[n];
306 if (connections == 0 || connections[0] == 0) {
309 // _source->disable_metering ();
315 chan.source = _session.engine().get_port_by_name (connections[0]);
325 DiskStream::find_and_use_playlist (const string& name)
328 AudioPlaylist* playlist;
330 if ((pl = _session.get_playlist (name)) == 0) {
331 error << string_compose(_("DiskStream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg;
335 if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
336 error << string_compose(_("DiskStream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
340 return use_playlist (playlist);
344 DiskStream::use_playlist (AudioPlaylist* playlist)
347 LockMonitor lm (state_lock, __LINE__, __FILE__);
349 if (playlist == _playlist) {
353 plstate_connection.disconnect();
354 plmod_connection.disconnect ();
355 plgone_connection.disconnect ();
361 _playlist = playlist;
364 if (!in_set_state && recordable()) {
365 reset_write_sources (false);
368 plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &DiskStream::playlist_changed));
369 plmod_connection = _playlist->Modified.connect (mem_fun (*this, &DiskStream::playlist_modified));
370 plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &DiskStream::playlist_deleted));
373 if (!overwrite_queued) {
374 _session.request_overwrite_buffer (this);
375 overwrite_queued = true;
378 PlaylistChanged (); /* EMIT SIGNAL */
379 _session.set_dirty ();
385 DiskStream::playlist_deleted (Playlist* pl)
387 /* this catches an ordering issue with session destruction. playlists
388 are destroyed before diskstreams. we have to invalidate any handles
389 we have to the playlist.
396 DiskStream::use_new_playlist ()
399 AudioPlaylist* playlist;
402 newname = Playlist::bump_name (_playlist->name(), _session);
404 newname = Playlist::bump_name (_name, _session);
407 if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) {
408 playlist->set_orig_diskstream_id (id());
409 return use_playlist (playlist);
416 DiskStream::use_copy_playlist ()
418 if (_playlist == 0) {
419 error << string_compose(_("DiskStream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
424 AudioPlaylist* playlist;
426 newname = Playlist::bump_name (_playlist->name(), _session);
428 if ((playlist = new AudioPlaylist (*_playlist, newname)) != 0) {
429 playlist->set_orig_diskstream_id (id());
430 return use_playlist (playlist);
437 DiskStream::set_io (IO& io)
440 set_align_style_from_io ();
444 DiskStream::set_name (string str, void *src)
447 _playlist->set_name (str);
450 if (!in_set_state && recordable()) {
452 /* open new capture files so that they have the correct name */
454 reset_write_sources (false);
460 DiskStream::set_speed (double sp)
462 _session.request_diskstream_speed (*this, sp);
464 /* to force a rebuffering at the right place */
469 DiskStream::realtime_set_speed (double sp, bool global)
471 bool changed = false;
472 double new_speed = sp * _session.transport_speed();
474 if (_visible_speed != sp) {
479 if (new_speed != _actual_speed) {
481 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() *
482 fabs (new_speed)) + 1;
484 if (required_wrap_size > wrap_buffer_size) {
485 _buffer_reallocation_required = true;
488 _actual_speed = new_speed;
489 phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
494 _seek_required = true;
496 speed_changed (); /* EMIT SIGNAL */
499 return _buffer_reallocation_required || _seek_required;
503 DiskStream::non_realtime_set_speed ()
505 if (_buffer_reallocation_required)
507 LockMonitor lm (state_lock, __LINE__, __FILE__);
508 allocate_temporary_buffers ();
510 _buffer_reallocation_required = false;
513 if (_seek_required) {
514 if (speed() != 1.0f || speed() != -1.0f) {
515 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
518 seek (_session.transport_frame(), true);
521 _seek_required = false;
526 DiskStream::prepare ()
529 playback_distance = 0;
533 DiskStream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
535 int possibly_recording;
538 const int transport_rolling = 0x4;
539 const int track_rec_enabled = 0x2;
540 const int global_rec_enabled = 0x1;
542 /* merge together the 3 factors that affect record status, and compute
546 rolling = _session.transport_speed() != 0.0f;
547 possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
548 change = possibly_recording ^ last_possibly_recording;
550 if (possibly_recording == last_possibly_recording) {
556 /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
558 if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) ||
559 ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
561 /* starting to record: compute first+last frames */
563 first_recordable_frame = transport_frame + _capture_offset;
564 last_recordable_frame = max_frames;
565 capture_start_frame = transport_frame;
567 if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) {
569 /* was stopped, now rolling (and recording) */
571 if (_alignment_style == ExistingMaterial) {
572 first_recordable_frame += _session.worst_output_latency();
574 first_recordable_frame += _roll_delay;
579 /* was rolling, but record state changed */
581 if (_alignment_style == ExistingMaterial) {
584 if (!_session.get_punch_in()) {
586 /* manual punch in happens at the correct transport frame
587 because the user hit a button. but to get alignment correct
588 we have to back up the position of the new region to the
589 appropriate spot given the roll delay.
592 capture_start_frame -= _roll_delay;
594 /* XXX paul notes (august 2005): i don't know why
598 first_recordable_frame += _capture_offset;
602 /* autopunch toggles recording at the precise
603 transport frame, and then the DS waits
604 to start recording for a time that depends
605 on the output latency.
608 first_recordable_frame += _session.worst_output_latency();
613 if (_session.get_punch_in()) {
614 first_recordable_frame += _roll_delay;
616 capture_start_frame -= _roll_delay;
622 if (_flags & Recordable) {
623 cerr << "START RECORD @ " << capture_start_frame << endl;
625 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
627 RingBufferNPT<CaptureTransition>::rw_vector transvec;
628 (*chan).capture_transition_buf->get_write_vector(&transvec);
630 if (transvec.len[0] > 0) {
631 transvec.buf[0]->type = CaptureStart;
632 transvec.buf[0]->capture_val = capture_start_frame;
633 (*chan).capture_transition_buf->increment_write_ptr(1);
637 cerr << "capture_transition_buf is full on rec start! inconceivable!" << endl;
642 } else if (!record_enabled() || !can_record) {
646 last_recordable_frame = transport_frame + _capture_offset;
648 if (_alignment_style == ExistingMaterial) {
649 last_recordable_frame += _session.worst_output_latency();
651 last_recordable_frame += _roll_delay;
655 last_possibly_recording = possibly_recording;
659 DiskStream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input)
662 ChannelList::iterator c;
664 jack_nframes_t rec_offset = 0;
665 jack_nframes_t rec_nframes = 0;
666 bool nominally_recording;
667 bool re = record_enabled ();
668 bool collect_playback = false;
670 /* if we've already processed the frames corresponding to this call,
671 just return. this allows multiple routes that are taking input
672 from this diskstream to call our ::process() method, but have
673 this stuff only happen once. more commonly, it allows both
674 the AudioTrack that is using this DiskStream *and* the Session
675 to call process() without problems.
682 check_record_status (transport_frame, nframes, can_record);
684 nominally_recording = (can_record && re);
691 /* This lock is held until the end of DiskStream::commit, so these two functions
692 must always be called as a pair. The only exception is if this function
693 returns a non-zero value, in which case, ::commit should not be called.
696 if (pthread_mutex_trylock (state_lock.mutex())) {
700 adjust_capture_position = 0;
702 for (c = channels.begin(); c != channels.end(); ++c) {
703 (*c).current_capture_buffer = 0;
704 (*c).current_playback_buffer = 0;
707 if (nominally_recording || (_session.get_record_enabled() && _session.get_punch_in())) {
710 ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
717 case OverlapInternal:
718 /* ---------- recrange
721 rec_nframes = nframes;
726 /* |--------| recrange
729 rec_nframes = transport_frame + nframes - first_recordable_frame;
731 rec_offset = first_recordable_frame - transport_frame;
736 /* |--------| recrange
739 rec_nframes = last_recordable_frame - transport_frame;
743 case OverlapExternal:
744 /* |--------| recrange
745 -------------- transrange
747 rec_nframes = last_recordable_frame - last_recordable_frame;
748 rec_offset = first_recordable_frame - transport_frame;
752 if (rec_nframes && !was_recording) {
753 capture_captured = 0;
754 was_recording = true;
759 if (can_record && !_last_capture_regions.empty()) {
760 _last_capture_regions.clear ();
763 if (nominally_recording || rec_nframes) {
765 for (n = 0, c = channels.begin(); c != channels.end(); ++c, ++n) {
767 ChannelInfo& chan (*c);
769 chan.capture_buf->get_write_vector (&chan.capture_vector);
771 if (rec_nframes <= chan.capture_vector.len[0]) {
773 chan.current_capture_buffer = chan.capture_vector.buf[0];
775 /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use
779 memcpy (chan.current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes);
783 jack_nframes_t total = chan.capture_vector.len[0] + chan.capture_vector.len[1];
785 if (rec_nframes > total) {
790 Sample* buf = _io->input (n)->get_buffer (nframes) + offset;
791 jack_nframes_t first = chan.capture_vector.len[0];
793 memcpy (chan.capture_wrap_buffer, buf, sizeof (Sample) * first);
794 memcpy (chan.capture_vector.buf[0], buf, sizeof (Sample) * first);
795 memcpy (chan.capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first));
796 memcpy (chan.capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first));
798 chan.current_capture_buffer = chan.capture_wrap_buffer;
805 finish_capture (rec_monitors_input);
812 /* data will be written to disk */
814 if (rec_nframes == nframes && rec_offset == 0) {
816 for (c = channels.begin(); c != channels.end(); ++c) {
817 (*c).current_playback_buffer = (*c).current_capture_buffer;
820 playback_distance = nframes;
825 /* we can't use the capture buffer as the playback buffer, because
826 we recorded only a part of the current process' cycle data
830 collect_playback = true;
833 adjust_capture_position = rec_nframes;
835 } else if (nominally_recording) {
837 /* can't do actual capture yet - waiting for latency effects to finish before we start*/
839 for (c = channels.begin(); c != channels.end(); ++c) {
840 (*c).current_playback_buffer = (*c).current_capture_buffer;
843 playback_distance = nframes;
847 collect_playback = true;
850 if (collect_playback) {
852 /* we're doing playback */
854 jack_nframes_t necessary_samples;
856 /* no varispeed playback if we're recording, because the output .... TBD */
858 if (rec_nframes == 0 && _actual_speed != 1.0f) {
859 necessary_samples = (jack_nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
861 necessary_samples = nframes;
864 for (c = channels.begin(); c != channels.end(); ++c) {
865 (*c).playback_buf->get_read_vector (&(*c).playback_vector);
870 for (c = channels.begin(); c != channels.end(); ++c, ++n) {
872 ChannelInfo& chan (*c);
874 if (necessary_samples <= chan.playback_vector.len[0]) {
876 chan.current_playback_buffer = chan.playback_vector.buf[0];
879 jack_nframes_t total = chan.playback_vector.len[0] + chan.playback_vector.len[1];
881 if (necessary_samples > total) {
887 memcpy ((char *) chan.playback_wrap_buffer, chan.playback_vector.buf[0],
888 chan.playback_vector.len[0] * sizeof (Sample));
889 memcpy (chan.playback_wrap_buffer + chan.playback_vector.len[0], chan.playback_vector.buf[1],
890 (necessary_samples - chan.playback_vector.len[0]) * sizeof (Sample));
892 chan.current_playback_buffer = chan.playback_wrap_buffer;
897 if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
899 uint64_t phase = last_phase;
900 jack_nframes_t i = 0;
902 // Linearly interpolate into the alt buffer
903 // using 40.24 fixp maths (swh)
905 for (c = channels.begin(); c != channels.end(); ++c) {
908 ChannelInfo& chan (*c);
913 for (jack_nframes_t outsample = 0; outsample < nframes; ++outsample) {
915 fr = (phase & 0xFFFFFF) / 16777216.0f;
916 chan.speed_buffer[outsample] =
917 chan.current_playback_buffer[i] * (1.0f - fr) +
918 chan.current_playback_buffer[i+1] * fr;
922 chan.current_playback_buffer = chan.speed_buffer;
925 playback_distance = i + 1;
926 last_phase = (phase & 0xFFFFFF);
929 playback_distance = nframes;
941 /* we're exiting with failure, so ::commit will not
942 be called. unlock the state lock.
945 pthread_mutex_unlock (state_lock.mutex());
952 DiskStream::recover ()
954 pthread_mutex_unlock (state_lock.mutex());
959 DiskStream::commit (jack_nframes_t nframes)
961 bool need_butler = false;
963 if (_actual_speed < 0.0) {
964 playback_sample -= playback_distance;
966 playback_sample += playback_distance;
969 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
971 (*chan).playback_buf->increment_read_ptr (playback_distance);
973 if (adjust_capture_position) {
974 (*chan).capture_buf->increment_write_ptr (adjust_capture_position);
978 if (adjust_capture_position != 0) {
979 capture_captured += adjust_capture_position;
980 adjust_capture_position = 0;
984 need_butler = channels[0].playback_buf->write_space() >= channels[0].playback_buf->bufsize() / 2;
986 need_butler = channels[0].playback_buf->write_space() >= disk_io_chunk_frames
987 || channels[0].capture_buf->read_space() >= disk_io_chunk_frames;
990 pthread_mutex_unlock (state_lock.mutex());
998 DiskStream::set_pending_overwrite (bool yn)
1000 /* called from audio thread, so we can use the read ptr and playback sample as we wish */
1002 pending_overwrite = yn;
1004 overwrite_frame = playback_sample;
1005 overwrite_offset = channels.front().playback_buf->get_read_ptr();
1009 DiskStream::overwrite_existing_buffers ()
1011 Sample* mixdown_buffer;
1015 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1017 overwrite_queued = false;
1019 /* assume all are the same size */
1020 jack_nframes_t size = channels[0].playback_buf->bufsize();
1022 mixdown_buffer = new Sample[size];
1023 gain_buffer = new float[size];
1024 workbuf = new char[size*4];
1026 /* reduce size so that we can fill the buffer correctly. */
1030 jack_nframes_t start;
1032 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1034 start = overwrite_frame;
1035 jack_nframes_t cnt = size;
1037 /* to fill the buffer without resetting the playback sample, we need to
1038 do it one or two chunks (normally two).
1040 |----------------------------------------------------------------------|
1044 |<- second chunk->||<----------------- first chunk ------------------>|
1048 jack_nframes_t to_read = size - overwrite_offset;
1050 if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, workbuf,
1051 start, to_read, *chan, n, reversed)) {
1052 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1053 _id, size, playback_sample) << endmsg;
1057 if (cnt > to_read) {
1061 if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer, workbuf,
1062 start, cnt, *chan, n, reversed)) {
1063 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1064 _id, size, playback_sample) << endmsg;
1073 pending_overwrite = false;
1074 delete [] gain_buffer;
1075 delete [] mixdown_buffer;
1081 DiskStream::seek (jack_nframes_t frame, bool complete_refill)
1083 LockMonitor lm (state_lock, __LINE__, __FILE__);
1086 ChannelList::iterator chan;
1088 for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1089 (*chan).playback_buf->reset ();
1090 (*chan).capture_buf->reset ();
1091 if ((*chan).write_source) {
1092 (*chan).write_source->seek (frame);
1096 playback_sample = frame;
1099 if (complete_refill) {
1100 while ((ret = do_refill (0, 0, 0)) > 0);
1102 ret = do_refill (0, 0, 0);
1109 DiskStream::can_internal_playback_seek (jack_nframes_t distance)
1111 ChannelList::iterator chan;
1113 for (chan = channels.begin(); chan != channels.end(); ++chan) {
1114 if ((*chan).playback_buf->read_space() < distance) {
1122 DiskStream::internal_playback_seek (jack_nframes_t distance)
1124 ChannelList::iterator chan;
1126 for (chan = channels.begin(); chan != channels.end(); ++chan) {
1127 (*chan).playback_buf->increment_read_ptr (distance);
1130 first_recordable_frame += distance;
1131 playback_sample += distance;
1137 DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt,
1138 ChannelInfo& channel_info, int channel, bool reversed)
1140 jack_nframes_t this_read = 0;
1141 bool reloop = false;
1142 jack_nframes_t loop_end = 0;
1143 jack_nframes_t loop_start = 0;
1144 jack_nframes_t loop_length = 0;
1145 jack_nframes_t offset = 0;
1149 /* Make the use of a Location atomic for this read operation.
1151 Note: Locations don't get deleted, so all we care about
1152 when I say "atomic" is that we are always pointing to
1153 the same one and using a start/length values obtained
1157 if ((loc = loop_location) != 0) {
1158 loop_start = loc->start();
1159 loop_end = loc->end();
1160 loop_length = loop_end - loop_start;
1163 /* if we are looping, ensure that the first frame we read is at the correct
1164 position within the loop.
1167 if (loc && start >= loop_end) {
1168 //cerr << "start adjusted from " << start;
1169 start = loop_start + ((start - loop_start) % loop_length);
1170 //cerr << "to " << start << endl;
1172 //cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
1177 /* take any loop into account. we can't read past the end of the loop. */
1179 if (loc && (loop_end - start < cnt)) {
1180 this_read = loop_end - start;
1181 //cerr << "reloop true: thisread: " << this_read << " cnt: " << cnt << endl;
1188 if (this_read == 0) {
1192 this_read = min(cnt,this_read);
1194 if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
1195 error << string_compose(_("DiskStream %1: cannot read %2 from playlist at frame %3"), _id, this_read,
1200 _read_data_count = _playlist->read_data_count();
1204 /* don't adjust start, since caller has already done that
1207 swap_by_ptr (buf, buf + this_read - 1);
1211 /* if we read to the end of the loop, go back to the beginning */
1221 offset += this_read;
1228 DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
1231 jack_nframes_t to_read;
1232 RingBufferNPT<Sample>::rw_vector vector;
1236 bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1237 jack_nframes_t total_space;
1238 jack_nframes_t zero_fill;
1240 ChannelList::iterator i;
1243 channels.front().playback_buf->get_write_vector (&vector);
1245 if ((total_space = vector.len[0] + vector.len[1]) == 0) {
1249 /* if there are 2+ chunks of disk i/o possible for
1250 this track, let the caller know so that it can arrange
1251 for us to be called again, ASAP.
1254 if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) {
1258 /* if we're running close to normal speed and there isn't enough
1259 space to do disk_io_chunk_frames of I/O, then don't bother.
1261 at higher speeds, just do it because the sync between butler
1262 and audio thread may not be good enough.
1265 if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
1269 /* when slaved, don't try to get too close to the read pointer. this
1270 leaves space for the buffer reversal to have something useful to
1274 if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) {
1278 total_space = min (disk_io_chunk_frames, total_space);
1282 if (file_frame == 0) {
1284 /* at start: nothing to do but fill with silence */
1286 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1288 ChannelInfo& chan (*i);
1289 chan.playback_buf->get_write_vector (&vector);
1290 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1291 if (vector.len[1]) {
1292 memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1294 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1299 if (file_frame < total_space) {
1301 /* too close to the start: read what we can,
1302 and then zero fill the rest
1305 zero_fill = total_space - file_frame;
1306 total_space = file_frame;
1311 /* move read position backwards because we are going
1312 to reverse the data.
1315 file_frame -= total_space;
1321 if (file_frame == max_frames) {
1323 /* at end: nothing to do but fill with silence */
1325 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1327 ChannelInfo& chan (*i);
1328 chan.playback_buf->get_write_vector (&vector);
1329 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1330 if (vector.len[1]) {
1331 memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1333 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1338 if (file_frame > max_frames - total_space) {
1340 /* to close to the end: read what we can, and zero fill the rest */
1342 zero_fill = total_space - (max_frames - file_frame);
1343 total_space = max_frames - file_frame;
1350 /* Please note: the code to allocate buffers isn't run
1351 during normal butler thread operation. Its there
1352 for other times when we need to call do_refill()
1353 from somewhere other than the butler thread.
1356 if (mixdown_buffer == 0) {
1357 mixdown_buffer = new Sample[disk_io_chunk_frames];
1358 free_mixdown = true;
1360 free_mixdown = false;
1363 if (gain_buffer == 0) {
1364 gain_buffer = new float[disk_io_chunk_frames];
1371 workbuf = new char[disk_io_chunk_frames * 4];
1372 free_workbuf = true;
1374 free_workbuf = false;
1377 jack_nframes_t file_frame_tmp = 0;
1379 for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1381 ChannelInfo& chan (*i);
1384 jack_nframes_t len1, len2;
1386 chan.playback_buf->get_write_vector (&vector);
1389 file_frame_tmp = file_frame;
1392 buf1 = vector.buf[1];
1393 len1 = vector.len[1];
1394 buf2 = vector.buf[0];
1395 len2 = vector.len[0];
1397 buf1 = vector.buf[0];
1398 len1 = vector.len[0];
1399 buf2 = vector.buf[1];
1400 len2 = vector.len[1];
1404 to_read = min (ts, len1);
1405 to_read = min (to_read, disk_io_chunk_frames);
1409 if (read (buf1, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1414 chan.playback_buf->increment_write_ptr (to_read);
1418 to_read = min (ts, len2);
1423 /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data,
1424 so read some or all of vector.len[1] as well.
1427 if (read (buf2, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1432 chan.playback_buf->increment_write_ptr (to_read);
1441 file_frame = file_frame_tmp;
1445 delete [] mixdown_buffer;
1448 delete [] gain_buffer;
1458 DiskStream::do_flush (char * workbuf, bool force_flush)
1462 RingBufferNPT<Sample>::rw_vector vector;
1463 RingBufferNPT<CaptureTransition>::rw_vector transvec;
1464 jack_nframes_t total;
1466 /* important note: this function will write *AT MOST*
1467 disk_io_chunk_frames of data to disk. it will never
1468 write more than that. if its writes that much and there
1469 is more than that waiting to be written, it will return 1,
1470 otherwise 0 on success or -1 on failure.
1472 if there is less than disk_io_chunk_frames to be written,
1473 no data will be written at all unless `force_flush' is true.
1476 _write_data_count = 0;
1478 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1480 (*chan).capture_buf->get_read_vector (&vector);
1482 total = vector.len[0] + vector.len[1];
1485 if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
1490 /* if there are 2+ chunks of disk i/o possible for
1491 this track, let the caller know so that it can arrange
1492 for us to be called again, ASAP.
1494 if we are forcing a flush, then if there is* any* extra
1495 work, let the caller know.
1497 if we are no longer recording and there is any extra work,
1498 let the caller know too.
1501 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
1505 to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
1508 // check the transition buffer when recording destructive
1509 // important that we get this after the capture buf
1511 if (destructive()) {
1512 (*chan).capture_transition_buf->get_read_vector(&transvec);
1513 size_t transcount = transvec.len[0] + transvec.len[1];
1514 bool have_start = false;
1517 for (ti=0; ti < transcount; ++ti) {
1518 CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
1520 if (captrans.type == CaptureStart) {
1521 // by definition, the first data we got above represents the given capture pos
1522 cerr << "DS " << name() << " got CaptureStart at " << captrans.capture_val << endl;
1524 (*chan).write_source->mark_capture_start (captrans.capture_val);
1526 (*chan).curr_capture_cnt = 0;
1530 else if (captrans.type == CaptureEnd) {
1532 // capture end, the capture_val represents total frames in capture
1534 if (captrans.capture_val <= (*chan).curr_capture_cnt + to_write) {
1536 cerr << "DS " << name() << " got CaptureEnd with " << captrans.capture_val << endl;
1537 // shorten to make the write a perfect fit
1538 uint32_t nto_write = (captrans.capture_val - (*chan).curr_capture_cnt);
1540 // starts and ends within same chunk we're processing
1541 cerr << "Starts and ends within same chunk: adjusting to_write from: "
1542 << to_write << " to: " << nto_write << endl;
1545 cerr << "Ends within chunk: adjusting to_write to: "
1546 << to_write << " to: " << nto_write << endl;
1549 if (nto_write < to_write) {
1550 ret = 1; // should we?
1552 to_write = nto_write;
1554 (*chan).write_source->mark_capture_end ();
1556 // increment past this transition, but go no further
1561 // actually ends just beyond this chunk, so force more work
1562 cerr << "DS " << name() << " got CaptureEnd beyond our chunk, cnt of: "
1563 << captrans.capture_val << " leaving on queue" << endl;
1571 (*chan).capture_transition_buf->increment_read_ptr(ti);
1577 if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write, workbuf) != to_write) {
1578 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1582 (*chan).capture_buf->increment_read_ptr (to_write);
1583 (*chan).curr_capture_cnt += to_write;
1585 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames) && !destructive()) {
1587 /* we wrote all of vector.len[0] but it wasn't an entire
1588 disk_io_chunk_frames of data, so arrange for some part
1589 of vector.len[1] to be flushed to disk as well.
1592 to_write = min ((jack_nframes_t)(disk_io_chunk_frames - to_write), (jack_nframes_t) vector.len[1]);
1594 if ((*chan).write_source->write (vector.buf[1], to_write, workbuf) != to_write) {
1595 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1599 _write_data_count += (*chan).write_source->write_data_count();
1601 (*chan).capture_buf->increment_read_ptr (to_write);
1602 (*chan).curr_capture_cnt += to_write;
1611 DiskStream::playlist_changed (Change ignored)
1613 playlist_modified ();
1617 DiskStream::playlist_modified ()
1619 if (!i_am_the_modifier && !overwrite_queued) {
1620 _session.request_overwrite_buffer (this);
1621 overwrite_queued = true;
1626 DiskStream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
1628 uint32_t buffer_position;
1629 bool more_work = true;
1631 AudioRegion* region = 0;
1632 jack_nframes_t total_capture;
1633 AudioRegion::SourceList srcs;
1634 AudioRegion::SourceList::iterator src;
1635 ChannelList::iterator chan;
1636 vector<CaptureInfo*>::iterator ci;
1638 list<Source*>* deletion_list;
1639 bool mark_write_completed = false;
1641 finish_capture (true);
1643 /* butler is already stopped, but there may be work to do
1644 to flush remaining data to disk.
1647 while (more_work && !err) {
1648 switch (do_flush ( _session.conversion_buffer(Session::TransportContext), true)) {
1655 error << string_compose(_("DiskStream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1660 /* XXX is there anything we can do if err != 0 ? */
1661 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
1663 if (capture_info.empty()) {
1667 if (abort_capture) {
1669 ChannelList::iterator chan;
1671 deletion_list = new list<Source*>;
1673 for ( chan = channels.begin(); chan != channels.end(); ++chan) {
1675 if ((*chan).write_source) {
1677 (*chan).write_source->mark_for_remove ();
1678 (*chan).write_source->release ();
1680 deletion_list->push_back ((*chan).write_source);
1682 (*chan).write_source = 0;
1685 /* new source set up in "out" below */
1688 if (!deletion_list->empty()) {
1689 DeleteSources (deletion_list);
1691 delete deletion_list;
1697 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1698 total_capture += (*ci)->frames;
1701 /* figure out the name for this take */
1703 for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1705 Source* s = (*chan).write_source;
1713 if ((fsrc = dynamic_cast<FileSource *>(s)) != 0) {
1714 fsrc->update_header (capture_info.front()->start, when, twhen);
1717 s->set_captured_for (_name);
1722 /* Register a new region with the Session that
1723 describes the entire source. Do this first
1724 so that any sub-regions will obviously be
1725 children of this one (later!)
1729 region = new AudioRegion (srcs, channels[0].write_source->last_capture_start_frame(), total_capture,
1730 region_name_from_path (channels[0].write_source->name()),
1731 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
1733 region->special_set_position (capture_info.front()->start);
1736 catch (failed_constructor& err) {
1737 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1741 _last_capture_regions.push_back (region);
1743 // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
1745 _session.add_undo (_playlist->get_memento());
1746 _playlist->freeze ();
1748 for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1751 _session.region_name (region_name, _name, false);
1753 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1756 region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
1759 catch (failed_constructor& err) {
1760 error << _("DiskStream: could not create region for captured audio!") << endmsg;
1761 continue; /* XXX is this OK? */
1764 _last_capture_regions.push_back (region);
1766 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1768 i_am_the_modifier++;
1769 _playlist->add_region (*region, (*ci)->start);
1770 i_am_the_modifier--;
1772 buffer_position += (*ci)->frames;
1776 _session.add_redo_no_execute (_playlist->get_memento());
1778 mark_write_completed = true;
1780 reset_write_sources (mark_write_completed);
1783 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1787 capture_info.clear ();
1788 capture_start_frame = 0;
1792 DiskStream::finish_capture (bool rec_monitors_input)
1794 was_recording = false;
1796 if (capture_captured == 0) {
1800 if ((_flags & Recordable) && destructive()) {
1801 cerr << "RECORD END @ " << capture_start_frame + capture_captured << endl;
1802 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1804 RingBufferNPT<CaptureTransition>::rw_vector transvec;
1805 (*chan).capture_transition_buf->get_write_vector(&transvec);
1808 if (transvec.len[0] > 0) {
1809 transvec.buf[0]->type = CaptureEnd;
1810 transvec.buf[0]->capture_val = capture_captured;
1811 (*chan).capture_transition_buf->increment_write_ptr(1);
1815 cerr << "capture_transition_buf is full when stopping record! inconceivable!" << endl;
1821 CaptureInfo* ci = new CaptureInfo;
1823 ci->start = capture_start_frame;
1824 ci->frames = capture_captured;
1826 /* XXX theoretical race condition here. Need atomic exchange ?
1827 However, the circumstances when this is called right
1828 now (either on record-disable or transport_stopped)
1829 mean that no actual race exists. I think ...
1830 We now have a capture_info_lock, but it is only to be used
1831 to synchronize in the transport_stop and the capture info
1832 accessors, so that invalidation will not occur (both non-realtime).
1835 // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1837 capture_info.push_back (ci);
1838 capture_captured = 0;
1842 DiskStream::set_record_enabled (bool yn, void* src)
1844 bool rolling = _session.transport_speed() != 0.0f;
1846 if (!recordable() || !_session.record_enabling_legal()) {
1850 /* if we're turning on rec-enable, there needs to be an
1854 if (yn && channels[0].source == 0) {
1856 /* pick up connections not initiated *from* the IO object
1857 we're associated with.
1860 get_input_sources ();
1862 if (channels[0].source == 0) {
1865 CannotRecordNoInput (this); /* emit signal */
1871 /* yes, i know that this not proof against race conditions, but its
1872 good enough. i think.
1875 if (record_enabled() != yn) {
1877 atomic_set (&_record_enabled, 1);
1878 capturing_sources.clear ();
1879 if (Config->get_use_hardware_monitoring()) {
1880 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1881 if ((*chan).source) {
1882 (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
1884 capturing_sources.push_back ((*chan).write_source);
1887 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1888 capturing_sources.push_back ((*chan).write_source);
1893 atomic_set (&_record_enabled, 0);
1894 if (Config->get_use_hardware_monitoring()) {
1895 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1896 if ((*chan).source) {
1897 (*chan).source->request_monitor_input (false);
1901 capturing_sources.clear ();
1904 record_enable_changed (src); /* EMIT SIGNAL */
1909 DiskStream::get_state ()
1911 XMLNode* node = new XMLNode ("DiskStream");
1913 LocaleGuard lg (X_("POSIX"));
1915 if (destructive()) {
1916 node->add_property ("destructive", "true");
1919 snprintf (buf, sizeof(buf), "%zd", channels.size());
1920 node->add_property ("channels", buf);
1922 node->add_property ("playlist", _playlist->name());
1924 snprintf (buf, sizeof(buf), "%f", _visible_speed);
1925 node->add_property ("speed", buf);
1927 node->add_property("name", _name);
1928 snprintf (buf, sizeof(buf), "%" PRIu64, id());
1929 node->add_property("id", buf);
1931 if (!capturing_sources.empty() && _session.get_record_enabled()) {
1933 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1934 XMLNode* cs_grandchild;
1936 for (vector<FileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1937 cs_grandchild = new XMLNode (X_("file"));
1938 cs_grandchild->add_property (X_("path"), (*i)->path());
1939 cs_child->add_child_nocopy (*cs_grandchild);
1942 /* store the location where capture will start */
1946 if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1947 snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
1949 snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
1952 cs_child->add_property (X_("at"), buf);
1953 node->add_child_nocopy (*cs_child);
1957 node->add_child_copy (*_extra_xml);
1964 DiskStream::set_state (const XMLNode& node)
1966 const XMLProperty* prop;
1967 XMLNodeList nlist = node.children();
1968 XMLNodeIterator niter;
1969 uint32_t nchans = 1;
1970 XMLNode* capture_pending_node = 0;
1971 LocaleGuard lg (X_("POSIX"));
1973 in_set_state = true;
1975 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1976 if ((*niter)->name() == IO::state_node_name) {
1977 deprecated_io_node = new XMLNode (**niter);
1980 if ((*niter)->name() == X_("CapturingSources")) {
1981 capture_pending_node = *niter;
1985 /* prevent write sources from being created */
1987 in_set_state = true;
1989 if ((prop = node.property ("name")) != 0) {
1990 _name = prop->value();
1993 if ((prop = node.property ("destructive")) != 0) {
1994 if (prop->value() == "true") {
1995 _flags |= Destructive;
1999 if (deprecated_io_node) {
2000 if ((prop = deprecated_io_node->property ("id")) != 0) {
2001 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
2004 if ((prop = node.property ("id")) != 0) {
2005 sscanf (prop->value().c_str(), "%" PRIu64, &_id);
2009 if ((prop = node.property ("channels")) != 0) {
2010 nchans = atoi (prop->value().c_str());
2013 // create necessary extra channels
2014 // we are always constructed with one
2015 // and we always need one
2017 if (nchans > _n_channels) {
2019 // we need to add new channel infos
2020 //LockMonitor lm (state_lock, __LINE__, __FILE__);
2022 int diff = nchans - channels.size();
2024 for (int i=0; i < diff; ++i) {
2028 } else if (nchans < _n_channels) {
2030 // we need to get rid of channels
2031 //LockMonitor lm (state_lock, __LINE__, __FILE__);
2033 int diff = channels.size() - nchans;
2035 for (int i = 0; i < diff; ++i) {
2040 if ((prop = node.property ("playlist")) == 0) {
2045 bool had_playlist = (_playlist != 0);
2047 if (find_and_use_playlist (prop->value())) {
2051 if (!had_playlist) {
2052 _playlist->set_orig_diskstream_id (_id);
2055 if (capture_pending_node) {
2056 use_pending_capture_data (*capture_pending_node);
2061 if ((prop = node.property ("speed")) != 0) {
2062 double sp = atof (prop->value().c_str());
2064 if (realtime_set_speed (sp, false)) {
2065 non_realtime_set_speed ();
2069 _n_channels = channels.size();
2071 in_set_state = false;
2073 /* now that we're all done with playlist+channel set up,
2074 go ahead and create write sources.
2078 capturing_sources.clear ();
2081 reset_write_sources (false);
2084 in_set_state = false;
2090 DiskStream::use_new_write_source (uint32_t n)
2092 if (!recordable()) {
2096 if (n >= channels.size()) {
2097 error << string_compose (_("DiskStream: channel %1 out of range"), n) << endmsg;
2101 ChannelInfo &chan = channels[n];
2103 if (chan.write_source) {
2105 if (FileSource::is_empty (chan.write_source->path())) {
2106 chan.write_source->mark_for_remove ();
2107 chan.write_source->release();
2108 delete chan.write_source;
2110 chan.write_source->release();
2111 chan.write_source = 0;
2116 if ((chan.write_source = _session.create_file_source (*this, n, destructive())) == 0) {
2117 throw failed_constructor();
2121 catch (failed_constructor &err) {
2122 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
2123 chan.write_source = 0;
2127 chan.write_source->use ();
2133 DiskStream::reset_write_sources (bool mark_write_complete, bool force)
2135 ChannelList::iterator chan;
2138 if (!recordable()) {
2142 if (!force && destructive()) {
2144 /* make sure we always have enough sources for the current channel count */
2146 for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2147 if ((*chan).write_source == 0) {
2152 if (chan == channels.end()) {
2156 /* some channels do not have a write source */
2159 capturing_sources.clear ();
2161 for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2162 if (mark_write_complete) {
2163 (*chan).write_source->mark_streaming_write_completed ();
2165 use_new_write_source (n);
2166 if (record_enabled()) {
2167 capturing_sources.push_back ((*chan).write_source);
2173 DiskStream::set_block_size (jack_nframes_t nframes)
2175 if (_session.get_block_size() > speed_buffer_size) {
2176 speed_buffer_size = _session.get_block_size();
2178 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2179 if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
2180 (*chan).speed_buffer = new Sample[speed_buffer_size];
2183 allocate_temporary_buffers ();
2187 DiskStream::allocate_temporary_buffers ()
2189 /* make sure the wrap buffer is at least large enough to deal
2190 with the speeds up to 1.2, to allow for micro-variation
2191 when slaving to MTC, SMPTE etc.
2194 double sp = max (fabsf (_actual_speed), 1.2f);
2195 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * sp) + 1;
2197 if (required_wrap_size > wrap_buffer_size) {
2199 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2200 if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
2201 (*chan).playback_wrap_buffer = new Sample[required_wrap_size];
2202 if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
2203 (*chan).capture_wrap_buffer = new Sample[required_wrap_size];
2206 wrap_buffer_size = required_wrap_size;
2211 DiskStream::monitor_input (bool yn)
2213 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2215 if ((*chan).source) {
2216 (*chan).source->request_monitor_input (yn);
2222 DiskStream::set_capture_offset ()
2225 /* can't capture, so forget it */
2229 _capture_offset = _io->input_latency();
2233 DiskStream::set_persistent_align_style (AlignStyle a)
2235 _persistent_alignment_style = a;
2239 DiskStream::set_align_style_from_io ()
2241 bool have_physical = false;
2247 get_input_sources ();
2249 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2250 if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
2251 have_physical = true;
2256 if (have_physical) {
2257 set_align_style (ExistingMaterial);
2259 set_align_style (CaptureTime);
2264 DiskStream::set_align_style (AlignStyle a)
2266 if (record_enabled() && _session.actively_recording()) {
2271 if (a != _alignment_style) {
2272 _alignment_style = a;
2273 AlignmentStyleChanged ();
2278 DiskStream::add_channel ()
2280 /* XXX need to take lock??? */
2284 init_channel (chan);
2286 chan.speed_buffer = new Sample[speed_buffer_size];
2287 chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
2288 chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
2290 channels.push_back (chan);
2292 _n_channels = channels.size();
2298 DiskStream::remove_channel ()
2300 if (channels.size() > 1) {
2301 /* XXX need to take lock??? */
2302 ChannelInfo & chan = channels.back();
2303 destroy_channel (chan);
2304 channels.pop_back();
2306 _n_channels = channels.size();
2314 DiskStream::playback_buffer_load () const
2316 return (float) ((double) channels.front().playback_buf->read_space()/
2317 (double) channels.front().playback_buf->bufsize());
2321 DiskStream::capture_buffer_load () const
2323 return (float) ((double) channels.front().capture_buf->write_space()/
2324 (double) channels.front().capture_buf->bufsize());
2328 DiskStream::set_loop (Location *location)
2331 if (location->start() >= location->end()) {
2332 error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
2337 loop_location = location;
2339 LoopSet (location); /* EMIT SIGNAL */
2344 DiskStream::get_capture_start_frame (uint32_t n)
2346 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2348 if (capture_info.size() > n) {
2349 return capture_info[n]->start;
2352 return capture_start_frame;
2357 DiskStream::get_captured_frames (uint32_t n)
2359 LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2361 if (capture_info.size() > n) {
2362 return capture_info[n]->frames;
2365 return capture_captured;
2370 DiskStream::punch_in ()
2375 DiskStream::punch_out ()
2380 DiskStream::use_pending_capture_data (XMLNode& node)
2382 const XMLProperty* prop;
2383 XMLNodeList nlist = node.children();
2384 XMLNodeIterator niter;
2386 FileSource* first_fs = 0;
2387 AudioRegion::SourceList pending_sources;
2388 jack_nframes_t position;
2390 if ((prop = node.property (X_("at"))) == 0) {
2394 if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
2398 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2399 if ((*niter)->name() == X_("file")) {
2401 if ((prop = (*niter)->property (X_("path"))) == 0) {
2406 fs = new FileSource (prop->value(), _session.frame_rate(), true);
2409 catch (failed_constructor& err) {
2410 error << string_compose (_("%1: cannot restore pending capture source file %2"),
2411 _name, prop->value())
2416 pending_sources.push_back (fs);
2418 if (first_fs == 0) {
2422 fs->set_captured_for (_name);
2426 if (pending_sources.size() == 0) {
2427 /* nothing can be done */
2431 if (pending_sources.size() != _n_channels) {
2432 error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2437 AudioRegion* region;
2440 region = new AudioRegion (pending_sources, 0, first_fs->length(),
2441 region_name_from_path (first_fs->name()),
2442 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
2444 region->special_set_position (0);
2447 catch (failed_constructor& err) {
2448 error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
2456 region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
2459 catch (failed_constructor& err) {
2460 error << string_compose (_("%1: cannot create region from pending capture sources"),
2467 _playlist->add_region (*region, position);
2473 DiskStream::set_roll_delay (jack_nframes_t nframes)
2475 _roll_delay = nframes;
2479 DiskStream::set_destructive (bool yn)
2481 if (yn != destructive()) {
2482 reset_write_sources (true, true);
2484 _flags |= Destructive;
2486 _flags &= ~Destructive;