X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fdisk_reader.cc;h=375dda70759f0f4345e193223d07eb67b0c04fb5;hb=79f01bc889d6c928345214eaba9016c6396bcfca;hp=dd6c3ee09d1bf78e509cd968355c8b234c5a32eb;hpb=33af0b0d3daabbbefdc8c09bf8f19b821b2fc137;p=ardour.git diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc index dd6c3ee09d..375dda7075 100644 --- a/libs/ardour/disk_reader.cc +++ b/libs/ardour/disk_reader.cc @@ -17,6 +17,8 @@ */ +#include + #include "pbd/enumwriter.h" #include "pbd/memento_command.h" @@ -54,6 +56,7 @@ DiskReader::DiskReader (Session& s, string const & str, DiskIOProcessor::Flag f) , overwrite_offset (0) , _pending_overwrite (false) , overwrite_queued (false) + , _declick_gain (0) { file_sample[DataType::AUDIO] = 0; file_sample[DataType::MIDI] = 0; @@ -68,21 +71,30 @@ DiskReader::~DiskReader () _playlists[n]->release (); } } + delete _midi_buf; +} - { - RCUWriter writer (channels); - boost::shared_ptr c = writer.get_copy(); - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - delete *chan; - } +void +DiskReader::ReaderChannelInfo::resize (samplecnt_t bufsize) +{ + delete rbuf; + /* touch memory to lock it */ + rbuf = new RingBufferNPT (bufsize); + memset (rbuf->buffer(), 0, sizeof (Sample) * rbuf->bufsize()); +} - c->clear(); +int +DiskReader::add_channel_to (boost::shared_ptr c, uint32_t how_many) +{ + while (how_many--) { + c->push_back (new ReaderChannelInfo (_session.butler()->audio_diskstream_playback_buffer_size())); + DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: new reader channel, write space = %2 read = %3\n", + name(), + c->back()->rbuf->write_space(), + c->back()->rbuf->read_space())); } - channels.flush (); - - delete _midi_buf; + return 0; } void @@ -173,7 +185,7 @@ DiskReader::buffer_load () const return 1.0; } - PBD::RingBufferNPT * b = c->front()->buf; + PBD::RingBufferNPT* b = c->front()->rbuf; return (float) ((double) b->read_space() / (double) b->bufsize()); } @@ -266,24 +278,23 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp goto midi; } - if (speed != 1.0f && speed != -1.0f) { - interpolation.set_speed (speed); - disk_samples_to_consume = interpolation.distance (nframes); - if (speed < 0.0) { - disk_samples_to_consume = -disk_samples_to_consume; - } - } else { + assert (speed == -1 || speed == 0 || speed == 1); + + if (speed < 0) { + disk_samples_to_consume = -nframes; + } else if (speed > 0) { disk_samples_to_consume = nframes; + } else { + disk_samples_to_consume = 0; } - if (!result_required || ((ms & MonitoringDisk) == 0) || still_locating || _no_disk_output) { /* no need for actual disk data, just advance read pointer and return */ if (!still_locating || _no_disk_output) { for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->buf->increment_read_ptr (disk_samples_to_consume); + (*chan)->rbuf->increment_read_ptr (disk_samples_to_consume); } } @@ -344,15 +355,11 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp } } - chaninfo->buf->get_read_vector (&(*chan)->rw_vector); + chaninfo->rbuf->get_read_vector (&(*chan)->rw_vector); if (disk_samples_to_consume <= (samplecnt_t) chaninfo->rw_vector.len[0]) { - if (fabsf (speed) != 1.0f) { - samplecnt_t ocnt = nframes; - samplecnt_t icnt = chaninfo->rw_vector.len[0]; - (void) interpolation.interpolate (n, icnt, chaninfo->rw_vector.buf[0], ocnt, disk_signal); - } else if (speed != 0.0) { + if (speed != 0.0) { memcpy (disk_signal, chaninfo->rw_vector.buf[0], sizeof (Sample) * disk_samples_to_consume); } @@ -362,22 +369,11 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp if (disk_samples_to_consume <= total) { - if (fabsf (speed) != 1.0f) { - samplecnt_t ocnt = nframes; - samplecnt_t icnt = interpolation.interpolate (n, chaninfo->rw_vector.len[0], chaninfo->rw_vector.buf[0], ocnt, disk_signal); - - if (ocnt < nframes) { - disk_signal += ocnt; - ocnt = nframes - ocnt; - icnt = interpolation.interpolate (n, chaninfo->rw_vector.len[1], chaninfo->rw_vector.buf[1], ocnt, disk_signal); - } - - } else if (speed != 0.0) { - - memcpy (disk_signal, + if (speed != 0.0) { + memcpy (disk_signal, chaninfo->rw_vector.buf[0], chaninfo->rw_vector.len[0] * sizeof (Sample)); - memcpy (disk_signal + chaninfo->rw_vector.len[0], + memcpy (disk_signal + chaninfo->rw_vector.len[0], chaninfo->rw_vector.buf[1], (disk_samples_to_consume - chaninfo->rw_vector.len[0]) * sizeof (Sample)); } @@ -398,9 +394,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp apply_gain_to_buffer (disk_signal, disk_samples_to_consume, scaling); } - chaninfo->buf->increment_read_ptr (disk_samples_to_consume); - - monitor_mix: + chaninfo->rbuf->increment_read_ptr (disk_samples_to_consume); if (ms & MonitoringInput) { /* mix the disk signal into the input signal (already in bufs) */ @@ -412,7 +406,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp /* MIDI data handling */ midi: - if (!_session.declick_out_pending() && bufs.count().n_midi()) { + if (/*!_session.declick_out_pending() && */ bufs.count().n_midi()) { MidiBuffer* dst; if (_no_disk_output) { @@ -439,14 +433,13 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp if (_playlists[DataType::AUDIO]) { if (!c->empty()) { if (_slaved) { - if (c->front()->buf->write_space() >= c->front()->buf->bufsize() / 2) { - DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: slaved, write space = %2 of %3\n", name(), c->front()->buf->write_space(), - c->front()->buf->bufsize())); + if (c->front()->rbuf->write_space() >= c->front()->rbuf->bufsize() / 2) { + DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: slaved, write space = %2 of %3\n", name(), c->front()->rbuf->write_space(), c->front()->rbuf->bufsize())); butler_required = true; } } else { - if ((samplecnt_t) c->front()->buf->write_space() >= _chunk_samples) { - DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: write space = %2 of %3\n", name(), c->front()->buf->write_space(), + if ((samplecnt_t) c->front()->rbuf->write_space() >= _chunk_samples) { + DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: write space = %2 of %3\n", name(), c->front()->rbuf->write_space(), _chunk_samples)); butler_required = true; } @@ -521,7 +514,7 @@ DiskReader::set_pending_overwrite (bool yn) boost::shared_ptr c = channels.reader (); if (!c->empty ()) { - overwrite_offset = c->front()->buf->get_read_ptr(); + overwrite_offset = c->front()->rbuf->get_read_ptr(); } } @@ -543,10 +536,10 @@ DiskReader::overwrite_existing_buffers () const bool reversed = _session.transport_speed() < 0.0f; /* assume all are the same size */ - samplecnt_t size = c->front()->buf->bufsize(); + samplecnt_t size = c->front()->rbuf->bufsize(); - std::auto_ptr mixdown_buffer (new Sample[size]); - std::auto_ptr gain_buffer (new float[size]); + boost::scoped_array mixdown_buffer (new Sample[size]); + boost::scoped_array gain_buffer (new float[size]); /* reduce size so that we can fill the buffer correctly (ringbuffers can only handle size-1, otherwise they appear to be empty) @@ -574,7 +567,7 @@ DiskReader::overwrite_existing_buffers () samplecnt_t to_read = size - overwrite_offset; - if (audio_read ((*chan)->buf->buffer() + overwrite_offset, mixdown_buffer.get(), gain_buffer.get(), start, to_read, n, reversed)) { + if (audio_read ((*chan)->rbuf->buffer() + overwrite_offset, mixdown_buffer.get(), gain_buffer.get(), start, to_read, n, reversed)) { error << string_compose(_("DiskReader %1: when refilling, cannot read %2 from playlist at sample %3"), id(), size, playback_sample) << endmsg; goto midi; @@ -584,7 +577,7 @@ DiskReader::overwrite_existing_buffers () cnt -= to_read; - if (audio_read ((*chan)->buf->buffer(), mixdown_buffer.get(), gain_buffer.get(), start, cnt, n, reversed)) { + if (audio_read ((*chan)->rbuf->buffer(), mixdown_buffer.get(), gain_buffer.get(), start, cnt, n, reversed)) { error << string_compose(_("DiskReader %1: when refilling, cannot read %2 from playlist at sample %3"), id(), size, playback_sample) << endmsg; goto midi; @@ -636,7 +629,7 @@ DiskReader::seek (samplepos_t sample, bool complete_refill) //sample = std::max ((samplecnt_t)0, sample -_session.worst_output_latency ()); for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) { - (*chan)->buf->reset (); + (*chan)->rbuf->reset (); } if (g_atomic_int_get (&_samples_read_from_ringbuffer) == 0) { @@ -680,7 +673,7 @@ DiskReader::can_internal_playback_seek (samplecnt_t distance) boost::shared_ptr c = channels.reader(); for (chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->buf->read_space() < (size_t) distance) { + if ((*chan)->rbuf->read_space() < (size_t) distance) { return false; } } @@ -700,7 +693,7 @@ DiskReader::internal_playback_seek (samplecnt_t distance) boost::shared_ptr c = channels.reader(); for (chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->buf->increment_read_ptr (::llabs(distance)); + (*chan)->rbuf->increment_read_ptr (::llabs(distance)); } playback_sample += distance; @@ -756,7 +749,7 @@ DiskReader::audio_read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, just once. */ - if ((loc = loop_location) != 0) { + if ((loc = _loop_location) != 0) { loop_start = loc->start(); loop_end = loc->end(); loop_length = loop_end - loop_start; @@ -836,8 +829,8 @@ DiskReader::_do_refill_with_alloc (bool partial_fill) */ { - std::auto_ptr mix_buf (new Sample[2*1048576]); - std::auto_ptr gain_buf (new float[2*1048576]); + boost::scoped_array mix_buf (new Sample[2*1048576]); + boost::scoped_array gain_buf (new float[2*1048576]); int ret = refill_audio (mix_buf.get(), gain_buf.get(), (partial_fill ? _chunk_samples : 0)); @@ -905,7 +898,7 @@ DiskReader::refill_audio (Sample* mixdown_buffer, float* gain_buffer, samplecnt_ vector.buf[1] = 0; vector.len[1] = 0; - c->front()->buf->get_write_vector (&vector); + c->front()->rbuf->get_write_vector (&vector); if ((total_space = vector.len[0] + vector.len[1]) == 0) { DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: no space to refill\n", name())); @@ -943,7 +936,7 @@ DiskReader::refill_audio (Sample* mixdown_buffer, float* gain_buffer, samplecnt_ work with. */ - if (_slaved && total_space < (samplecnt_t) (c->front()->buf->bufsize() / 2)) { + if (_slaved && total_space < (samplecnt_t) (c->front()->rbuf->bufsize() / 2)) { DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: not enough to refill while slaved\n", this)); return 0; } @@ -959,12 +952,12 @@ DiskReader::refill_audio (Sample* mixdown_buffer, float* gain_buffer, samplecnt_ for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { ChannelInfo* chan (*i); - chan->buf->get_write_vector (&vector); + chan->rbuf->get_write_vector (&vector); memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]); if (vector.len[1]) { memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]); } - chan->buf->increment_write_ptr (vector.len[0] + vector.len[1]); + chan->rbuf->increment_write_ptr (vector.len[0] + vector.len[1]); } return 0; } @@ -992,12 +985,12 @@ DiskReader::refill_audio (Sample* mixdown_buffer, float* gain_buffer, samplecnt_ for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { ChannelInfo* chan (*i); - chan->buf->get_write_vector (&vector); + chan->rbuf->get_write_vector (&vector); memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]); if (vector.len[1]) { memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]); } - chan->buf->increment_write_ptr (vector.len[0] + vector.len[1]); + chan->rbuf->increment_write_ptr (vector.len[0] + vector.len[1]); } return 0; } @@ -1045,7 +1038,7 @@ DiskReader::refill_audio (Sample* mixdown_buffer, float* gain_buffer, samplecnt_ Sample* buf2; samplecnt_t len1, len2; - chan->buf->get_write_vector (&vector); + chan->rbuf->get_write_vector (&vector); if ((samplecnt_t) vector.len[0] > samples_to_read) { @@ -1089,7 +1082,7 @@ DiskReader::refill_audio (Sample* mixdown_buffer, float* gain_buffer, samplecnt_ ret = -1; goto out; } - chan->buf->increment_write_ptr (to_read); + chan->rbuf->increment_write_ptr (to_read); ts -= to_read; } @@ -1107,7 +1100,7 @@ DiskReader::refill_audio (Sample* mixdown_buffer, float* gain_buffer, samplecnt_ goto out; } - chan->buf->increment_write_ptr (to_read); + chan->rbuf->increment_write_ptr (to_read); } if (zero_fill) { @@ -1124,7 +1117,7 @@ DiskReader::refill_audio (Sample* mixdown_buffer, float* gain_buffer, samplecnt_ ret = ((total_space - samples_to_read) > _chunk_samples); - c->front()->buf->get_write_vector (&vector); + c->front()->rbuf->get_write_vector (&vector); out: return ret; @@ -1254,7 +1247,7 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, sample if (ms & MonitoringDisk) { /* disk data needed */ - Location* loc = loop_location; + Location* loc = _loop_location; DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ( "%1 MDS pre-read read %8 offset = %9 @ %4..%5 from %2 write to %3, LOOPED ? %6 .. %7\n", _name, @@ -1379,7 +1372,7 @@ DiskReader::midi_read (samplepos_t& start, samplecnt_t dur, bool reversed) samplepos_t loop_end = 0; samplepos_t loop_start = 0; samplecnt_t loop_length = 0; - Location* loc = loop_location; + Location* loc = _loop_location; samplepos_t effective_start = start; Evoral::Range* loop_range (0);