X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Faudio_diskstream.cc;h=8e6b5c27f1af8cfd917d43f10bf246c087b47cb3;hb=1db2be2fef7a70f5200bcd96a701f612bbd7ec52;hp=36d72ce124bc599c21cd3d3fa5bda3008e3050ff;hpb=148c1f805bca9d459d9a24a6b5c8d5f277680a9e;p=ardour.git diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 36d72ce124..8e6b5c27f1 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -31,35 +31,30 @@ #include #include "pbd/error.h" -#include #include "pbd/xml++.h" #include "pbd/memento_command.h" #include "pbd/enumwriter.h" #include "pbd/stateful_diff_command.h" #include "ardour/analyser.h" -#include "ardour/ardour.h" #include "ardour/audio_buffer.h" #include "ardour/audio_diskstream.h" #include "ardour/audio_port.h" #include "ardour/audioengine.h" #include "ardour/audiofilesource.h" - #include "ardour/audioplaylist.h" #include "ardour/audioregion.h" #include "ardour/butler.h" -#include "ardour/configuration.h" -#include "ardour/cycle_timer.h" #include "ardour/debug.h" #include "ardour/io.h" #include "ardour/playlist_factory.h" #include "ardour/region_factory.h" -#include "ardour/send.h" #include "ardour/session.h" +#include "ardour/session_playlists.h" #include "ardour/source_factory.h" +#include "ardour/track.h" +#include "ardour/types.h" #include "ardour/utils.h" -#include "ardour/session_playlists.h" -#include "ardour/route.h" #include "i18n.h" #include @@ -162,7 +157,7 @@ AudioDiskstream::non_realtime_input_change () return; } - { + if (input_change_pending.type == IOChange::ConfigurationChanged) { RCUWriter writer (channels); boost::shared_ptr c = writer.get_copy(); @@ -175,9 +170,11 @@ AudioDiskstream::non_realtime_input_change () } } - get_input_sources (); - set_capture_offset (); - set_align_style_from_io (); + if (input_change_pending.type & IOChange::ConnectionsChanged) { + get_input_sources (); + set_capture_offset (); + set_align_style_from_io (); + } input_change_pending = IOChange::NoChange; @@ -223,20 +220,13 @@ AudioDiskstream::get_input_sources () connections.clear (); - cerr << "Getting Nth connection from io " << n << " = " << _io->nth(n) << endl; - if (_io->nth (n)->get_connections (connections) == 0) { - - cerr << "\tThere were NO connections, apparently ...\n"; - if ((*chan)->source) { + if (!(*chan)->source.name.empty()) { // _source->disable_metering (); } - - (*chan)->source = 0; - + (*chan)->source.name = string(); } else { - cerr << "\tThere were some connections, apparently ... to " << connections[0] << endl; - (*chan)->source = dynamic_cast(_session.engine().get_port_by_name (connections[0]) ); + (*chan)->source.name = connections[0]; } } } @@ -286,7 +276,6 @@ AudioDiskstream::use_new_playlist () if ((playlist = boost::dynamic_pointer_cast (PlaylistFactory::create (DataType::AUDIO, _session, newname, hidden()))) != 0) { - playlist->set_orig_diskstream_id (id()); return use_playlist (playlist); } else { @@ -314,7 +303,6 @@ AudioDiskstream::use_copy_playlist () newname = Playlist::bump_name (_playlist->name(), _session); if ((playlist = boost::dynamic_pointer_cast(PlaylistFactory::create (audio_playlist(), newname))) != 0) { - playlist->set_orig_diskstream_id (id()); return use_playlist (playlist); } else { return -1; @@ -368,7 +356,7 @@ AudioDiskstream::use_destructive_playlist () /* be sure to stretch the region out to the maximum length */ - region->set_length (max_framepos - region->position(), this); + region->set_length (max_framepos - region->position()); uint32_t n; ChannelList::iterator chan; @@ -410,16 +398,25 @@ AudioDiskstream::prepare_record_status(framepos_t capture_start_frame) } } + +/** Do some record stuff [not described in this comment!] + * + * Also: + * - Setup playback_distance with the nframes, or nframes adjusted + * for current varispeed, if appropriate. + * - Setup current_playback_buffer in each ChannelInfo to point to data + * that someone can read playback_distance worth of data from. + */ int -AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can_record, bool rec_monitors_input, bool& need_butler) +AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance) { uint32_t n; boost::shared_ptr c = channels.reader(); ChannelList::iterator chan; - int ret = -1; framecnt_t rec_offset = 0; framecnt_t rec_nframes = 0; bool collect_playback = false; + bool can_record = _session.actively_recording (); playback_distance = 0; @@ -446,30 +443,22 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca (*chan)->current_playback_buffer = 0; } - /* two conditions to test for here: - - A: this track is rec-enabled, and the session has confirmed that we can record - B: this track is rec-enabled, has been recording, and we are set up for auto-punch-in - - The second test is necessary to capture the extra material that arrives AFTER the transport - frame has left the punch range (which will cause the "can_record" argument to be false). - */ - - - // Safeguard against situations where process() goes haywire when autopunching + // Safeguard against situations where process() goes haywire when autopunching // and last_recordable_frame < first_recordable_frame if (last_recordable_frame < first_recordable_frame) { last_recordable_frame = max_framepos; } - OverlapType ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes); + if (record_enabled()) { - calculate_record_range (ot, transport_frame, nframes, rec_nframes, rec_offset); + Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes); + calculate_record_range (ot, transport_frame, nframes, rec_nframes, rec_offset); - if (rec_nframes && !was_recording) { - capture_captured = 0; - was_recording = true; + if (rec_nframes && !was_recording) { + capture_captured = 0; + was_recording = true; + } } if (can_record && !_last_capture_sources.empty()) { @@ -501,11 +490,12 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca for recording, and use rec_offset */ - AudioPort* const ap = _io->audio (n); + boost::shared_ptr const ap = _io->audio (n); assert(ap); assert(rec_nframes <= (framecnt_t) ap->get_audio_buffer(nframes).capacity()); - memcpy (chaninfo->current_capture_buffer, ap->get_audio_buffer (nframes).data(rec_offset), sizeof (Sample) * rec_nframes); + Sample *buf = ap->get_audio_buffer (nframes).data (rec_offset); + memcpy (chaninfo->current_capture_buffer, buf, sizeof (Sample) * rec_nframes); } else { @@ -513,13 +503,13 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca if (rec_nframes > total) { DiskOverrun (); - goto out; + return -1; } - AudioPort* const ap = _io->audio (n); + boost::shared_ptr const ap = _io->audio (n); assert(ap); - Sample* buf = ap->get_audio_buffer(nframes).data(); + Sample* buf = ap->get_audio_buffer(nframes).data (rec_offset); framecnt_t first = chaninfo->capture_vector.len[0]; memcpy (chaninfo->capture_wrap_buffer, buf, sizeof (Sample) * first); @@ -534,7 +524,7 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca } else { if (was_recording) { - finish_capture (rec_monitors_input, c); + finish_capture (c); } } @@ -579,8 +569,8 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca collect_playback = true; } - if (collect_playback) { - + if ((_track->monitoring_state () & MonitoringDisk) || collect_playback) { + /* we're doing playback */ framecnt_t necessary_samples; @@ -599,12 +589,17 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca n = 0; + /* Setup current_playback_buffer in each ChannelInfo to point to data that someone + can read necessary_samples (== nframes at a transport speed of 1) worth of data + from right now. + */ + for (chan = c->begin(); chan != c->end(); ++chan, ++n) { ChannelInfo* chaninfo (*chan); if (necessary_samples <= (framecnt_t) chaninfo->playback_vector.len[0]) { - + /* There are enough samples in the first part of the ringbuffer */ chaninfo->current_playback_buffer = chaninfo->playback_vector.buf[0]; } else { @@ -614,13 +609,21 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca cerr << _name << " Need " << necessary_samples << " total = " << total << endl; cerr << "underrun for " << _name << endl; DiskUnderrun (); - goto out; + return -1; } else { + /* We have enough samples, but not in one lump. Coalesce the two parts + into one in playback_wrap_buffer in our ChannelInfo, and specify that + as our current_playback_buffer. + */ + + /* Copy buf[0] from playback_buf */ memcpy ((char *) chaninfo->playback_wrap_buffer, chaninfo->playback_vector.buf[0], chaninfo->playback_vector.len[0] * sizeof (Sample)); + + /* Copy buf[1] from playback_buf */ memcpy (chaninfo->playback_wrap_buffer + chaninfo->playback_vector.len[0], chaninfo->playback_vector.buf[1], (necessary_samples - chaninfo->playback_vector.len[0]) @@ -632,45 +635,35 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool ca } if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) { - process_varispeed_playback(nframes, c); + + interpolation.set_speed (_target_speed); + + int channel = 0; + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++channel) { + ChannelInfo* chaninfo (*chan); + + playback_distance = interpolation.interpolate ( + channel, nframes, chaninfo->current_playback_buffer, chaninfo->speed_buffer); + + chaninfo->current_playback_buffer = chaninfo->speed_buffer; + } + } else { playback_distance = nframes; } _speed = _target_speed; - - } - - ret = 0; - - if (commit (nframes)) { - need_butler = true; } - out: - return ret; -} - -void -AudioDiskstream::process_varispeed_playback (pframes_t nframes, boost::shared_ptr c) -{ - ChannelList::iterator chan; - - interpolation.set_speed (_target_speed); - - int channel = 0; - for (chan = c->begin(); chan != c->end(); ++chan, ++channel) { - ChannelInfo* chaninfo (*chan); - - playback_distance = interpolation.interpolate ( - channel, nframes, chaninfo->current_playback_buffer, chaninfo->speed_buffer); - - chaninfo->current_playback_buffer = chaninfo->speed_buffer; - } + return 0; } +/** Update various things including playback_sample, read pointer on each channel's playback_buf + * and write pointer on each channel's capture_buf. Also wout whether the butler is needed. + * @return true if the butler is required. + */ bool -AudioDiskstream::commit (framecnt_t /* nframes */) +AudioDiskstream::commit (framecnt_t playback_distance) { bool need_butler = false; @@ -698,11 +691,11 @@ AudioDiskstream::commit (framecnt_t /* nframes */) capture_captured += adjust_capture_position; adjust_capture_position = 0; } - + if (c->empty()) { return false; } - + if (_slaved) { if (_io && _io->active()) { need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2; @@ -744,7 +737,7 @@ AudioDiskstream::overwrite_existing_buffers () _pending_overwrite = false; return 0; } - + Sample* mixdown_buffer; float* gain_buffer; int ret = -1; @@ -758,7 +751,9 @@ AudioDiskstream::overwrite_existing_buffers () mixdown_buffer = new Sample[size]; gain_buffer = new float[size]; - /* reduce size so that we can fill the buffer correctly. */ + /* reduce size so that we can fill the buffer correctly (ringbuffers + can only handle size-1, otherwise they appear to be empty) + */ size--; uint32_t n=0; @@ -782,9 +777,9 @@ AudioDiskstream::overwrite_existing_buffers () framecnt_t to_read = size - overwrite_offset; - if (read ((*chan)->playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, start, to_read, *chan, n, reversed)) { + if (read ((*chan)->playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, start, to_read, n, reversed)) { error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"), - _id, size, playback_sample) << endmsg; + id(), size, playback_sample) << endmsg; goto out; } @@ -792,10 +787,9 @@ AudioDiskstream::overwrite_existing_buffers () cnt -= to_read; - if (read ((*chan)->playback_buf->buffer(), mixdown_buffer, gain_buffer, - start, cnt, *chan, n, reversed)) { + if (read ((*chan)->playback_buf->buffer(), mixdown_buffer, gain_buffer, start, cnt, n, reversed)) { error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"), - _id, size, playback_sample) << endmsg; + id(), size, playback_sample) << endmsg; goto out; } } @@ -875,10 +869,17 @@ AudioDiskstream::internal_playback_seek (framecnt_t distance) return 0; } +/** Read some data for 1 channel from our playlist into a buffer. + * @param buf Buffer to write to. + * @param start Session frame to start reading from; updated to where we end up + * after the read. + * @param cnt Count of samples to read. + * @param reversed true if we are running backwards, otherwise false. + */ int -AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, +AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, framepos_t& start, framecnt_t cnt, - ChannelInfo* /*channel_info*/, int channel, bool reversed) + int channel, bool reversed) { framecnt_t this_read = 0; bool reloop = false; @@ -912,25 +913,24 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, */ if (loc && start >= loop_end) { - //cerr << "start adjusted from " << start; start = loop_start + ((start - loop_start) % loop_length); - //cerr << "to " << start << endl; } - - //cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl; } if (reversed) { start -= cnt; } - + + /* We need this while loop in case we hit a loop boundary, in which case our read from + the playlist must be split into more than one section. + */ + while (cnt) { /* take any loop into account. we can't read past the end of the loop. */ if (loc && (loop_end - start < cnt)) { this_read = loop_end - start; - //cerr << "reloop true: thisread: " << this_read << " cnt: " << cnt << endl; reloop = true; } else { reloop = false; @@ -944,13 +944,11 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, this_read = min(cnt,this_read); if (audio_playlist()->read (buf+offset, mixdown_buffer, gain_buffer, start, this_read, channel) != this_read) { - error << string_compose(_("AudioDiskstream %1: cannot read %2 from playlist at frame %3"), _id, this_read, + error << string_compose(_("AudioDiskstream %1: cannot read %2 from playlist at frame %3"), id(), this_read, start) << endmsg; return -1; } - _read_data_count = _playlist->read_data_count(); - if (reversed) { swap_by_ptr (buf, buf + this_read - 1); @@ -987,13 +985,16 @@ AudioDiskstream::do_refill_with_alloc () return ret; } +/** Get some more data from disk and put it in our channels' playback_bufs, + * if there is suitable space in them. + */ int AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) { int32_t ret = 0; framecnt_t to_read; RingBufferNPT::rw_vector vector; - bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f; + bool const reversed = (_visible_speed * _session.transport_speed()) < 0.0f; framecnt_t total_space; framecnt_t zero_fill; uint32_t chan_n; @@ -1016,6 +1017,7 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) c->front()->playback_buf->get_write_vector (&vector); if ((total_space = vector.len[0] + vector.len[1]) == 0) { + /* nowhere to write to */ return 0; } @@ -1024,7 +1026,7 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) for us to be called again, ASAP. */ - if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) { + if (total_space >= (_slaved ? 3 : 2) * disk_io_chunk_frames) { ret = 1; } @@ -1033,6 +1035,10 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) at higher speeds, just do it because the sync between butler and audio thread may not be good enough. + + Note: it is a design assumption that disk_io_chunk_frames is smaller + than the playback buffer size, so this check should never trip when + the playback buffer is empty. */ if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) { @@ -1165,7 +1171,7 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) if (to_read) { - if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) { + if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan_n, reversed)) { ret = -1; goto out; } @@ -1182,7 +1188,7 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) so read some or all of vector.len[1] as well. */ - if (read (buf2, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) { + if (read (buf2, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan_n, reversed)) { ret = -1; goto out; } @@ -1191,14 +1197,14 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) } if (zero_fill) { - /* do something */ + /* XXX: do something */ } } file_frame = file_frame_tmp; assert (file_frame >= 0); - + out: return ret; @@ -1223,8 +1229,6 @@ AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush) RingBufferNPT::rw_vector transvec; framecnt_t total; - _write_data_count = 0; - transvec.buf[0] = 0; transvec.buf[1] = 0; vector.buf[0] = 0; @@ -1264,7 +1268,6 @@ AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush) if (destructive()) { (*chan)->capture_transition_buf->get_read_vector(&transvec); size_t transcount = transvec.len[0] + transvec.len[1]; - bool have_start = false; size_t ti; for (ti=0; ti < transcount; ++ti) { @@ -1276,9 +1279,7 @@ AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush) (*chan)->write_source->mark_capture_start (captrans.capture_val); (*chan)->curr_capture_cnt = 0; - have_start = true; - } - else if (captrans.type == CaptureEnd) { + } else if (captrans.type == CaptureEnd) { // capture end, the capture_val represents total frames in capture @@ -1312,7 +1313,7 @@ AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush) } if ((!(*chan)->write_source) || (*chan)->write_source->write (vector.buf[0], to_write) != to_write) { - error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg; + error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg; return -1; } @@ -1329,12 +1330,10 @@ AudioDiskstream::do_flush (RunContext /*context*/, bool force_flush) to_write = min ((framecnt_t)(disk_io_chunk_frames - to_write), (framecnt_t) vector.len[1]); if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) { - error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg; + error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg; return -1; } - _write_data_count += (*chan)->write_source->write_data_count(); - (*chan)->capture_buf->increment_read_ptr (to_write); (*chan)->curr_capture_cnt += to_write; } @@ -1360,7 +1359,7 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo uint32_t n = 0; bool mark_write_completed = false; - finish_capture (true, c); + finish_capture (c); /* butler is already stopped, but there may be work to do to flush remaining data to disk. @@ -1477,6 +1476,7 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n"; _playlist->clear_changes (); + _playlist->set_capture_insertion_in_progress (true); _playlist->freeze (); for (buffer_position = c->front()->write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) { @@ -1485,16 +1485,17 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo RegionFactory::region_name (region_name, whole_file_region_name, false); - // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add region " << region_name << endl; + DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n", + _name, (*ci)->start, (*ci)->frames, region_name)); try { PropertyList plist; - + plist.add (Properties::start, buffer_position); plist.add (Properties::length, (*ci)->frames); plist.add (Properties::name, region_name); - + boost::shared_ptr rx (RegionFactory::create (srcs, plist)); region = boost::dynamic_pointer_cast (rx); } @@ -1506,21 +1507,15 @@ AudioDiskstream::transport_stopped_wallclock (struct tm& when, time_t twhen, boo i_am_the_modifier++; - if (_playlist->explicit_relayering()) { - /* We are in `explicit relayering' mode, so we must specify which layer this new region - should end up on. Put it at the top. - */ - region->set_layer (_playlist->top_layer() + 1); - region->set_pending_explicit_relayer (true); - } - _playlist->add_region (region, (*ci)->start, 1, non_layered()); + _playlist->set_layer (region, DBL_MAX); i_am_the_modifier--; buffer_position += (*ci)->frames; } _playlist->thaw (); + _playlist->set_capture_insertion_in_progress (false); _session.add_command (new StatefulDiffCommand (_playlist)); } @@ -1558,7 +1553,7 @@ AudioDiskstream::transport_looped (framepos_t transport_frame) } } - finish_capture (true, c); + finish_capture (c); // the next region will start recording via the normal mechanism // we'll set the start position to the current transport pos @@ -1591,7 +1586,7 @@ AudioDiskstream::transport_looped (framepos_t transport_frame) } void -AudioDiskstream::finish_capture (bool /*rec_monitors_input*/, boost::shared_ptr c) +AudioDiskstream::finish_capture (boost::shared_ptr c) { was_recording = false; first_recordable_frame = max_framepos; @@ -1681,9 +1676,7 @@ AudioDiskstream::engage_record_enable () if (Config->get_monitoring_model() == HardwareMonitoring) { for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->source) { - (*chan)->source->ensure_monitor_input (!(_session.config.get_auto_input() && rolling)); - } + (*chan)->source.request_jack_monitors_input (!(_session.config.get_auto_input() && rolling)); capturing_sources.push_back ((*chan)->write_source); (*chan)->write_source->mark_streaming_write_started (); } @@ -1705,9 +1698,7 @@ AudioDiskstream::disengage_record_enable () boost::shared_ptr c = channels.reader(); if (Config->get_monitoring_model() == HardwareMonitoring) { for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->source) { - (*chan)->source->ensure_monitor_input (false); - } + (*chan)->source.request_jack_monitors_input (false); } } capturing_sources.clear (); @@ -1855,11 +1846,11 @@ AudioDiskstream::use_new_write_source (uint32_t n) /* do not remove destructive files even if they are empty */ chan->write_source->set_allow_remove_if_empty (!destructive()); - + return 0; } -list > +list > AudioDiskstream::steal_write_sources() { /* not possible to steal audio write sources */ @@ -1895,7 +1886,7 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/) (*chan)->write_source->mark_for_remove (); (*chan)->write_source->drop_references (); } - + (*chan)->write_source.reset (); } @@ -1925,23 +1916,6 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/) } } -int -AudioDiskstream::rename_write_sources () -{ - ChannelList::iterator chan; - boost::shared_ptr c = channels.reader(); - uint32_t n; - - for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) { - if ((*chan)->write_source != 0) { - (*chan)->write_source->set_source_name (_name.val(), destructive()); - /* XXX what to do if one of them fails ? */ - } - } - - return 0; -} - void AudioDiskstream::set_block_size (pframes_t /*nframes*/) { @@ -1974,11 +1948,13 @@ AudioDiskstream::allocate_temporary_buffers () boost::shared_ptr c = channels.reader(); for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->playback_wrap_buffer) + if ((*chan)->playback_wrap_buffer) { delete [] (*chan)->playback_wrap_buffer; + } (*chan)->playback_wrap_buffer = new Sample[required_wrap_size]; - if ((*chan)->capture_wrap_buffer) + if ((*chan)->capture_wrap_buffer) { delete [] (*chan)->capture_wrap_buffer; + } (*chan)->capture_wrap_buffer = new Sample[required_wrap_size]; } @@ -1987,15 +1963,12 @@ AudioDiskstream::allocate_temporary_buffers () } void -AudioDiskstream::monitor_input (bool yn) +AudioDiskstream::request_jack_monitors_input (bool yn) { boost::shared_ptr c = channels.reader(); for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - - if ((*chan)->source) { - (*chan)->source->ensure_monitor_input (yn); - } + (*chan)->source.request_jack_monitors_input (yn); } } @@ -2016,17 +1989,12 @@ AudioDiskstream::set_align_style_from_io () boost::shared_ptr c = channels.reader(); - cerr << "Checking " << c->size() << " for physical connections\n"; - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - cerr << "Channel connected via " << (*chan)->source << endl; - if ((*chan)->source && (*chan)->source->flags() & JackPortIsPhysical) { - cerr << "\tchannel has physical connection to " << (*chan)->source->name() << endl; + if ((*chan)->source.is_physical ()) { have_physical = true; break; } } - cerr << "\tphysical? " << have_physical << endl; if (have_physical) { set_align_style (ExistingMaterial); @@ -2040,7 +2008,7 @@ AudioDiskstream::add_channel_to (boost::shared_ptr c, uint32_t how_ { while (how_many--) { c->push_back (new ChannelInfo( - _session.butler()->audio_diskstream_playback_buffer_size(), + _session.butler()->audio_diskstream_playback_buffer_size(), _session.butler()->audio_diskstream_capture_buffer_size(), speed_buffer_size, wrap_buffer_size)); interpolation.add_channel_to ( @@ -2106,7 +2074,7 @@ AudioDiskstream::capture_buffer_load () const if (c->empty ()) { return 0; } - + return (float) ((double) c->front()->capture_buf->write_space()/ (double) c->front()->capture_buf->bufsize()); } @@ -2181,9 +2149,9 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node) boost::shared_ptr region; try { - + PropertyList plist; - + plist.add (Properties::start, 0); plist.add (Properties::length, first_fs->length (first_fs->timeline_position())); plist.add (Properties::name, region_name_from_path (first_fs->name(), true)); @@ -2292,7 +2260,7 @@ AudioDiskstream::can_become_destructive (bool& requires_bounce) const return true; } -void +void AudioDiskstream::adjust_playback_buffering () { boost::shared_ptr c = channels.reader(); @@ -2302,7 +2270,7 @@ AudioDiskstream::adjust_playback_buffering () } } -void +void AudioDiskstream::adjust_capture_buffering () { boost::shared_ptr c = channels.reader(); @@ -2312,10 +2280,28 @@ AudioDiskstream::adjust_capture_buffering () } } +bool +AudioDiskstream::ChannelSource::is_physical () const +{ + if (name.empty()) { + return false; + } + + return AudioEngine::instance()->port_is_physical (name); +} + +void +AudioDiskstream::ChannelSource::request_jack_monitors_input (bool yn) const +{ + if (name.empty()) { + return; + } + + return AudioEngine::instance()->request_jack_monitors_input (name, yn); +} + AudioDiskstream::ChannelInfo::ChannelInfo (framecnt_t playback_bufsize, framecnt_t capture_bufsize, framecnt_t speed_size, framecnt_t wrap_size) { - peak_power = 0.0f; - source = 0; current_capture_buffer = 0; current_playback_buffer = 0; curr_capture_cnt = 0; @@ -2379,3 +2365,21 @@ AudioDiskstream::ChannelInfo::~ChannelInfo () capture_transition_buf = 0; } + +bool +AudioDiskstream::set_name (string const & name) +{ + Diskstream::set_name (name); + + /* get a new write source so that its name reflects the new diskstream name */ + + boost::shared_ptr c = channels.reader(); + ChannelList::iterator i; + int n = 0; + + for (n = 0, i = c->begin(); i != c->end(); ++i, ++n) { + use_new_write_source (n); + } + + return true; +}