ardour
audio_diskstream.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000-2006 Paul Davis
3 
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.
8 
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.
13 
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.
17 */
18 
19 #include <fstream>
20 #include <cstdio>
21 #include <unistd.h>
22 #include <cmath>
23 #include <cerrno>
24 #include <cassert>
25 #include <string>
26 #include <climits>
27 #include <fcntl.h>
28 #include <cstdlib>
29 #include <ctime>
30 
31 #include "pbd/error.h"
32 #include "pbd/xml++.h"
33 #include "pbd/memento_command.h"
34 #include "pbd/enumwriter.h"
36 
37 #include "ardour/analyser.h"
38 #include "ardour/audio_buffer.h"
40 #include "ardour/audio_port.h"
41 #include "ardour/audioengine.h"
42 #include "ardour/audiofilesource.h"
43 #include "ardour/audioplaylist.h"
44 #include "ardour/audioregion.h"
45 #include "ardour/butler.h"
46 #include "ardour/debug.h"
47 #include "ardour/io.h"
49 #include "ardour/region_factory.h"
50 #include "ardour/session.h"
52 #include "ardour/source_factory.h"
53 #include "ardour/track.h"
54 #include "ardour/types.h"
55 #include "ardour/utils.h"
56 
57 #include "i18n.h"
58 #include <locale.h>
59 
60 using namespace std;
61 using namespace ARDOUR;
62 using namespace PBD;
63 
64 size_t AudioDiskstream::_working_buffers_size = 0;
65 Sample* AudioDiskstream::_mixdown_buffer = 0;
66 gain_t* AudioDiskstream::_gain_buffer = 0;
67 
68 AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
69  : Diskstream(sess, name, flag)
70  , channels (new ChannelList)
71 {
72  /* prevent any write sources from being created */
73 
74  in_set_state = true;
75  use_new_playlist ();
76  in_set_state = false;
77 
78  if (flag & Destructive) {
79  use_destructive_playlist ();
80  }
81 }
82 
84  : Diskstream(sess, node)
85  , channels (new ChannelList)
86 {
87  in_set_state = true;
88  init ();
89 
91  in_set_state = false;
92  throw failed_constructor();
93  }
94 
95  in_set_state = false;
96 
97  if (destructive()) {
99  }
100 }
101 
102 void
104 {
105  /* there are no channels at this point, so these
106  two calls just get speed_buffer_size and wrap_buffer
107  size setup without duplicating their code.
108  */
109 
112 }
113 
115 {
116  DEBUG_TRACE (DEBUG::Destruction, string_compose ("Audio Diskstream %1 destructor\n", _name));
117 
118  {
121 
122  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
123  delete *chan;
124  }
125 
126  c->clear();
127  }
128 
129  channels.flush ();
130 }
131 
132 void
134 {
138 }
139 
140 void
142 {
143  delete [] _mixdown_buffer;
144  delete [] _gain_buffer;
146  _mixdown_buffer = 0;
147  _gain_buffer = 0;
148 }
149 
150 void
152 {
153  bool need_write_sources = false;
154 
155  {
157 
159  return;
160  }
161 
163  if (!cr->empty() && !cr->front()->write_source) {
164  need_write_sources = true;
165  }
166 
170 
171  _n_channels.set(DataType::AUDIO, c->size());
172 
173  if (_io->n_ports().n_audio() > _n_channels.n_audio()) {
175  } else if (_io->n_ports().n_audio() < _n_channels.n_audio()) {
177  }
178 
179  need_write_sources = true;
180  }
181 
186  }
187 
189 
190  /* implicit unlock */
191  }
192 
193  if (need_write_sources) {
194  reset_write_sources (false);
195  }
196 
197  /* now refill channel buffers */
198 
199  if (speed() != 1.0f || speed() != -1.0f) {
200  seek ((framepos_t) (_session.transport_frame() * (double) speed()));
201  } else {
203  }
204 }
205 
206 void
208 {
209  /* now refill channel buffers */
210 
211  if (speed() != 1.0f || speed() != -1.0f) {
212  seek ((framepos_t) (location * (double) speed()));
213  } else {
214  seek (location);
215  }
216 }
217 
218 void
220 {
222 
223  uint32_t n;
224  ChannelList::iterator chan;
225  uint32_t ni = _io->n_ports().n_audio();
226  vector<string> connections;
227 
228  for (n = 0, chan = c->begin(); chan != c->end() && n < ni; ++chan, ++n) {
229 
230  connections.clear ();
231 
232  if ((_io->nth (n).get()) && (_io->nth (n)->get_connections (connections) == 0)) {
233  if (!(*chan)->source.name.empty()) {
234  // _source->disable_metering ();
235  }
236  (*chan)->source.name = string();
237  } else {
238  (*chan)->source.name = connections[0];
239  }
240  }
241 }
242 
243 int
245 {
247 
248  if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlists->by_name (name))) == 0) {
250  }
251 
252  if (!playlist) {
253  error << string_compose(_("AudioDiskstream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
254  return -1;
255  }
256 
257  return use_playlist (playlist);
258 }
259 
260 int
262 {
263  assert(boost::dynamic_pointer_cast<AudioPlaylist>(playlist));
264 
265  Diskstream::use_playlist(playlist);
266 
267  return 0;
268 }
269 
270 int
272 {
273  string newname;
275 
276  if (!in_set_state && destructive()) {
277  return 0;
278  }
279 
280  if (_playlist) {
281  newname = Playlist::bump_name (_playlist->name(), _session);
282  } else {
283  newname = Playlist::bump_name (_name, _session);
284  }
285 
286  if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, _session, newname, hidden()))) != 0) {
287 
288  return use_playlist (playlist);
289 
290  } else {
291  return -1;
292  }
293 }
294 
295 int
297 {
298  assert(audio_playlist());
299 
300  if (destructive()) {
301  return 0;
302  }
303 
304  if (_playlist == 0) {
305  error << string_compose(_("AudioDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
306  return -1;
307  }
308 
309  string newname;
311 
312  newname = Playlist::bump_name (_playlist->name(), _session);
313 
314  if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist>(PlaylistFactory::create (audio_playlist(), newname))) != 0) {
315  return use_playlist (playlist);
316  } else {
317  return -1;
318  }
319 }
320 
321 void
323 {
324  SourceList srcs;
326 
327  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
328  srcs.push_back ((*chan)->write_source);
329  }
330 
331  /* a single full-sized region */
332 
333  assert (!srcs.empty ());
334 
335  PropertyList plist;
336  plist.add (Properties::name, _name.val());
337  plist.add (Properties::start, 0);
338  plist.add (Properties::length, max_framepos - srcs.front()->natural_position());
339 
340  boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist));
341  _playlist->add_region (region, srcs.front()->natural_position());
342 
343  /* apply region properties and update write sources */
345 }
346 
347 void
349 {
350  /* this is called from the XML-based constructor or ::set_destructive. when called,
351  we already have a playlist and a region, but we need to
352  set up our sources for write. we use the sources associated
353  with the (presumed single, full-extent) region.
354  */
355 
357  {
358  const RegionList& rl (_playlist->region_list().rlist());
359  if (rl.size() > 0) {
360  assert((rl.size() == 1));
361  rp = rl.front();
362  }
363  }
364 
365  if (!rp) {
366  reset_write_sources (false, true);
367  return;
368  }
369 
371 
372  if (region == 0) {
373  throw failed_constructor();
374  }
375 
376  /* be sure to stretch the region out to the maximum length */
377 
378  region->set_length (max_framepos - region->position());
379 
380  uint32_t n;
381  ChannelList::iterator chan;
383 
384  for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
385  (*chan)->write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
386  assert((*chan)->write_source);
387  (*chan)->write_source->set_allow_remove_if_empty (false);
388 
389  /* this might be false if we switched modes, so force it */
390 
391  (*chan)->write_source->set_destructive (true);
392  }
393 
394  /* the source list will never be reset for a destructive track */
395 }
396 
397 void
399 {
400  if (recordable() && destructive()) {
402  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
403 
405  (*chan)->capture_transition_buf->get_write_vector (&transitions);
406 
407  if (transitions.len[0] > 0) {
408  transitions.buf[0]->type = CaptureStart;
409  transitions.buf[0]->capture_val = capture_start_frame;
410  (*chan)->capture_transition_buf->increment_write_ptr(1);
411  } else {
412  // bad!
413  fatal << X_("programming error: capture_transition_buf is full on rec start! inconceivable!")
414  << endmsg;
415  }
416  }
417  }
418 }
419 
420 
429 int
430 AudioDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance, bool need_disk_signal)
431 {
432  uint32_t n;
434  ChannelList::iterator chan;
435  framecnt_t rec_offset = 0;
436  framecnt_t rec_nframes = 0;
437  bool collect_playback = false;
438  bool can_record = _session.actively_recording ();
439 
440  playback_distance = 0;
441 
442  if (!_io || !_io->active()) {
443  return 0;
444  }
445 
446  check_record_status (transport_frame, can_record);
447 
448  if (nframes == 0) {
449  return 0;
450  }
451 
452  Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
453 
454  if (!sm.locked()) {
455  return 1;
456  }
457 
459 
460  for (chan = c->begin(); chan != c->end(); ++chan) {
461  (*chan)->current_capture_buffer = 0;
462  (*chan)->current_playback_buffer = 0;
463  }
464 
465  // Safeguard against situations where process() goes haywire when autopunching
466  // and last_recordable_frame < first_recordable_frame
467 
470  }
471 
472  if (record_enabled()) {
473 
474  Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
475  // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
476  // XXX also, first_recordable_frame & last_recordable_frame may both be == max_framepos: coverage() will return OverlapNone in that case. Is thak OK?
477  calculate_record_range (ot, transport_frame, nframes, rec_nframes, rec_offset);
478 
479  DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: this time record %2 of %3 frames, offset %4\n", _name, rec_nframes, nframes, rec_offset));
480 
481  if (rec_nframes && !was_recording) {
482  capture_captured = 0;
483  was_recording = true;
484  }
485  }
486 
487  if (can_record && !_last_capture_sources.empty()) {
488  _last_capture_sources.clear ();
489  }
490 
491  if (rec_nframes) {
492 
493  uint32_t limit = _io->n_ports ().n_audio();
494 
495  /* one or more ports could already have been removed from _io, but our
496  channel setup hasn't yet been updated. prevent us from trying to
497  use channels that correspond to missing ports. note that the
498  process callback (from which this is called) is always atomic
499  with respect to port removal/addition.
500  */
501 
502  for (n = 0, chan = c->begin(); chan != c->end() && n < limit; ++chan, ++n) {
503 
504  ChannelInfo* chaninfo (*chan);
505 
506  chaninfo->capture_buf->get_write_vector (&chaninfo->capture_vector);
507 
508  if (rec_nframes <= (framecnt_t) chaninfo->capture_vector.len[0]) {
509 
510  chaninfo->current_capture_buffer = chaninfo->capture_vector.buf[0];
511 
512  /* note: grab the entire port buffer, but only copy what we were supposed to
513  for recording, and use rec_offset
514  */
515 
516  boost::shared_ptr<AudioPort> const ap = _io->audio (n);
517  assert(ap);
518  assert(rec_nframes <= (framecnt_t) ap->get_audio_buffer(nframes).capacity());
519 
520  Sample *buf = bufs.get_audio (n).data(rec_offset);
521  memcpy (chaninfo->current_capture_buffer, buf, sizeof (Sample) * rec_nframes);
522 
523  } else {
524 
525  framecnt_t total = chaninfo->capture_vector.len[0] + chaninfo->capture_vector.len[1];
526 
527  if (rec_nframes > total) {
528  DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 overrun in %2, rec_nframes = %3 total space = %4\n",
529  DEBUG_THREAD_SELF, name(), rec_nframes, total));
530  DiskOverrun ();
531  return -1;
532  }
533 
534  boost::shared_ptr<AudioPort> const ap = _io->audio (n);
535  assert(ap);
536 
537  Sample *buf = bufs.get_audio (n).data(rec_offset);
538  framecnt_t first = chaninfo->capture_vector.len[0];
539 
540  memcpy (chaninfo->capture_wrap_buffer, buf, sizeof (Sample) * first);
541  memcpy (chaninfo->capture_vector.buf[0], buf, sizeof (Sample) * first);
542  memcpy (chaninfo->capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first));
543  memcpy (chaninfo->capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first));
544 
545  chaninfo->current_capture_buffer = chaninfo->capture_wrap_buffer;
546  }
547  }
548 
549  } else {
550 
551  if (was_recording) {
552  finish_capture (c);
553  }
554 
555  }
556 
557  if (rec_nframes) {
558 
559  /* data will be written to disk */
560 
561  if (rec_nframes == nframes && rec_offset == 0) {
562 
563  for (chan = c->begin(); chan != c->end(); ++chan) {
564  (*chan)->current_playback_buffer = (*chan)->current_capture_buffer;
565  }
566 
567  playback_distance = nframes;
568 
569  } else {
570 
571 
572  /* we can't use the capture buffer as the playback buffer, because
573  we recorded only a part of the current process' cycle data
574  for capture.
575  */
576 
577  collect_playback = true;
578  }
579 
580  adjust_capture_position = rec_nframes;
581 
582  } else if (can_record && record_enabled()) {
583 
584  /* can't do actual capture yet - waiting for latency effects to finish before we start*/
585 
586  for (chan = c->begin(); chan != c->end(); ++chan) {
587  (*chan)->current_playback_buffer = (*chan)->current_capture_buffer;
588  }
589 
590  playback_distance = nframes;
591 
592  } else {
593 
594  collect_playback = true;
595  }
596 
597  if ((_track->monitoring_state () & MonitoringDisk) || collect_playback) {
598 
599  /* we're doing playback */
600 
601  framecnt_t necessary_samples;
602 
603  /* no varispeed playback if we're recording, because the output .... TBD */
604 
605  if (rec_nframes == 0 && _actual_speed != 1.0f) {
606  necessary_samples = (framecnt_t) ceil ((nframes * fabs (_actual_speed))) + 2;
607  } else {
608  necessary_samples = nframes;
609  }
610 
611  for (chan = c->begin(); chan != c->end(); ++chan) {
612  (*chan)->playback_buf->get_read_vector (&(*chan)->playback_vector);
613  }
614 
615  n = 0;
616 
617  /* Setup current_playback_buffer in each ChannelInfo to point to data that someone
618  can read necessary_samples (== nframes at a transport speed of 1) worth of data
619  from right now.
620  */
621 
622  for (chan = c->begin(); chan != c->end(); ++chan, ++n) {
623 
624  ChannelInfo* chaninfo (*chan);
625 
626  if (necessary_samples <= (framecnt_t) chaninfo->playback_vector.len[0]) {
627  /* There are enough samples in the first part of the ringbuffer */
628  chaninfo->current_playback_buffer = chaninfo->playback_vector.buf[0];
629 
630  } else {
631  framecnt_t total = chaninfo->playback_vector.len[0] + chaninfo->playback_vector.len[1];
632 
633  if (necessary_samples > total) {
634  cerr << _name << " Need " << necessary_samples << " total = " << total << endl;
635  cerr << "underrun for " << _name << endl;
636  DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 underrun in %2, rec_nframes = %3 total space = %4\n",
637  DEBUG_THREAD_SELF, name(), rec_nframes, total));
638  DiskUnderrun ();
639  return -1;
640 
641  } else {
642 
643  /* We have enough samples, but not in one lump. Coalesce the two parts
644  into one in playback_wrap_buffer in our ChannelInfo, and specify that
645  as our current_playback_buffer.
646  */
647 
648  assert(wrap_buffer_size >= necessary_samples);
649 
650  /* Copy buf[0] from playback_buf */
651  memcpy ((char *) chaninfo->playback_wrap_buffer,
652  chaninfo->playback_vector.buf[0],
653  chaninfo->playback_vector.len[0] * sizeof (Sample));
654 
655  /* Copy buf[1] from playback_buf */
656  memcpy (chaninfo->playback_wrap_buffer + chaninfo->playback_vector.len[0],
657  chaninfo->playback_vector.buf[1],
658  (necessary_samples - chaninfo->playback_vector.len[0])
659  * sizeof (Sample));
660 
661  chaninfo->current_playback_buffer = chaninfo->playback_wrap_buffer;
662  }
663  }
664  }
665 
666  if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
667 
669 
670  int channel = 0;
671  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++channel) {
672  ChannelInfo* chaninfo (*chan);
673 
674  playback_distance = interpolation.interpolate (
675  channel, nframes, chaninfo->current_playback_buffer, chaninfo->speed_buffer);
676 
677  chaninfo->current_playback_buffer = chaninfo->speed_buffer;
678  }
679 
680  } else {
681  playback_distance = nframes;
682  }
683 
685  }
686 
687  if (need_disk_signal) {
688 
689  /* copy data over to buffer set */
690 
691  size_t n_buffers = bufs.count().n_audio();
692  size_t n_chans = c->size();
693  gain_t scaling = 1.0f;
694 
695  if (n_chans > n_buffers) {
696  scaling = ((float) n_buffers)/n_chans;
697  }
698 
699  for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
700 
701  AudioBuffer& buf (bufs.get_audio (n%n_buffers));
702  ChannelInfo* chaninfo (*chan);
703 
704  if (n < n_chans) {
705  if (scaling != 1.0f) {
706  buf.read_from_with_gain (chaninfo->current_playback_buffer, nframes, scaling);
707  } else {
708  buf.read_from (chaninfo->current_playback_buffer, nframes);
709  }
710  } else {
711  if (scaling != 1.0f) {
712  buf.accumulate_with_gain_from (chaninfo->current_playback_buffer, nframes, scaling);
713  } else {
714  buf.accumulate_from (chaninfo->current_playback_buffer, nframes);
715  }
716  }
717  }
718 
719  /* leave the MIDI count alone */
720  ChanCount cnt (DataType::AUDIO, n_chans);
721  cnt.set (DataType::MIDI, bufs.count().n_midi());
722  bufs.set_count (cnt);
723 
724  /* extra buffers will already be silent, so leave them alone */
725  }
726 
727  return 0;
728 }
729 
732 {
733  frameoffset_t playback_distance = nframes;
734 
735  if (record_enabled()) {
736  playback_distance = nframes;
737  } else if (_actual_speed != 1.0f && _actual_speed != -1.0f) {
740  int channel = 0;
741  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++channel) {
742  playback_distance = interpolation.interpolate (channel, nframes, NULL, NULL);
743  }
744  } else {
745  playback_distance = nframes;
746  }
747 
748  if (_actual_speed < 0.0) {
749  return -playback_distance;
750  } else {
751  return playback_distance;
752  }
753 }
754 
759 bool
761 {
762  bool need_butler = false;
763 
764  if (!_io || !_io->active()) {
765  return false;
766  }
767 
768  if (_actual_speed < 0.0) {
769  playback_sample -= playback_distance;
770  } else {
771  playback_sample += playback_distance;
772  }
773 
775  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
776 
777  (*chan)->playback_buf->increment_read_ptr (playback_distance);
778 
780  (*chan)->capture_buf->increment_write_ptr (adjust_capture_position);
781  }
782  }
783 
784  if (adjust_capture_position != 0) {
787  }
788 
789  if (c->empty()) {
790  return false;
791  }
792 
793  if (_slaved) {
794  if (_io && _io->active()) {
795  need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2;
796  } else {
797  need_butler = false;
798  }
799  } else {
800  if (_io && _io->active()) {
801  need_butler = ((framecnt_t) c->front()->playback_buf->write_space() >= disk_read_chunk_frames)
802  || ((framecnt_t) c->front()->capture_buf->read_space() >= disk_write_chunk_frames);
803  } else {
804  need_butler = ((framecnt_t) c->front()->capture_buf->read_space() >= disk_write_chunk_frames);
805  }
806  }
807 
808  return need_butler;
809 }
810 
811 void
813 {
814  /* called from audio thread, so we can use the read ptr and playback sample as we wish */
815 
816  _pending_overwrite = yn;
817 
819 
821  if (!c->empty ()) {
822  overwrite_offset = c->front()->playback_buf->get_read_ptr();
823  }
824 }
825 
826 int
828 {
830  if (c->empty ()) {
831  _pending_overwrite = false;
832  return 0;
833  }
834 
835  Sample* mixdown_buffer;
836  float* gain_buffer;
837  int ret = -1;
839 
840  overwrite_queued = false;
841 
842  /* assume all are the same size */
843  framecnt_t size = c->front()->playback_buf->bufsize();
844 
845  mixdown_buffer = new Sample[size];
846  gain_buffer = new float[size];
847 
848  /* reduce size so that we can fill the buffer correctly (ringbuffers
849  can only handle size-1, otherwise they appear to be empty)
850  */
851  size--;
852 
853  uint32_t n=0;
855 
856  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++n) {
857 
858  start = overwrite_frame;
859  framecnt_t cnt = size;
860 
861  /* to fill the buffer without resetting the playback sample, we need to
862  do it one or two chunks (normally two).
863 
864  |----------------------------------------------------------------------|
865 
866  ^
867  overwrite_offset
868  |<- second chunk->||<----------------- first chunk ------------------>|
869 
870  */
871 
872  framecnt_t to_read = size - overwrite_offset;
873 
874  if (read ((*chan)->playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, start, to_read, n, reversed)) {
875  error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"),
876  id(), size, playback_sample) << endmsg;
877  goto out;
878  }
879 
880  if (cnt > to_read) {
881 
882  cnt -= to_read;
883 
884  if (read ((*chan)->playback_buf->buffer(), mixdown_buffer, gain_buffer, start, cnt, n, reversed)) {
885  error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"),
886  id(), size, playback_sample) << endmsg;
887  goto out;
888  }
889  }
890  }
891 
892  ret = 0;
893 
894  out:
895  _pending_overwrite = false;
896  delete [] gain_buffer;
897  delete [] mixdown_buffer;
898  return ret;
899 }
900 
901 int
902 AudioDiskstream::seek (framepos_t frame, bool complete_refill)
903 {
904  uint32_t n;
905  int ret = -1;
906  ChannelList::iterator chan;
908 
910 
911  for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
912  (*chan)->playback_buf->reset ();
913  (*chan)->capture_buf->reset ();
914  }
915 
916  /* can't rec-enable in destructive mode if transport is before start */
917 
918  if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
920  }
921 
922  playback_sample = frame;
923  file_frame = frame;
924 
925  if (complete_refill) {
926  while ((ret = do_refill_with_alloc ()) > 0) ;
927  } else {
928  ret = do_refill_with_alloc ();
929  }
930 
931  return ret;
932 }
933 
934 int
936 {
937  ChannelList::iterator chan;
939 
940  for (chan = c->begin(); chan != c->end(); ++chan) {
941  if ((*chan)->playback_buf->read_space() < (size_t) distance) {
942  return false;
943  }
944  }
945  return true;
946 }
947 
948 int
950 {
951  ChannelList::iterator chan;
953 
954  for (chan = c->begin(); chan != c->end(); ++chan) {
955  (*chan)->playback_buf->increment_read_ptr (llabs(distance));
956  }
957 
959  first_recordable_frame += distance;
960  }
961  playback_sample += distance;
962 
963  return 0;
964 }
965 
973 int
974 AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
976  int channel, bool reversed)
977 {
978  framecnt_t this_read = 0;
979  bool reloop = false;
980  framepos_t loop_end = 0;
981  framepos_t loop_start = 0;
982  framecnt_t offset = 0;
983  Location *loc = 0;
984 
985  /* XXX we don't currently play loops in reverse. not sure why */
986 
987  if (!reversed) {
988 
989  framecnt_t loop_length = 0;
990 
991  /* Make the use of a Location atomic for this read operation.
992 
993  Note: Locations don't get deleted, so all we care about
994  when I say "atomic" is that we are always pointing to
995  the same one and using a start/length values obtained
996  just once.
997  */
998 
999  if ((loc = loop_location) != 0) {
1000  loop_start = loc->start();
1001  loop_end = loc->end();
1002  loop_length = loop_end - loop_start;
1003  }
1004 
1005  /* if we are looping, ensure that the first frame we read is at the correct
1006  position within the loop.
1007  */
1008 
1009  if (loc && start >= loop_end) {
1010  start = loop_start + ((start - loop_start) % loop_length);
1011  }
1012 
1013  }
1014 
1015  if (reversed) {
1016  start -= cnt;
1017  }
1018 
1019  /* We need this while loop in case we hit a loop boundary, in which case our read from
1020  the playlist must be split into more than one section.
1021  */
1022 
1023  while (cnt) {
1024 
1025  /* take any loop into account. we can't read past the end of the loop. */
1026 
1027  if (loc && (loop_end - start < cnt)) {
1028  this_read = loop_end - start;
1029  reloop = true;
1030  } else {
1031  reloop = false;
1032  this_read = cnt;
1033  }
1034 
1035  if (this_read == 0) {
1036  break;
1037  }
1038 
1039  this_read = min(cnt,this_read);
1040 
1041  if (audio_playlist()->read (buf+offset, mixdown_buffer, gain_buffer, start, this_read, channel) != this_read) {
1042  error << string_compose(_("AudioDiskstream %1: cannot read %2 from playlist at frame %3"), id(), this_read,
1043  start) << endmsg;
1044  return -1;
1045  }
1046 
1047  if (reversed) {
1048 
1049  swap_by_ptr (buf, buf + this_read - 1);
1050 
1051  } else {
1052 
1053  /* if we read to the end of the loop, go back to the beginning */
1054 
1055  if (reloop) {
1056  start = loop_start;
1057  } else {
1058  start += this_read;
1059  }
1060  }
1061 
1062  cnt -= this_read;
1063  offset += this_read;
1064  }
1065 
1066  return 0;
1067 }
1068 
1069 int
1071 {
1072  Sample* mix_buf = new Sample[disk_read_chunk_frames];
1073  float* gain_buf = new float[disk_read_chunk_frames];
1074 
1075  int ret = _do_refill(mix_buf, gain_buf);
1076 
1077  delete [] mix_buf;
1078  delete [] gain_buf;
1079 
1080  return ret;
1081 }
1082 
1086 int
1087 AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer)
1088 {
1089  int32_t ret = 0;
1090  framecnt_t to_read;
1092  bool const reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1093  framecnt_t total_space;
1094  framecnt_t zero_fill;
1095  uint32_t chan_n;
1096  ChannelList::iterator i;
1098  framecnt_t ts;
1099 
1100  if (c->empty()) {
1101  return 0;
1102  }
1103 
1104  assert(mixdown_buffer);
1105  assert(gain_buffer);
1106 
1107  vector.buf[0] = 0;
1108  vector.len[0] = 0;
1109  vector.buf[1] = 0;
1110  vector.len[1] = 0;
1111 
1112  c->front()->playback_buf->get_write_vector (&vector);
1113 
1114  if ((total_space = vector.len[0] + vector.len[1]) == 0) {
1115  /* nowhere to write to */
1116  return 0;
1117  }
1118 
1119  /* if there are 2+ chunks of disk i/o possible for
1120  this track, let the caller know so that it can arrange
1121  for us to be called again, ASAP.
1122  */
1123 
1124  if (total_space >= (_slaved ? 3 : 2) * disk_read_chunk_frames) {
1125  ret = 1;
1126  }
1127 
1128  /* if we're running close to normal speed and there isn't enough
1129  space to do disk_read_chunk_frames of I/O, then don't bother.
1130 
1131  at higher speeds, just do it because the sync between butler
1132  and audio thread may not be good enough.
1133 
1134  Note: it is a design assumption that disk_read_chunk_frames is smaller
1135  than the playback buffer size, so this check should never trip when
1136  the playback buffer is empty.
1137  */
1138 
1139  if ((total_space < disk_read_chunk_frames) && fabs (_actual_speed) < 2.0f) {
1140  return 0;
1141  }
1142 
1143  /* when slaved, don't try to get too close to the read pointer. this
1144  leaves space for the buffer reversal to have something useful to
1145  work with.
1146  */
1147 
1148  if (_slaved && total_space < (framecnt_t) (c->front()->playback_buf->bufsize() / 2)) {
1149  return 0;
1150  }
1151 
1152  /* never do more than disk_read_chunk_frames worth of disk input per call (limit doesn't apply for memset) */
1153 
1154  total_space = min (disk_read_chunk_frames, total_space);
1155 
1156  if (reversed) {
1157 
1158  if (file_frame == 0) {
1159 
1160  /* at start: nothing to do but fill with silence */
1161 
1162  for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) {
1163 
1164  ChannelInfo* chan (*i);
1165  chan->playback_buf->get_write_vector (&vector);
1166  memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1167  if (vector.len[1]) {
1168  memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1169  }
1170  chan->playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1171  }
1172  return 0;
1173  }
1174 
1175  if (file_frame < total_space) {
1176 
1177  /* too close to the start: read what we can,
1178  and then zero fill the rest
1179  */
1180 
1181  zero_fill = total_space - file_frame;
1182  total_space = file_frame;
1183 
1184  } else {
1185 
1186  zero_fill = 0;
1187  }
1188 
1189  } else {
1190 
1191  if (file_frame == max_framepos) {
1192 
1193  /* at end: nothing to do but fill with silence */
1194 
1195  for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) {
1196 
1197  ChannelInfo* chan (*i);
1198  chan->playback_buf->get_write_vector (&vector);
1199  memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1200  if (vector.len[1]) {
1201  memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1202  }
1203  chan->playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1204  }
1205  return 0;
1206  }
1207 
1208  if (file_frame > max_framepos - total_space) {
1209 
1210  /* to close to the end: read what we can, and zero fill the rest */
1211 
1212  zero_fill = total_space - (max_framepos - file_frame);
1213  total_space = max_framepos - file_frame;
1214 
1215  } else {
1216  zero_fill = 0;
1217  }
1218  }
1219 
1220  framepos_t file_frame_tmp = 0;
1221 
1222  for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) {
1223 
1224  ChannelInfo* chan (*i);
1225  Sample* buf1;
1226  Sample* buf2;
1227  framecnt_t len1, len2;
1228 
1229  chan->playback_buf->get_write_vector (&vector);
1230 
1231  if ((framecnt_t) vector.len[0] > disk_read_chunk_frames) {
1232 
1233  /* we're not going to fill the first chunk, so certainly do not bother with the
1234  other part. it won't be connected with the part we do fill, as in:
1235 
1236  .... => writable space
1237  ++++ => readable space
1238  ^^^^ => 1 x disk_read_chunk_frames that would be filled
1239 
1240  |......|+++++++++++++|...............................|
1241  buf1 buf0
1242  ^^^^^^^^^^^^^^^
1243 
1244 
1245  So, just pretend that the buf1 part isn't there.
1246 
1247  */
1248 
1249  vector.buf[1] = 0;
1250  vector.len[1] = 0;
1251 
1252  }
1253 
1254  ts = total_space;
1255  file_frame_tmp = file_frame;
1256 
1257  buf1 = vector.buf[0];
1258  len1 = vector.len[0];
1259  buf2 = vector.buf[1];
1260  len2 = vector.len[1];
1261 
1262  to_read = min (ts, len1);
1263  to_read = min (to_read, disk_read_chunk_frames);
1264 
1265  assert (to_read >= 0);
1266 
1267  if (to_read) {
1268 
1269  if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan_n, reversed)) {
1270  ret = -1;
1271  goto out;
1272  }
1273 
1274  chan->playback_buf->increment_write_ptr (to_read);
1275  ts -= to_read;
1276  }
1277 
1278  to_read = min (ts, len2);
1279 
1280  if (to_read) {
1281 
1282  /* we read all of vector.len[0], but it wasn't an entire disk_read_chunk_frames of data,
1283  so read some or all of vector.len[1] as well.
1284  */
1285 
1286  if (read (buf2, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan_n, reversed)) {
1287  ret = -1;
1288  goto out;
1289  }
1290 
1291  chan->playback_buf->increment_write_ptr (to_read);
1292  }
1293 
1294  if (zero_fill) {
1295  /* XXX: do something */
1296  }
1297 
1298  }
1299 
1300  file_frame = file_frame_tmp;
1301  assert (file_frame >= 0);
1302 
1303  out:
1304 
1305  return ret;
1306 }
1307 
1318 int
1319 AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush)
1320 {
1321  uint32_t to_write;
1322  int32_t ret = 0;
1325  framecnt_t total;
1326 
1327  transvec.buf[0] = 0;
1328  transvec.buf[1] = 0;
1329  vector.buf[0] = 0;
1330  vector.buf[1] = 0;
1331 
1333  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1334 
1335  (*chan)->capture_buf->get_read_vector (&vector);
1336 
1337  total = vector.len[0] + vector.len[1];
1338 
1339  if (total == 0 || (total < disk_write_chunk_frames && !force_flush && was_recording)) {
1340  goto out;
1341  }
1342 
1343  /* if there are 2+ chunks of disk i/o possible for
1344  this track, let the caller know so that it can arrange
1345  for us to be called again, ASAP.
1346 
1347  if we are forcing a flush, then if there is* any* extra
1348  work, let the caller know.
1349 
1350  if we are no longer recording and there is any extra work,
1351  let the caller know too.
1352  */
1353 
1354  if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) {
1355  ret = 1;
1356  }
1357 
1358  to_write = min (disk_write_chunk_frames, (framecnt_t) vector.len[0]);
1359 
1360  // check the transition buffer when recording destructive
1361  // important that we get this after the capture buf
1362 
1363  if (destructive()) {
1364  (*chan)->capture_transition_buf->get_read_vector(&transvec);
1365  size_t transcount = transvec.len[0] + transvec.len[1];
1366  size_t ti;
1367 
1368  for (ti=0; ti < transcount; ++ti) {
1369  CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
1370 
1371  if (captrans.type == CaptureStart) {
1372  // by definition, the first data we got above represents the given capture pos
1373 
1374  (*chan)->write_source->mark_capture_start (captrans.capture_val);
1375  (*chan)->curr_capture_cnt = 0;
1376 
1377  } else if (captrans.type == CaptureEnd) {
1378 
1379  // capture end, the capture_val represents total frames in capture
1380 
1381  if (captrans.capture_val <= (*chan)->curr_capture_cnt + to_write) {
1382 
1383  // shorten to make the write a perfect fit
1384  uint32_t nto_write = (captrans.capture_val - (*chan)->curr_capture_cnt);
1385 
1386  if (nto_write < to_write) {
1387  ret = 1; // should we?
1388  }
1389  to_write = nto_write;
1390 
1391  (*chan)->write_source->mark_capture_end ();
1392 
1393  // increment past this transition, but go no further
1394  ++ti;
1395  break;
1396  }
1397  else {
1398  // actually ends just beyond this chunk, so force more work
1399  ret = 1;
1400  break;
1401  }
1402  }
1403  }
1404 
1405  if (ti > 0) {
1406  (*chan)->capture_transition_buf->increment_read_ptr(ti);
1407  }
1408  }
1409 
1410  if ((!(*chan)->write_source) || (*chan)->write_source->write (vector.buf[0], to_write) != to_write) {
1411  error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
1412  return -1;
1413  }
1414 
1415  (*chan)->capture_buf->increment_read_ptr (to_write);
1416  (*chan)->curr_capture_cnt += to_write;
1417 
1418  if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_write_chunk_frames) && !destructive()) {
1419 
1420  /* we wrote all of vector.len[0] but it wasn't an entire
1421  disk_write_chunk_frames of data, so arrange for some part
1422  of vector.len[1] to be flushed to disk as well.
1423  */
1424 
1425  to_write = min ((framecnt_t)(disk_write_chunk_frames - to_write), (framecnt_t) vector.len[1]);
1426 
1427  DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 additional write of %2\n", name(), to_write));
1428 
1429  if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) {
1430  error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
1431  return -1;
1432  }
1433 
1434  (*chan)->capture_buf->increment_read_ptr (to_write);
1435  (*chan)->curr_capture_cnt += to_write;
1436  }
1437  }
1438 
1439  out:
1440  return ret;
1441 }
1442 
1443 void
1444 AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abort_capture)
1445 {
1446  uint32_t buffer_position;
1447  bool more_work = true;
1448  int err = 0;
1450  framecnt_t total_capture;
1451  SourceList srcs;
1452  SourceList::iterator src;
1453  ChannelList::iterator chan;
1454  vector<CaptureInfo*>::iterator ci;
1456  uint32_t n = 0;
1457  bool mark_write_completed = false;
1458 
1459  finish_capture (c);
1460 
1461  /* butler is already stopped, but there may be work to do
1462  to flush remaining data to disk.
1463  */
1464 
1465  while (more_work && !err) {
1466  switch (do_flush (TransportContext, true)) {
1467  case 0:
1468  more_work = false;
1469  break;
1470  case 1:
1471  break;
1472  case -1:
1473  error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1474  err++;
1475  }
1476  }
1477 
1478  /* XXX is there anything we can do if err != 0 ? */
1480 
1481  if (capture_info.empty()) {
1482  return;
1483  }
1484 
1485  if (abort_capture) {
1486 
1487  if (destructive()) {
1488  goto outout;
1489  }
1490 
1491  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1492 
1493  if ((*chan)->write_source) {
1494 
1495  (*chan)->write_source->mark_for_remove ();
1496  (*chan)->write_source->drop_references ();
1497  (*chan)->write_source.reset ();
1498  }
1499 
1500  /* new source set up in "out" below */
1501  }
1502 
1503  goto out;
1504  }
1505 
1506  for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1507  total_capture += (*ci)->frames;
1508  }
1509 
1510  /* figure out the name for this take */
1511 
1512  for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
1513 
1514  boost::shared_ptr<AudioFileSource> s = (*chan)->write_source;
1515 
1516  if (s) {
1517  srcs.push_back (s);
1518  s->update_header (capture_info.front()->start, when, twhen);
1519  s->set_captured_for (_name.val());
1520  s->mark_immutable ();
1521 
1522  if (Config->get_auto_analyse_audio()) {
1524  }
1525  }
1526  }
1527 
1528  /* destructive tracks have a single, never changing region */
1529 
1530  if (destructive()) {
1531 
1532  /* send a signal that any UI can pick up to do the right thing. there is
1533  a small problem here in that a UI may need the peak data to be ready
1534  for the data that was recorded and this isn't interlocked with that
1535  process. this problem is deferred to the UI.
1536  */
1537 
1538  _playlist->LayeringChanged(); // XXX this may not get the UI to do the right thing
1539 
1540  } else {
1541 
1542  string whole_file_region_name;
1543  whole_file_region_name = region_name_from_path (c->front()->write_source->name(), true);
1544 
1545  /* Register a new region with the Session that
1546  describes the entire source. Do this first
1547  so that any sub-regions will obviously be
1548  children of this one (later!)
1549  */
1550 
1551  try {
1552  PropertyList plist;
1553 
1554  plist.add (Properties::start, c->front()->write_source->last_capture_start_frame());
1555  plist.add (Properties::length, total_capture);
1556  plist.add (Properties::name, whole_file_region_name);
1558  rx->set_automatic (true);
1559  rx->set_whole_file (true);
1560 
1562  region->special_set_position (capture_info.front()->start);
1563  }
1564 
1565 
1566  catch (failed_constructor& err) {
1567  error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1568  /* XXX what now? */
1569  }
1570 
1571  _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1572 
1575  _playlist->freeze ();
1576 
1577  for (buffer_position = c->front()->write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1578 
1579  string region_name;
1580 
1581  RegionFactory::region_name (region_name, whole_file_region_name, false);
1582 
1583  DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1584  _name, (*ci)->start, (*ci)->frames, region_name));
1585 
1586  try {
1587 
1588  PropertyList plist;
1589 
1590  plist.add (Properties::start, buffer_position);
1591  plist.add (Properties::length, (*ci)->frames);
1592  plist.add (Properties::name, region_name);
1593 
1596  }
1597 
1598  catch (failed_constructor& err) {
1599  error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1600  continue; /* XXX is this OK? */
1601  }
1602 
1604 
1605  _playlist->add_region (region, (*ci)->start, 1, non_layered());
1606  _playlist->set_layer (region, DBL_MAX);
1608 
1609  buffer_position += (*ci)->frames;
1610  }
1611 
1612  _playlist->thaw ();
1615  }
1616 
1617  mark_write_completed = true;
1618 
1619  out:
1620  reset_write_sources (mark_write_completed);
1621 
1622  outout:
1623 
1624  for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1625  delete *ci;
1626  }
1627 
1628  capture_info.clear ();
1629  capture_start_frame = 0;
1630 }
1631 
1632 void
1634 {
1635  if (was_recording) {
1636  // all we need to do is finish this capture, with modified capture length
1638 
1639  // adjust the capture length knowing that the data will be recorded to disk
1640  // only necessary after the first loop where we're recording
1641  if (capture_info.size() == 0) {
1643 
1646  } else {
1648  }
1649  }
1650 
1651  finish_capture (c);
1652 
1653  // the next region will start recording via the normal mechanism
1654  // we'll set the start position to the current transport pos
1655  // no latency adjustment or capture offset needs to be made, as that already happened the first time
1656  capture_start_frame = transport_frame;
1657  first_recordable_frame = transport_frame; // mild lie
1659  was_recording = true;
1660 
1661  if (recordable() && destructive()) {
1662  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1663 
1665  (*chan)->capture_transition_buf->get_write_vector(&transvec);
1666 
1667  if (transvec.len[0] > 0) {
1668  transvec.buf[0]->type = CaptureStart;
1669  transvec.buf[0]->capture_val = capture_start_frame;
1670  (*chan)->capture_transition_buf->increment_write_ptr(1);
1671  }
1672  else {
1673  // bad!
1674  fatal << X_("programming error: capture_transition_buf is full on rec loop! inconceivable!")
1675  << endmsg;
1676  }
1677  }
1678  }
1679 
1680  }
1681 }
1682 
1683 void
1685 {
1686  was_recording = false;
1689 
1690  if (capture_captured == 0) {
1691  return;
1692  }
1693 
1694  if (recordable() && destructive()) {
1695  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1696 
1698  (*chan)->capture_transition_buf->get_write_vector(&transvec);
1699 
1700  if (transvec.len[0] > 0) {
1701  transvec.buf[0]->type = CaptureEnd;
1702  transvec.buf[0]->capture_val = capture_captured;
1703  (*chan)->capture_transition_buf->increment_write_ptr(1);
1704  }
1705  else {
1706  // bad!
1707  fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record! inconceivable!")) << endmsg;
1708  }
1709  }
1710  }
1711 
1712 
1713  CaptureInfo* ci = new CaptureInfo;
1714 
1715  ci->start = capture_start_frame;
1716  ci->frames = capture_captured;
1717 
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).
1725  */
1726 
1727  DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("Finish capture, add new CI, %1 + %2\n", ci->start, ci->frames));
1728 
1729  capture_info.push_back (ci);
1730  capture_captured = 0;
1731 
1732  /* now we've finished a capture, reset first_recordable_frame for next time */
1734 }
1735 
1736 void
1738 {
1739  if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_audio() == 0) {
1740  return;
1741  }
1742 
1743  /* can't rec-enable in destructive mode if transport is before start */
1744 
1746  return;
1747  }
1748 
1749  /* yes, i know that this not proof against race conditions, but its
1750  good enough. i think.
1751  */
1752 
1753  if (record_enabled() != yn) {
1754  if (yn) {
1756  } else {
1758  }
1759 
1760  RecordEnableChanged (); /* EMIT SIGNAL */
1761  }
1762 }
1763 
1764 bool
1766 {
1767  if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_audio() == 0) {
1768  return false;
1769  }
1770 
1771  /* can't rec-enable in destructive mode if transport is before start */
1772 
1774  return false;
1775  }
1776 
1777  bool rolling = _session.transport_speed() != 0.0f;
1779 
1780  capturing_sources.clear ();
1781 
1782  if (Config->get_monitoring_model() == HardwareMonitoring) {
1783 
1784  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1785  (*chan)->source.request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1786  capturing_sources.push_back ((*chan)->write_source);
1787  Source::Lock lock((*chan)->write_source->mutex());
1788  (*chan)->write_source->mark_streaming_write_started (lock);
1789  }
1790 
1791  } else {
1792  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1793  capturing_sources.push_back ((*chan)->write_source);
1794  Source::Lock lock((*chan)->write_source->mutex());
1795  (*chan)->write_source->mark_streaming_write_started (lock);
1796  }
1797  }
1798 
1799  return true;
1800 }
1801 
1802 bool
1804 {
1806  if (Config->get_monitoring_model() == HardwareMonitoring) {
1807  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
1808  (*chan)->source.request_input_monitoring (false);
1809  }
1810  }
1811  capturing_sources.clear ();
1812 
1813  return true;
1814 }
1815 
1816 XMLNode&
1818 {
1819  XMLNode& node (Diskstream::get_state());
1820  char buf[64] = "";
1821  LocaleGuard lg (X_("C"));
1822 
1824  snprintf (buf, sizeof(buf), "%u", (unsigned int) c->size());
1825  node.add_property ("channels", buf);
1826 
1827  if (!capturing_sources.empty() && _session.get_record_enabled()) {
1828 
1829  XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1830  XMLNode* cs_grandchild;
1831 
1832  for (vector<boost::shared_ptr<AudioFileSource> >::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1833  cs_grandchild = new XMLNode (X_("file"));
1834  cs_grandchild->add_property (X_("path"), (*i)->path());
1835  cs_child->add_child_nocopy (*cs_grandchild);
1836  }
1837 
1838  /* store the location where capture will start */
1839 
1840  Location* pi;
1841 
1842  if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1843  snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1844  } else {
1845  snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1846  }
1847 
1848  cs_child->add_property (X_("at"), buf);
1849  node.add_child_nocopy (*cs_child);
1850  }
1851 
1852  return node;
1853 }
1854 
1855 int
1856 AudioDiskstream::set_state (const XMLNode& node, int version)
1857 {
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_("C"));
1864 
1865  /* prevent write sources from being created */
1866 
1867  in_set_state = true;
1868 
1869  for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1870  if ((*niter)->name() == IO::state_node_name) {
1871  deprecated_io_node = new XMLNode (**niter);
1872  }
1873 
1874  if ((*niter)->name() == X_("CapturingSources")) {
1875  capture_pending_node = *niter;
1876  }
1877  }
1878 
1879  if (Diskstream::set_state (node, version)) {
1880  return -1;
1881  }
1882 
1883  if ((prop = node.property ("channels")) != 0) {
1884  nchans = atoi (prop->value().c_str());
1885  }
1886 
1887  // create necessary extra channels
1888  // we are always constructed with one and we always need one
1889 
1891 
1892  if (nchans > _n_channels.n_audio()) {
1893 
1894  add_channel (nchans - _n_channels.n_audio());
1896 
1897  } else if (nchans < _n_channels.n_audio()) {
1898 
1899  remove_channel (_n_channels.n_audio() - nchans);
1900  }
1901 
1902 
1903 
1904  if (!destructive() && capture_pending_node) {
1905  /* destructive streams have one and only one source per channel,
1906  and so they never end up in pending capture in any useful
1907  sense.
1908  */
1909  use_pending_capture_data (*capture_pending_node);
1910  }
1911 
1912  in_set_state = false;
1913 
1914  /* make sure this is clear before we do anything else */
1915 
1916  capturing_sources.clear ();
1917 
1918  /* write sources are handled when we handle the input set
1919  up of the IO that owns this DS (::non_realtime_input_change())
1920  */
1921 
1922  return 0;
1923 }
1924 
1925 int
1927 {
1929 
1930  if (!recordable()) {
1931  return 1;
1932  }
1933 
1934  if (n >= c->size()) {
1935  error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg;
1936  return -1;
1937  }
1938 
1939  ChannelInfo* chan = (*c)[n];
1940 
1941  try {
1943  n_channels().n_audio(), write_source_name(), n, destructive())) == 0) {
1944  throw failed_constructor();
1945  }
1946  }
1947 
1948  catch (failed_constructor &err) {
1949  error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1950  chan->write_source.reset ();
1951  return -1;
1952  }
1953 
1954  /* do not remove destructive files even if they are empty */
1955 
1956  chan->write_source->set_allow_remove_if_empty (!destructive());
1957 
1958  return 0;
1959 }
1960 
1961 void
1962 AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1963 {
1964  ChannelList::iterator chan;
1966  uint32_t n;
1967 
1968  if (!_session.writable() || !recordable()) {
1969  return;
1970  }
1971 
1972  capturing_sources.clear ();
1973 
1974  for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
1975 
1976  if (!destructive()) {
1977 
1978  if ((*chan)->write_source) {
1979 
1980  if (mark_write_complete) {
1981  Source::Lock lock((*chan)->write_source->mutex());
1982  (*chan)->write_source->mark_streaming_write_completed (lock);
1983  (*chan)->write_source->done_with_peakfile_writes ();
1984  }
1985 
1986  if ((*chan)->write_source->removable()) {
1987  (*chan)->write_source->mark_for_remove ();
1988  (*chan)->write_source->drop_references ();
1989  }
1990 
1991  (*chan)->write_source.reset ();
1992  }
1993 
1995 
1996  if (record_enabled()) {
1997  capturing_sources.push_back ((*chan)->write_source);
1998  }
1999 
2000  } else {
2001 
2002  if ((*chan)->write_source == 0) {
2004  }
2005  }
2006  }
2007 
2008  if (destructive() && !c->empty ()) {
2009 
2010  /* we now have all our write sources set up, so create the
2011  playlist's single region.
2012  */
2013 
2014  if (_playlist->empty()) {
2016  }
2017  }
2018 }
2019 
2020 void
2022 {
2026 
2027  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
2028  if ((*chan)->speed_buffer)
2029  delete [] (*chan)->speed_buffer;
2030  (*chan)->speed_buffer = new Sample[speed_buffer_size];
2031  }
2032  }
2034 }
2035 
2036 void
2038 {
2039  /* make sure the wrap buffer is at least large enough to deal
2040  with the speeds up to 1.2, to allow for micro-variation
2041  when slaving to MTC, Timecode etc.
2042  */
2043 
2044  double const sp = max (fabsf (_actual_speed), 1.2f);
2045  framecnt_t required_wrap_size = (framecnt_t) ceil (_session.get_block_size() * sp) + 2;
2046 
2047  if (required_wrap_size > wrap_buffer_size) {
2048 
2050 
2051  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
2052  if ((*chan)->playback_wrap_buffer) {
2053  delete [] (*chan)->playback_wrap_buffer;
2054  }
2055  (*chan)->playback_wrap_buffer = new Sample[required_wrap_size];
2056  if ((*chan)->capture_wrap_buffer) {
2057  delete [] (*chan)->capture_wrap_buffer;
2058  }
2059  (*chan)->capture_wrap_buffer = new Sample[required_wrap_size];
2060  }
2061 
2062  wrap_buffer_size = required_wrap_size;
2063  }
2064 }
2065 
2066 void
2068 {
2070 
2071  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
2072  (*chan)->source.request_input_monitoring (yn);
2073  }
2074 }
2075 
2076 void
2078 {
2079  bool have_physical = false;
2080 
2081  if (_alignment_choice != Automatic) {
2082  return;
2083  }
2084 
2085  if (_io == 0) {
2086  return;
2087  }
2088 
2089  get_input_sources ();
2090 
2092 
2093  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
2094  if ((*chan)->source.is_physical ()) {
2095  have_physical = true;
2096  break;
2097  }
2098  }
2099 
2100  if (have_physical) {
2102  } else {
2104  }
2105 }
2106 
2107 int
2109 {
2110  while (how_many--) {
2111  c->push_back (new ChannelInfo(
2118  }
2119 
2120  _n_channels.set(DataType::AUDIO, c->size());
2121 
2122  return 0;
2123 }
2124 
2125 int
2126 AudioDiskstream::add_channel (uint32_t how_many)
2127 {
2130 
2131  return add_channel_to (c, how_many);
2132 }
2133 
2134 int
2136 {
2137  while (how_many-- && !c->empty()) {
2138  delete c->back();
2139  c->pop_back();
2141  }
2142 
2143  _n_channels.set(DataType::AUDIO, c->size());
2144 
2145  return 0;
2146 }
2147 
2148 int
2150 {
2153 
2154  return remove_channel_from (c, how_many);
2155 }
2156 
2157 float
2159 {
2161 
2162  if (c->empty ()) {
2163  return 0;
2164  }
2165 
2166  return (float) ((double) c->front()->playback_buf->read_space()/
2167  (double) c->front()->playback_buf->bufsize());
2168 }
2169 
2170 float
2172 {
2174 
2175  if (c->empty ()) {
2176  return 0;
2177  }
2178 
2179  return (float) ((double) c->front()->capture_buf->write_space()/
2180  (double) c->front()->capture_buf->bufsize());
2181 }
2182 
2183 int
2185 {
2186  const XMLProperty* prop;
2187  XMLNodeList nlist = node.children();
2188  XMLNodeIterator niter;
2191  SourceList pending_sources;
2193 
2194  if ((prop = node.property (X_("at"))) == 0) {
2195  return -1;
2196  }
2197 
2198  if (sscanf (prop->value().c_str(), "%" PRIu64, &position) != 1) {
2199  return -1;
2200  }
2201 
2202  for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2203  if ((*niter)->name() == X_("file")) {
2204 
2205  if ((prop = (*niter)->property (X_("path"))) == 0) {
2206  continue;
2207  }
2208 
2209  // This protects sessions from errant CapturingSources in stored sessions
2210  struct stat sbuf;
2211  if (stat (prop->value().c_str(), &sbuf)) {
2212  continue;
2213  }
2214 
2215  /* XXX as of June 2014, we always record to mono
2216  files. Since this Source is being created as part of
2217  crash recovery, we know that we need the first
2218  channel (the final argument to the SourceFactory
2219  call below). If we ever support non-mono files for
2220  capture, this will need rethinking.
2221  */
2222 
2223  try {
2225  }
2226 
2227  catch (failed_constructor& err) {
2228  error << string_compose (_("%1: cannot restore pending capture source file %2"),
2229  _name, prop->value())
2230  << endmsg;
2231  return -1;
2232  }
2233 
2234  pending_sources.push_back (fs);
2235 
2236  if (first_fs == 0) {
2237  first_fs = fs;
2238  }
2239 
2240  fs->set_captured_for (_name.val());
2241  }
2242  }
2243 
2244  if (pending_sources.size() == 0) {
2245  /* nothing can be done */
2246  return 1;
2247  }
2248 
2249  if (pending_sources.size() != _n_channels.n_audio()) {
2250  error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2251  << endmsg;
2252  return -1;
2253  }
2254 
2255  try {
2256 
2259 
2260  /* First create the whole file region */
2261 
2262  PropertyList plist;
2263 
2264  plist.add (Properties::start, 0);
2265  plist.add (Properties::length, first_fs->length (first_fs->timeline_position()));
2266  plist.add (Properties::name, region_name_from_path (first_fs->name(), true));
2267 
2268  wf_region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, plist));
2269 
2270  wf_region->set_automatic (true);
2271  wf_region->set_whole_file (true);
2272  wf_region->special_set_position (position);
2273 
2274  /* Now create a region that isn't the whole file for adding to
2275  * the playlist */
2276 
2277  region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, plist));
2278 
2279  _playlist->add_region (region, position);
2280  }
2281 
2282  catch (failed_constructor& err) {
2283  error << string_compose (
2284  _("%1: cannot create whole-file region from pending capture sources"),
2285  _name) << endmsg;
2286 
2287  return -1;
2288  }
2289 
2290 
2291  return 0;
2292 }
2293 
2294 int
2296 {
2297  if (yn != non_layered()) {
2298 
2299  if (yn) {
2300  _flags = Flag (_flags | NonLayered);
2301  } else {
2302  _flags = Flag (_flags & ~NonLayered);
2303  }
2304  }
2305 
2306  return 0;
2307 }
2308 
2309 int
2311 {
2312  if (yn != destructive()) {
2313 
2314  if (yn) {
2315  bool bounce_ignored;
2316  /* requestor should already have checked this and
2317  bounced if necessary and desired
2318  */
2319  if (!can_become_destructive (bounce_ignored)) {
2320  return -1;
2321  }
2322  _flags = Flag (_flags | Destructive);
2324  } else {
2325  _flags = Flag (_flags & ~Destructive);
2326  reset_write_sources (true, true);
2327  }
2328  }
2329 
2330  return 0;
2331 }
2332 
2333 bool
2334 AudioDiskstream::can_become_destructive (bool& requires_bounce) const
2335 {
2336  if (!_playlist) {
2337  requires_bounce = false;
2338  return false;
2339  }
2340 
2341  /* if no regions are present: easy */
2342 
2343  if (_playlist->n_regions() == 0) {
2344  requires_bounce = false;
2345  return true;
2346  }
2347 
2348  /* is there only one region ? */
2349 
2350  if (_playlist->n_regions() != 1) {
2351  requires_bounce = true;
2352  return false;
2353  }
2354 
2356  {
2357  const RegionList& rl (_playlist->region_list().rlist());
2358  assert((rl.size() == 1));
2359  first = rl.front();
2360 
2361  }
2362 
2363  if (!first) {
2364  requires_bounce = false;
2365  return true;
2366  }
2367 
2368  /* do the source(s) for the region cover the session start position ? */
2369 
2370  if (first->position() != _session.current_start_frame()) {
2371  // what is the idea here? why start() ??
2372  if (first->start() > _session.current_start_frame()) {
2373  requires_bounce = true;
2374  return false;
2375  }
2376  }
2377 
2378  /* currently RouteTimeAxisView::set_track_mode does not
2379  * implement bounce. Existing regions cannot be converted.
2380  *
2381  * so let's make sure this region is already set up
2382  * as tape-track (spanning the complete range)
2383  */
2384  if (first->length() != max_framepos - first->position()) {
2385  requires_bounce = true;
2386  return false;
2387  }
2388 
2389  /* is the source used by only 1 playlist ? */
2390 
2392 
2393  assert (afirst);
2394 
2395  if (_session.playlists->source_use_count (afirst->source()) > 1) {
2396  requires_bounce = true;
2397  return false;
2398  }
2399 
2400  requires_bounce = false;
2401  return true;
2402 }
2403 
2404 void
2406 {
2408 
2409  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
2410  (*chan)->resize_playback (_session.butler()->audio_diskstream_playback_buffer_size());
2411  }
2412 }
2413 
2414 void
2416 {
2418 
2419  for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
2420  (*chan)->resize_capture (_session.butler()->audio_diskstream_capture_buffer_size());
2421  }
2422 }
2423 
2424 bool
2426 {
2427  if (name.empty()) {
2428  return false;
2429  }
2430 
2431  return AudioEngine::instance()->port_is_physical (name);
2432 }
2433 
2434 void
2436 {
2437  if (name.empty()) {
2438  return;
2439  }
2440 
2441  return AudioEngine::instance()->request_input_monitoring (name, yn);
2442 }
2443 
2444 AudioDiskstream::ChannelInfo::ChannelInfo (framecnt_t playback_bufsize, framecnt_t capture_bufsize, framecnt_t speed_size, framecnt_t wrap_size)
2445 {
2446  current_capture_buffer = 0;
2447  current_playback_buffer = 0;
2448  curr_capture_cnt = 0;
2449 
2450  speed_buffer = new Sample[speed_size];
2451  playback_wrap_buffer = new Sample[wrap_size];
2452  capture_wrap_buffer = new Sample[wrap_size];
2453 
2454  playback_buf = new RingBufferNPT<Sample> (playback_bufsize);
2455  capture_buf = new RingBufferNPT<Sample> (capture_bufsize);
2456  capture_transition_buf = new RingBufferNPT<CaptureTransition> (256);
2457 
2458  /* touch the ringbuffer buffers, which will cause
2459  them to be mapped into locked physical RAM if
2460  we're running with mlockall(). this doesn't do
2461  much if we're not.
2462  */
2463 
2464  memset (playback_buf->buffer(), 0, sizeof (Sample) * playback_buf->bufsize());
2465  memset (capture_buf->buffer(), 0, sizeof (Sample) * capture_buf->bufsize());
2466  memset (capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * capture_transition_buf->bufsize());
2467 }
2468 
2469 void
2471 {
2472  delete playback_buf;
2473  playback_buf = new RingBufferNPT<Sample> (playback_bufsize);
2474  memset (playback_buf->buffer(), 0, sizeof (Sample) * playback_buf->bufsize());
2475 }
2476 
2477 void
2479 {
2480  delete capture_buf;
2481 
2482  capture_buf = new RingBufferNPT<Sample> (capture_bufsize);
2483  memset (capture_buf->buffer(), 0, sizeof (Sample) * capture_buf->bufsize());
2484 }
2485 
2487 {
2488  if (write_source) {
2489  if (write_source->removable()) {
2490  /* this is a "stub" write source which exists in the
2491  Session source list, but is removable. We must emit
2492  a drop references call because it should not
2493  continue to exist. If we do not do this, then the
2494  Session retains a reference to it, it is not
2495  deleted, and later attempts to create a new source
2496  file will use wierd naming because it already
2497  exists.
2498 
2499  XXX longer term TO-DO: do not add to session source
2500  list until we write to the source.
2501  */
2502  write_source->drop_references ();
2503  }
2504  }
2505 
2506  write_source.reset ();
2507 
2508  delete [] speed_buffer;
2509  speed_buffer = 0;
2510 
2511  delete [] playback_wrap_buffer;
2512  playback_wrap_buffer = 0;
2513 
2514  delete [] capture_wrap_buffer;
2515  capture_wrap_buffer = 0;
2516 
2517  delete playback_buf;
2518  playback_buf = 0;
2519 
2520  delete capture_buf;
2521  capture_buf = 0;
2522 
2523  delete capture_transition_buf;
2524  capture_transition_buf = 0;
2525 }
2526 
2527 
2528 bool
2529 AudioDiskstream::set_name (string const & name)
2530 {
2531  if (_name == name) {
2532  return true;
2533  }
2534  Diskstream::set_name (name);
2535 
2536  /* get a new write source so that its name reflects the new diskstream name */
2537 
2539  ChannelList::iterator i;
2540  int n = 0;
2541 
2542  for (n = 0, i = c->begin(); i != c->end(); ++i, ++n) {
2544  }
2545 
2546  return true;
2547 }
2548 
2549 bool
2550 AudioDiskstream::set_write_source_name (const std::string& str) {
2551  if (_write_source_name == str) {
2552  return true;
2553  }
2554 
2556 
2557  if (_write_source_name == name()) {
2558  return true;
2559  }
2561  ChannelList::iterator i;
2562  int n = 0;
2563 
2564  for (n = 0, i = c->begin(); i != c->end(); ++i, ++n) {
2566  }
2567  return true;
2568 }
framepos_t first_recordable_frame
Definition: diskstream.h:306
framecnt_t _capture_offset
Definition: diskstream.h:301
XMLNodeList::iterator XMLNodeIterator
Definition: xml++.h:48
ARDOUR::Session & _session
int internal_playback_seek(framecnt_t distance)
LIBPBD_API Transmitter fatal
void calculate_record_range(Evoral::OverlapType ot, framepos_t transport_frame, framecnt_t nframes, framecnt_t &rec_nframes, framecnt_t &rec_offset)
Definition: diskstream.cc:689
static int region_name(std::string &, std::string, bool new_level=false)
int atoi(const string &s)
Definition: convert.cc:140
boost::shared_ptr< Playlist > _playlist
Definition: diskstream.h:287
framecnt_t audio_diskstream_capture_buffer_size() const
Definition: butler.h:64
#define DEBUG_THREAD_SELF
Definition: debug.h:63
AudioBuffer & get_audio_buffer(pframes_t nframes)
Definition: audio_port.cc:74
const std::string & value() const
Definition: xml++.h:159
void flush()
Definition: rcu.h:191
bool get_record_enabled() const
Definition: session.h:272
bool non_layered() const
Definition: diskstream.h:116
int read(Sample *buf, Sample *mixdown_buffer, float *gain_buffer, framepos_t &start, framecnt_t cnt, int channel, bool reversed)
Glib::Threads::Mutex::Lock Lock
Definition: source.h:54
double transport_speed() const
Definition: session.h:590
boost::shared_ptr< AudioFileSource > create_audio_source_for_session(size_t, std::string const &, uint32_t, bool destructive)
Definition: session.cc:4022
bool writable() const
Definition: session.h:173
LIBARDOUR_API uint64_t Destruction
Definition: debug.cc:38
PBD::Signal0< void > RecordEnableChanged
Definition: diskstream.h:178
int remove_channel(uint32_t how_many)
void set_count(const ChanCount &count)
Definition: buffer_set.h:93
virtual bool set_name(const std::string &str)
Definition: diskstream.cc:440
void disengage_record_enable()
Definition: diskstream.cc:767
virtual void set_capture_offset()
Definition: diskstream.cc:244
bool actively_recording() const
Definition: session.h:280
std::list< boost::shared_ptr< Source > > _last_capture_sources
Definition: diskstream.h:253
void special_set_position(framepos_t)
Definition: region.cc:532
PBD::RingBufferNPT< Sample > * capture_buf
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
static PBD::Signal0< void > DiskUnderrun
Definition: diskstream.h:187
LIBARDOUR_API PBD::PropertyDescriptor< std::string > name
bool reversed() const
Definition: diskstream.h:117
T const & val() const
Definition: properties.h:96
framecnt_t wrap_buffer_size
Definition: diskstream.h:318
void set_layer(boost::shared_ptr< Region >, double)
Definition: playlist.cc:2334
static Sample * _mixdown_buffer
uint32_t i_am_the_modifier
Definition: diskstream.h:281
int set_state(const XMLNode &node, int version)
void add_command(Command *const cmd)
Definition: session.h:787
int add_channel_to(boost::shared_ptr< ChannelList >, uint32_t how_many)
void set_speed(double new_speed)
Definition: interpolation.h:45
int add_channel(uint32_t how_many)
bool port_is_physical(const std::string &) const
framepos_t last_recordable_frame
Definition: diskstream.h:307
bool destructive() const
Definition: diskstream.h:109
JACK does monitoring.
Definition: types.h:381
uint32_t pframes_t
Definition: types.h:61
uint32_t n_audio() const
Definition: chan_count.h:63
tuple f
Definition: signals.py:35
framepos_t end() const
Definition: location.h:72
Definition: Beats.hpp:239
LIBPBD_API Transmitter error
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
float gain_t
Definition: types.h:58
LIBARDOUR_API uint64_t CaptureAlignment
Definition: debug.cc:52
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
bool active() const
Definition: io.h:87
void request_input_monitoring(const std::string &, bool) const
SessionConfiguration config
Definition: session.h:866
AlignChoice _alignment_choice
Definition: diskstream.h:310
RunContext
Definition: types.h:492
boost::shared_ptr< Source > source(uint32_t n=0) const
Definition: region.h:258
virtual void check_record_status(framepos_t transport_frame, bool can_record)
Definition: diskstream.cc:601
static size_t _working_buffers_size
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
framepos_t capture_val
The start or end file frame position.
Definition: diskstream.h:224
frameoffset_t calculate_playback_distance(pframes_t nframes)
static AudioEngine * instance()
Definition: audioengine.h:196
AudioBuffer & get_audio(size_t i)
Definition: buffer_set.h:100
virtual bool set_write_source_name(const std::string &str)
Definition: diskstream.cc:451
PBD::RingBufferNPT< Sample >::rw_vector capture_vector
int _do_refill(Sample *mixdown_buffer, float *gain_buffer)
int process(BufferSet &, framepos_t transport_frame, pframes_t nframes, framecnt_t &, bool need_disk_signal)
std::string _write_source_name
Definition: diskstream.h:330
float playback_buffer_load() const
void thaw(bool from_undo=false)
Definition: playlist.cc:422
uint32_t n_midi() const
Definition: chan_count.h:66
framecnt_t audio_diskstream_playback_buffer_size() const
Definition: butler.h:65
AudioDiskstream(Session &, const std::string &name, Diskstream::Flag f=Recordable)
void finish_capture(boost::shared_ptr< ChannelList >)
boost::shared_ptr< AudioPort > audio(uint32_t n) const
Definition: io.cc:1430
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
int use_playlist(boost::shared_ptr< Playlist >)
void add_channel_to(int, int)
Definition: interpolation.h:51
Locations * locations()
Definition: session.h:382
boost::shared_ptr< AudioFileSource > write_source(uint32_t n=0)
std::vector< boost::shared_ptr< AudioFileSource > > capturing_sources
bool recordable() const
Definition: diskstream.h:115
#define _(Text)
Definition: i18n.h:11
CubicInterpolation interpolation
static framecnt_t disk_write_chunk_frames
Definition: diskstream.h:276
bool set_name(std::string const &)
IOChange input_change_pending
Definition: diskstream.h:317
Location * loop_location
Definition: diskstream.h:312
void add_region(boost::shared_ptr< Region >, framepos_t position, float times=1, bool auto_partition=false)
Definition: playlist.cc:668
PBD::RingBufferNPT< Sample > * playback_buf
const ChanCount & n_ports() const
Definition: io.h:135
LIBARDOUR_API uint64_t Butler
Definition: diskstream.h:191
Glib::Threads::Mutex state_lock
Definition: diskstream.h:332
void prepare_record_status(framepos_t capture_start_frame)
#define X_(Text)
Definition: i18n.h:13
ChannelInfo(framecnt_t playback_buffer_size, framecnt_t capture_buffer_size, framecnt_t speed_buffer_size, framecnt_t wrap_buffer_size)
void engage_record_enable()
Definition: diskstream.cc:761
int64_t framecnt_t
Definition: types.h:76
PBD::Signal0< void > LayeringChanged
Definition: playlist.h:194
XMLProperty * property(const char *)
Definition: xml++.cc:413
boost::shared_ptr< ARDOUR::IO > _io
Definition: diskstream.h:283
LIBARDOUR_API RCConfiguration * Config
Definition: globals.cc:119
float Sample
Definition: types.h:54
std::vector< CaptureInfo * > capture_info
Definition: diskstream.h:278
enum ARDOUR::IOChange::Type type
Container rlist() const
static std::string bump_name(std::string old_name, Session &)
Definition: playlist.cc:2292
static void queue_source_for_analysis(boost::shared_ptr< Source >, bool force)
Definition: analyser.cc:60
framepos_t transport_frame() const
Definition: session.h:551
Definition: amp.h:29
static void free_working_buffers()
float capture_buffer_load() const
framecnt_t adjust_capture_position
Definition: diskstream.h:300
static framecnt_t disk_read_chunk_frames
Definition: diskstream.h:275
int remove_channel_from(boost::shared_ptr< ChannelList >, uint32_t how_many)
framepos_t file_frame
Definition: diskstream.h:325
static PBD::Signal1< void, ChanCount > PortCountChanged
Definition: io.h:177
std::vector< ChannelInfo * > ChannelList
boost::shared_ptr< T > get_copy() const
Definition: rcu.h:250
bool record_enabled() const
Definition: diskstream.h:106
framecnt_t worst_output_latency() const
Definition: session.h:394
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
int seek(framepos_t which_sample, bool complete_refill=false)
int64_t framepos_t
Definition: types.h:66
int use_pending_capture_data(XMLNode &node)
virtual int set_state(const XMLNode &, int version)
Definition: diskstream.cc:480
int64_t frameoffset_t
Definition: types.h:71
static int loading_state_version
Definition: stateful.h:90
PBD::Property< std::string > _name
framepos_t capture_start_frame
Definition: diskstream.h:297
void set_whole_file(bool yn)
Definition: region.cc:948
std::list< boost::shared_ptr< Region > > RegionList
Definition: types.h:87
bool hidden() const
Definition: diskstream.h:114
framepos_t position() const
Definition: region.h:112
SerializedRCUManager< ChannelList > channels
int find_and_use_playlist(const std::string &)
double speed() const
Definition: diskstream.h:118
XMLProperty * add_property(const char *name, const std::string &value)
ChanCount n_channels()
Definition: diskstream.h:139
boost::shared_ptr< Port > nth(uint32_t n) const
Definition: io.h:122
framecnt_t interpolate(int channel, framecnt_t nframes, Sample *input, Sample *output)
boost::shared_ptr< AudioFileSource > write_source
uint32_t n_regions() const
Definition: playlist.cc:2237
size_t capacity() const
Definition: buffer.h:51
void set_capture_insertion_in_progress(bool yn)
Definition: playlist.cc:3252
MonitorState monitoring_state() const
Definition: track.cc:894
const char * name
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
void transport_stopped_wallclock(struct tm &, time_t, bool abort)
pframes_t get_block_size() const
Definition: session.h:393
void set_captured_for(std::string str)
Definition: audiosource.h:68
framecnt_t _roll_delay
Definition: diskstream.h:305
const RegionListProperty & region_list() const
Definition: playlist.h:163
void set_length(framecnt_t)
Definition: region.cc:430
framepos_t current_start_frame() const
Definition: session.cc:5042
Definition: xml++.h:95
ChanCount _n_channels
Definition: diskstream.h:285
std::string name() const
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
Definition: region.cc:65
const ChanCount & count() const
Definition: buffer_set.h:87
void set(DataType t, uint32_t count)
Definition: chan_count.h:58
void get_write_vector(rw_vector *)
void increment_write_ptr(size_t cnt)
Definition: ringbufferNPT.h:79
OverlapType coverage(T sa, T ea, T sb, T eb)
Definition: Range.hpp:40
framecnt_t capture_captured
Definition: diskstream.h:298
int use_new_write_source(uint32_t n=0)
static void allocate_working_buffers()
OverlapType
Definition: Range.hpp:31
bool record_enabling_legal() const
Definition: session.cc:1275
void transport_looped(framepos_t transport_frame)
Definition: debug.h:30
void set_block_size(pframes_t)
framepos_t timeline_position() const
Definition: source.h:100
static const std::string state_node_name
Definition: io.h:70
framepos_t playback_sample
Definition: diskstream.h:326
boost::shared_ptr< SessionPlaylists > playlists
Definition: session.h:907
void set_automatic(bool yn)
Definition: region.cc:955
framepos_t start() const
Definition: location.h:71
framecnt_t length() const
Definition: region.h:114
static const framepos_t max_framepos
Definition: types.h:78
static boost::shared_ptr< Source > createForRecovery(DataType type, Session &, const std::string &path, int chn)
framepos_t start() const
Definition: region.h:113
int can_internal_playback_seek(framecnt_t distance)
const Sample * data(framecnt_t offset=0) const
Definition: audio_buffer.h:187
void reset_write_sources(bool, bool force=false)
boost::shared_ptr< AudioPlaylist > audio_playlist()
Definition: rcu.h:217
std::string write_source_name() const
Definition: diskstream.h:75
boost::shared_ptr< T > reader() const
Definition: rcu.h:58
Glib::Threads::Mutex capture_info_lock
Definition: diskstream.h:279
framecnt_t length(framepos_t pos) const
Definition: audiosource.cc:161
static boost::shared_ptr< Region > create(boost::shared_ptr< const Region > other, bool announce=false)
PBD::RingBufferNPT< Sample >::rw_vector playback_vector
framepos_t overwrite_frame
Definition: diskstream.h:313
framecnt_t speed_buffer_size
Definition: diskstream.h:319
virtual int use_playlist(boost::shared_ptr< Playlist >)
Definition: diskstream.cc:356
boost::shared_ptr< Playlist > playlist()
Definition: diskstream.h:127
virtual XMLNode & get_state(void)
Definition: diskstream.cc:457
void set_align_style(AlignStyle, bool force=false)
Definition: diskstream.cc:267
static boost::shared_ptr< Playlist > create(Session &, const XMLNode &, bool hidden=false, bool unused=false)
void clear_changes()
Definition: stateful.cc:184
size_t bufsize() const
std::vector< boost::shared_ptr< Source > > SourceList
Definition: types.h:520
LIBARDOUR_API std::string region_name_from_path(std::string path, bool strip_channels, bool add_channel_suffix=false, uint32_t total=0, uint32_t this_one=0)
bool add(PropertyBase *prop)
bool can_become_destructive(bool &requires_bounce) const
XMLNode * deprecated_io_node
Definition: diskstream.h:339
static gain_t * _gain_buffer
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
virtual int update_header(framepos_t when, struct tm &, time_t)=0
bool set_write_source_name(const std::string &str)
int do_flush(RunContext context, bool force=false)
static PBD::Signal0< void > DiskOverrun
Definition: diskstream.h:186
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > length
Definition: region.cc:64
void non_realtime_locate(framepos_t location)
bool empty() const
Definition: playlist.cc:2230
Location * auto_punch_location() const
Definition: location.cc:1370
AlignStyle _alignment_style
Definition: diskstream.h:309
Butler * butler()
Definition: session.h:221
static void swap_by_ptr(Sample *first, Sample *last)