X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Faudio_diskstream.cc;h=24687c766f242fff2e1d8181107c9923ab539f1a;hb=27d77b8719c15254369391e57227d20c4cfcbb20;hp=3345a00b423deedbb7217a9047c350c03db53f11;hpb=3cd8138a419cb165f56070ace0b21a1e63ec5a43;p=ardour.git diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 3345a00b42..24687c766f 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -408,7 +408,7 @@ AudioDiskstream::prepare_record_status(framepos_t capture_start_frame) * that someone can read playback_distance worth of data from. */ int -AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance) +AudioDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance, bool need_disk_signal) { uint32_t n; boost::shared_ptr c = channels.reader(); @@ -494,9 +494,9 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecn assert(ap); assert(rec_nframes <= (framecnt_t) ap->get_audio_buffer(nframes).capacity()); - Sample *buf = ap->get_audio_buffer (nframes).data (rec_offset); + Sample *buf = bufs.get_audio (n).data(rec_offset); memcpy (chaninfo->current_capture_buffer, buf, sizeof (Sample) * rec_nframes); - + } else { framecnt_t total = chaninfo->capture_vector.len[0] + chaninfo->capture_vector.len[1]; @@ -509,7 +509,7 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecn boost::shared_ptr const ap = _io->audio (n); assert(ap); - Sample* buf = ap->get_audio_buffer(nframes).data (rec_offset); + Sample *buf = bufs.get_audio (n).data(rec_offset); framecnt_t first = chaninfo->capture_vector.len[0]; memcpy (chaninfo->capture_wrap_buffer, buf, sizeof (Sample) * first); @@ -578,7 +578,7 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecn /* no varispeed playback if we're recording, because the output .... TBD */ if (rec_nframes == 0 && _actual_speed != 1.0f) { - necessary_samples = (framecnt_t) floor ((nframes * fabs (_actual_speed))) + 1; + necessary_samples = (framecnt_t) ceil ((nframes * fabs (_actual_speed))) + 2; } else { necessary_samples = nframes; } @@ -618,6 +618,8 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecn as our current_playback_buffer. */ + assert(wrap_buffer_size >= necessary_samples); + /* Copy buf[0] from playback_buf */ memcpy ((char *) chaninfo->playback_wrap_buffer, chaninfo->playback_vector.buf[0], @@ -655,6 +657,46 @@ AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecn _speed = _target_speed; } + if (need_disk_signal) { + + /* copy data over to buffer set */ + + size_t n_buffers = bufs.count().n_audio(); + size_t n_chans = c->size(); + gain_t scaling = 1.0f; + + if (n_chans > n_buffers) { + scaling = ((float) n_buffers)/n_chans; + } + + for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) { + + AudioBuffer& buf (bufs.get_audio (n%n_buffers)); + ChannelInfo* chaninfo (*chan); + + if (n < n_chans) { + if (scaling != 1.0f) { + buf.read_from_with_gain (chaninfo->current_playback_buffer, nframes, scaling); + } else { + buf.read_from (chaninfo->current_playback_buffer, nframes); + } + } else { + if (scaling != 1.0f) { + buf.accumulate_with_gain_from (chaninfo->current_playback_buffer, nframes, scaling); + } else { + buf.accumulate_from (chaninfo->current_playback_buffer, nframes); + } + } + } + + /* leave the MIDI count alone */ + ChanCount cnt (DataType::AUDIO, n_chans); + cnt.set (DataType::MIDI, bufs.count().n_midi()); + bufs.set_count (cnt); + + /* extra buffers will already be silent, so leave them alone */ + } + return 0; } @@ -1661,16 +1703,27 @@ AudioDiskstream::set_record_enabled (bool yn) } else { disengage_record_enable (); } + + RecordEnableChanged (); /* EMIT SIGNAL */ } } -void -AudioDiskstream::engage_record_enable () +bool +AudioDiskstream::prep_record_enable () { + if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_audio() == 0) { + return false; + } + + /* can't rec-enable in destructive mode if transport is before start */ + + if (destructive() && _session.transport_frame() < _session.current_start_frame()) { + return false; + } + bool rolling = _session.transport_speed() != 0.0f; boost::shared_ptr c = channels.reader(); - g_atomic_int_set (&_record_enabled, 1); capturing_sources.clear (); if (Config->get_monitoring_model() == HardwareMonitoring) { @@ -1688,13 +1741,12 @@ AudioDiskstream::engage_record_enable () } } - RecordEnableChanged (); /* EMIT SIGNAL */ + return true; } -void -AudioDiskstream::disengage_record_enable () +bool +AudioDiskstream::prep_record_disable () { - g_atomic_int_set (&_record_enabled, 0); boost::shared_ptr c = channels.reader(); if (Config->get_monitoring_model() == HardwareMonitoring) { for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { @@ -1702,7 +1754,8 @@ AudioDiskstream::disengage_record_enable () } } capturing_sources.clear (); - RecordEnableChanged (); /* EMIT SIGNAL */ + + return true; } XMLNode& @@ -1941,7 +1994,7 @@ AudioDiskstream::allocate_temporary_buffers () */ double const sp = max (fabsf (_actual_speed), 1.2f); - framecnt_t required_wrap_size = (framecnt_t) floor (_session.get_block_size() * sp) + 1; + framecnt_t required_wrap_size = (framecnt_t) ceil (_session.get_block_size() * sp) + 2; if (required_wrap_size > wrap_buffer_size) {