X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fdisk_reader.cc;h=4896a95af2af8943a2d271e8507035f5583d0fb7;hb=baa00942a20856cf332f547086ed5ebd2ff9078e;hp=624a9ac17d7fb0cff581c60427cd51bb3f58548e;hpb=8139becb1898187729b0ea57f145302d4975bf3a;p=ardour.git diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc index 624a9ac17d..4896a95af2 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,7 +56,6 @@ DiskReader::DiskReader (Session& s, string const & str, DiskIOProcessor::Flag f) , overwrite_offset (0) , _pending_overwrite (false) , overwrite_queued (false) - , _gui_feed_buffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)) { file_sample[DataType::AUDIO] = 0; file_sample[DataType::MIDI] = 0; @@ -127,9 +128,9 @@ DiskReader::set_name (string const & str) } XMLNode& -DiskReader::state (bool full) +DiskReader::state () { - XMLNode& node (DiskIOProcessor::state (full)); + XMLNode& node (DiskIOProcessor::state ()); node.set_property(X_("type"), X_("diskreader")); return node; } @@ -147,7 +148,6 @@ DiskReader::set_state (const XMLNode& node, int version) void DiskReader::realtime_handle_transport_stopped () { - realtime_speed_change (); } void @@ -253,24 +253,24 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp } } - if (speed == 0.0) { - /* stopped. Don't accidentally pass any data from disk - * into our outputs (e.g. via interpolation) - * nor jump ahead playback_sample when not rolling - */ - if (ms == MonitoringDisk) { - /* when monitoring disk, clear input data so far, - * everything before the disk processor is not relevant. - */ - bufs.silence (nframes, 0); - } + if ((speed == 0.0) && (ms == MonitoringDisk)) { + /* no channels, or stopped. Don't accidentally pass any data + * from disk into our outputs (e.g. via interpolation) + */ return; } + BufferSet& scratch_bufs (_session.get_scratch_buffers (bufs.count())); + const bool still_locating = _session.global_locate_pending(); + + if (c->empty()) { + /* do nothing with audio */ + goto midi; + } + if (speed != 1.0f && speed != -1.0f) { interpolation.set_speed (speed); - midi_interpolation.set_speed (speed); - disk_samples_to_consume = midi_interpolation.distance (nframes); + disk_samples_to_consume = interpolation.distance (nframes); if (speed < 0.0) { disk_samples_to_consume = -disk_samples_to_consume; } @@ -278,8 +278,6 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp disk_samples_to_consume = nframes; } - BufferSet& scratch_bufs (_session.get_scratch_buffers (bufs.count())); - const bool still_locating = _session.global_locate_pending(); if (!result_required || ((ms & MonitoringDisk) == 0) || still_locating || _no_disk_output) { @@ -325,12 +323,19 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp disk_signal = output.data (); } - if (start_sample < playback_sample) { - cerr << owner()->name() << " SS = " << start_sample << " PS = " << playback_sample << endl; - abort (); + if (speed > 0) { + if (start_sample < playback_sample) { + cerr << owner()->name() << " SS = " << start_sample << " PS = " << playback_sample << endl; + abort (); + } + } else if (speed < 0) { + if (playback_sample < start_sample) { + cerr << owner()->name() << " SS = " << start_sample << " PS = " << playback_sample << " REVERSE" << endl; + abort (); + } } - if (start_sample != playback_sample) { + if ((speed > 0) && (start_sample != playback_sample)) { cerr << owner()->name() << " playback not aligned, jump ahead " << (start_sample - playback_sample) << endl; if (can_internal_playback_seek (start_sample - playback_sample)) { @@ -346,10 +351,9 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp if (disk_samples_to_consume <= (samplecnt_t) chaninfo->rw_vector.len[0]) { if (fabsf (speed) != 1.0f) { - (void) interpolation.interpolate ( - n, disk_samples_to_consume, - chaninfo->rw_vector.buf[0], - disk_signal); + 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) { memcpy (disk_signal, chaninfo->rw_vector.buf[0], sizeof (Sample) * disk_samples_to_consume); } @@ -360,18 +364,18 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp if (disk_samples_to_consume <= total) { - /* We have enough samples, but not in one lump. - */ - if (fabsf (speed) != 1.0f) { - interpolation.interpolate (n, chaninfo->rw_vector.len[0], - chaninfo->rw_vector.buf[0], - disk_signal); - disk_signal += chaninfo->rw_vector.len[0]; - interpolation.interpolate (n, disk_samples_to_consume - chaninfo->rw_vector.len[0], - chaninfo->rw_vector.buf[1], - disk_signal); + samplecnt_t ocnt = nframes; + 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; + interpolation.interpolate (n, chaninfo->rw_vector.len[1], chaninfo->rw_vector.buf[1], ocnt, disk_signal); + } + } else if (speed != 0.0) { + memcpy (disk_signal, chaninfo->rw_vector.buf[0], chaninfo->rw_vector.len[0] * sizeof (Sample)); @@ -398,8 +402,6 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp chaninfo->buf->increment_read_ptr (disk_samples_to_consume); - monitor_mix: - if (ms & MonitoringInput) { /* mix the disk signal into the input signal (already in bufs) */ mix_buffers_no_gain (output.data(), disk_signal, disk_samples_to_consume); @@ -420,7 +422,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp } if ((ms & MonitoringDisk) && !still_locating) { - get_midi_playback (*dst, disk_samples_to_consume, ms, scratch_bufs, speed, disk_samples_to_consume); + get_midi_playback (*dst, start_sample, end_sample, ms, scratch_bufs, speed, disk_samples_to_consume); } } @@ -543,8 +545,8 @@ DiskReader::overwrite_existing_buffers () /* assume all are the same size */ samplecnt_t size = c->front()->buf->bufsize(); - std::auto_ptr mixdown_buffer (new Sample[size]); - std::auto_ptr gain_buffer (new float[size]); + boost::scoped_ptr mixdown_buffer (new Sample[size]); + boost::scoped_ptr 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) @@ -754,7 +756,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; @@ -834,8 +836,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_ptr mix_buf (new Sample[2*1048576]); + boost::scoped_ptr gain_buf (new float[2*1048576]); int ret = refill_audio (mix_buf.get(), gain_buf.get(), (partial_fill ? _chunk_samples : 0)); @@ -1209,16 +1211,6 @@ DiskReader::move_processor_automation (boost::weak_ptr p, list< Evora } } -boost::shared_ptr -DiskReader::get_gui_feed_buffer () const -{ - boost::shared_ptr b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI))); - - Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex); - b->copy (_gui_feed_buffer); - return b; -} - void DiskReader::reset_tracker () { @@ -1247,25 +1239,26 @@ DiskReader::resolve_tracker (Evoral::EventSink& buffer, samplepos_t * so that an event at playback_sample has time = 0 */ void -DiskReader::get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorState ms, BufferSet& scratch_bufs, double speed, samplecnt_t disk_samples_to_consume) +DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, samplepos_t end_sample, MonitorState ms, BufferSet& scratch_bufs, double speed, samplecnt_t disk_samples_to_consume) { MidiBuffer* target; + samplepos_t nframes = end_sample - start_sample; if ((ms & MonitoringInput) == 0) { - dst.clear(); + /* Route::process_output_buffers() clears the buffer as-needed */ target = &dst; } else { target = &scratch_bufs.get_midi (0); } if (ms & MonitoringDisk) { - /* no disk data needed */ + /* 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, - _midi_buf->get_read_ptr(), _midi_buf->get_write_ptr(), playback_sample, playback_sample + nframes, + _midi_buf->get_read_ptr(), _midi_buf->get_write_ptr(), start_sample, end_sample, (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes, Port::port_offset())); //cerr << "======== PRE ========\n"; @@ -1278,7 +1271,7 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorStat samplepos_t effective_start; Evoral::Range loop_range (loc->start(), loc->end() - 1); - effective_start = loop_range.squish (playback_sample); + effective_start = loop_range.squish (start_sample); DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start)); @@ -1325,12 +1318,12 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorStat events_read = _midi_buf->read (*target, effective_start, effective_start + nframes); } } else { - const size_t n_skipped = _midi_buf->skip_to (playback_sample); + const size_t n_skipped = _midi_buf->skip_to (start_sample); if (n_skipped > 0) { warning << string_compose(_("MidiDiskstream %1: skipped %2 events, possible underflow"), id(), n_skipped) << endmsg; } - DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("playback buffer read, from %1 to %2 (%3)", playback_sample, playback_sample + nframes, nframes)); - events_read = _midi_buf->read (*target, playback_sample, playback_sample + nframes); + DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("playback buffer read, from %1 to %2 (%3)", start_sample, end_sample, nframes)); + events_read = _midi_buf->read (*target, start_sample, end_sample, Port::port_offset ()); } DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ( @@ -1343,10 +1336,12 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorStat g_atomic_int_add (&_samples_read_from_ringbuffer, nframes); /* vari-speed */ - if (speed != 0.0 && fabsf (speed) != 1.0f) { for (MidiBuffer::iterator i = target->begin(); i != target->end(); ++i) { MidiBuffer::TimeType *tme = i.timeptr(); + // XXX need to subtract port offsets before scaling + // also we must only scale events read from disk + // and not existing input data in the buffer. *tme = (*tme) * nframes / disk_samples_to_consume; } } @@ -1355,9 +1350,25 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorStat dst.merge_from (*target, nframes); } - //cerr << "======== POST ========\n"; - //_midi_buf->dump (cerr); - //cerr << "----------------\n"; +#if 0 + if (!target->empty ()) { + cerr << "======== MIDI OUT ========\n"; + for (MidiBuffer::iterator i = target->begin(); i != target->end(); ++i) { + const Evoral::Event ev (*i, false); + cerr << "MIDI EVENT (from disk) @ " << ev.time(); + for (size_t xx = 0; xx < ev.size(); ++xx) { + cerr << ' ' << hex << (int) ev.buffer()[xx]; + } + cerr << dec << endl; + } + cerr << "----------------\n"; + } +#endif +#if 0 + cerr << "======== MIDI Disk Buffer ========\n"; + _midi_buf->dump (cerr); + cerr << "----------------\n"; +#endif } /** @a start is set to the new sample position (TIME) read up to */ @@ -1368,7 +1379,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);