From bb0fedabba303c2de78c346af0bd77cfecdf38be Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Mon, 9 May 2022 14:55:51 -0700 Subject: [PATCH] simplified and optimized samplebuffer --- app/audio/audiovisualwaveform.cpp | 20 +++--- app/audio/audiovisualwaveform.h | 6 +- app/codec/decoder.cpp | 12 ++-- app/codec/decoder.h | 4 +- app/codec/encoder.h | 2 +- app/codec/ffmpeg/ffmpegdecoder.cpp | 4 +- app/codec/ffmpeg/ffmpegencoder.cpp | 18 +++--- app/codec/ffmpeg/ffmpegencoder.h | 2 +- app/codec/oiio/oiioencoder.cpp | 2 +- app/codec/oiio/oiioencoder.h | 2 +- app/codec/samplebuffer.cpp | 61 +++++++++---------- app/codec/samplebuffer.h | 24 +++----- app/core.cpp | 2 +- app/node/audio/pan/pan.cpp | 33 +++++----- app/node/audio/pan/pan.h | 2 +- app/node/audio/volume/volume.cpp | 2 +- app/node/audio/volume/volume.h | 2 +- .../crossdissolve/crossdissolvetransition.cpp | 22 +++---- .../crossdissolve/crossdissolvetransition.h | 2 +- app/node/block/transition/transition.cpp | 29 ++------- app/node/block/transition/transition.h | 4 +- app/node/hashtraverser.cpp | 14 +---- app/node/hashtraverser.h | 4 +- app/node/math/math/math.cpp | 2 +- app/node/math/math/math.h | 2 +- app/node/math/math/mathbase.cpp | 43 ++++++------- app/node/math/math/mathbase.h | 2 +- app/node/node.cpp | 2 +- app/node/node.h | 2 +- app/node/traverser.cpp | 4 +- app/node/traverser.h | 12 ++-- app/node/value.h | 2 +- app/render/audioplaybackcache.cpp | 8 +-- app/render/audioplaybackcache.h | 2 +- app/render/job/samplejob.h | 7 +-- app/render/previewautocacher.cpp | 2 +- app/render/renderprocessor.cpp | 52 ++++++++-------- app/render/renderprocessor.h | 8 +-- app/task/export/export.cpp | 6 +- app/task/export/export.h | 6 +- app/task/precache/precachetask.cpp | 2 +- app/task/precache/precachetask.h | 2 +- app/task/render/render.cpp | 2 +- app/task/render/render.h | 2 +- app/widget/audiomonitor/audiomonitor.cpp | 4 +- app/widget/audiomonitor/audiomonitor.h | 4 +- app/widget/viewer/viewer.cpp | 15 ++--- 47 files changed, 214 insertions(+), 252 deletions(-) diff --git a/app/audio/audiovisualwaveform.cpp b/app/audio/audiovisualwaveform.cpp index dbc0cb973..7719d7090 100644 --- a/app/audio/audiovisualwaveform.cpp +++ b/app/audio/audiovisualwaveform.cpp @@ -40,10 +40,10 @@ AudioVisualWaveform::AudioVisualWaveform() : } } -void AudioVisualWaveform::OverwriteSamplesFromBuffer(SampleBufferPtr samples, int sample_rate, const rational &start, double target_rate, Sample& data, int &start_index, int &samples_length) +void AudioVisualWaveform::OverwriteSamplesFromBuffer(const SampleBuffer &samples, int sample_rate, const rational &start, double target_rate, Sample& data, int &start_index, int &samples_length) { start_index = time_to_samples(start, target_rate); - samples_length = time_to_samples(static_cast(samples->sample_count()) / static_cast(sample_rate), target_rate); + samples_length = time_to_samples(static_cast(samples.sample_count()) / static_cast(sample_rate), target_rate); int end_index = start_index + samples_length; if (data.size() < end_index) { @@ -54,7 +54,7 @@ void AudioVisualWaveform::OverwriteSamplesFromBuffer(SampleBufferPtr samples, in for (int i=0; isample_count()); + int src_end = qMin(qRound((double(i + channels_) * chunk_size)) / channels_, samples.sample_count()); Sample summary = SumSamples(samples, src_start, @@ -91,7 +91,7 @@ void AudioVisualWaveform::OverwriteSamplesFromMipmap(const AudioVisualWaveform:: input_length = samples_length; } -void AudioVisualWaveform::OverwriteSamples(SampleBufferPtr samples, int sample_rate, const rational &start) +void AudioVisualWaveform::OverwriteSamples(const SampleBuffer &samples, int sample_rate, const rational &start) { if (!channels_) { qWarning() << "Failed to write samples - channel count is zero"; @@ -125,7 +125,7 @@ void AudioVisualWaveform::OverwriteSamples(SampleBufferPtr samples, int sample_r current_mipmap->second); } - rational sample_length(samples->sample_count(), sample_rate); + rational sample_length(samples.sample_count(), sample_rate); length_ = qMax(length_, start + sample_length); } @@ -277,7 +277,7 @@ AudioVisualWaveform::Sample AudioVisualWaveform::GetSummaryFromTime(const ration return AudioVisualWaveform::Sample(channel_count(), {0, 0}); } -void ExpandMinMaxChannel(float *a, int start, int length, float &min_val, float &max_val) +void ExpandMinMaxChannel(const float *a, int start, int length, float &min_val, float &max_val) { #if defined(Q_PROCESSOR_X86) || defined(Q_PROCESSOR_ARM) // SSE optimized @@ -321,13 +321,13 @@ void ExpandMinMaxChannel(float *a, int start, int length, float &min_val, float #endif } -AudioVisualWaveform::Sample AudioVisualWaveform::SumSamples(SampleBufferPtr samples, int start_index, int length) +AudioVisualWaveform::Sample AudioVisualWaveform::SumSamples(const SampleBuffer &samples, int start_index, int length) { - int channels = samples->audio_params().channel_count(); + int channels = samples.audio_params().channel_count(); AudioVisualWaveform::Sample summed_samples(channels); - for (int channel=0; channelaudio_params().channel_count(); channel++) { - ExpandMinMaxChannel(samples->data(channel), start_index, length, summed_samples[channel].min, summed_samples[channel].max); + for (int channel=0; channel &filenames, const Audi return false; } -bool Decoder::RetrieveAudioFromConform(SampleBufferPtr sample_buffer, const QVector &conform_filenames, const TimeRange& range, Footage::LoopMode loop_mode, const AudioParams &input_params) +bool Decoder::RetrieveAudioFromConform(SampleBuffer &sample_buffer, const QVector &conform_filenames, const TimeRange& range, Footage::LoopMode loop_mode, const AudioParams &input_params) { PlanarFileDevice input; if (input.open(conform_filenames, QFile::ReadOnly)) { qint64 read_index = input_params.time_to_bytes(range.in()) / input_params.channel_count(); qint64 write_index = 0; - const qint64 buffer_length_in_bytes = sample_buffer->sample_count() * input_params.bytes_per_sample_per_channel(); + const qint64 buffer_length_in_bytes = sample_buffer.sample_count() * input_params.bytes_per_sample_per_channel(); while (write_index < buffer_length_in_bytes) { if (loop_mode == Footage::kLoopModeLoop) { @@ -297,15 +297,15 @@ bool Decoder::RetrieveAudioFromConform(SampleBufferPtr sample_buffer, const QVec if (read_index < 0) { // Reading before 0, write silence here until audio data would actually start write_count = qMin(-read_index, buffer_length_in_bytes); - sample_buffer->silence_bytes(write_index, write_index + write_count); + sample_buffer.silence_bytes(write_index, write_index + write_count); } else if (read_index >= input.size()) { // Reading after data length, write silence until the end of the buffer write_count = buffer_length_in_bytes - write_index; - sample_buffer->silence_bytes(write_index, write_index + write_count); + sample_buffer.silence_bytes(write_index, write_index + write_count); } else { write_count = qMin(input.size() - read_index, buffer_length_in_bytes - write_index); input.seek(read_index); - input.read(reinterpret_cast(sample_buffer->to_raw_ptrs()), write_count, write_index); + input.read(reinterpret_cast(sample_buffer.to_raw_ptrs().data()), write_count, write_index); } read_index += write_count; diff --git a/app/codec/decoder.h b/app/codec/decoder.h index 2234753d9..3191ade23 100644 --- a/app/codec/decoder.h +++ b/app/codec/decoder.h @@ -201,7 +201,7 @@ public: * * This function is thread safe and can only run while the decoder is open. \see Open() */ - RetrieveAudioStatus RetrieveAudio(SampleBufferPtr dest, const TimeRange& range, const AudioParams& params, const QString &cache_path, Footage::LoopMode loop_mode, RenderMode::Mode mode); + RetrieveAudioStatus RetrieveAudio(SampleBuffer &dest, const TimeRange& range, const AudioParams& params, const QString &cache_path, Footage::LoopMode loop_mode, RenderMode::Mode mode); /** * @brief Determine the last time this decoder instance was used in any way @@ -307,7 +307,7 @@ signals: private: void UpdateLastAccessed(); - bool RetrieveAudioFromConform(SampleBufferPtr sample_buffer, const QVector &conform_filenames, const TimeRange &range, Footage::LoopMode loop_mode, const AudioParams ¶ms); + bool RetrieveAudioFromConform(SampleBuffer &sample_buffer, const QVector &conform_filenames, const TimeRange &range, Footage::LoopMode loop_mode, const AudioParams ¶ms); CodecStream stream_; diff --git a/app/codec/encoder.h b/app/codec/encoder.h index 102b0430e..f94473dbb 100644 --- a/app/codec/encoder.h +++ b/app/codec/encoder.h @@ -183,7 +183,7 @@ public slots: virtual bool Open() = 0; virtual bool WriteFrame(olive::FramePtr frame, olive::rational time) = 0; - virtual bool WriteAudio(olive::SampleBufferPtr audio) = 0; + virtual bool WriteAudio(const olive::SampleBuffer &audio) = 0; virtual bool WriteSubtitle(const SubtitleBlock *sub_block) = 0; virtual void Close() = 0; diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 04f889a34..df6c874da 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -515,7 +515,7 @@ bool FFmpegDecoder::ConformAudioInternal(const QVector &filenames, cons // Resample audio to our destination parameters nb_samples = swr_convert(resampler, - reinterpret_cast(data.to_raw_ptrs()), + reinterpret_cast(data.to_raw_ptrs().data()), nb_samples, const_cast(frame->data), frame->nb_samples); @@ -526,7 +526,7 @@ bool FFmpegDecoder::ConformAudioInternal(const QVector &filenames, cons nb_bytes_per_channel = params.samples_to_bytes(nb_samples) / nb_channels; // Write to files - wave_out.write(const_cast(reinterpret_cast(data.to_raw_ptrs())), nb_bytes_per_channel); + wave_out.write(const_cast(reinterpret_cast(data.to_raw_ptrs().data())), nb_bytes_per_channel); } // Free buffer diff --git a/app/codec/ffmpeg/ffmpegencoder.cpp b/app/codec/ffmpeg/ffmpegencoder.cpp index 8a0462e2d..6c42df4da 100644 --- a/app/codec/ffmpeg/ffmpegencoder.cpp +++ b/app/codec/ffmpeg/ffmpegencoder.cpp @@ -266,26 +266,26 @@ fail: return success; } -bool FFmpegEncoder::WriteAudio(SampleBufferPtr audio) +bool FFmpegEncoder::WriteAudio(const SampleBuffer &audio) { bool result = true; // Create input buffer int input_sample_count = 0; uint8_t** input_data = nullptr; - if (audio) { - input_sample_count = audio->sample_count(); + if (audio.is_allocated()) { + input_sample_count = audio.sample_count(); int input_linesize; - av_samples_alloc_array_and_samples(&input_data, &input_linesize, audio->audio_params().channel_count(), - input_sample_count, FFmpegUtils::GetFFmpegSampleFormat(audio->audio_params().format()), 0); + av_samples_alloc_array_and_samples(&input_data, &input_linesize, audio.audio_params().channel_count(), + input_sample_count, FFmpegUtils::GetFFmpegSampleFormat(audio.audio_params().format()), 0); - for (int i=0; iaudio_params().channel_count(); i++) { - memcpy(input_data[i], audio->data(i), input_sample_count * audio->audio_params().bytes_per_sample_per_channel()); + for (int i=0; iaudio_params() : params().audio_params(), const_cast(input_data), input_sample_count); + result = WriteAudioData(audio.audio_params().is_valid() ? audio.audio_params() : params().audio_params(), const_cast(input_data), input_sample_count); if (input_data) { av_freep(&input_data[0]); @@ -774,7 +774,7 @@ void FFmpegEncoder::FlushEncoders() } if (audio_codec_ctx_) { - WriteAudio(nullptr); + WriteAudio(SampleBuffer()); FlushCodecCtx(audio_codec_ctx_, audio_stream_); } diff --git a/app/codec/ffmpeg/ffmpegencoder.h b/app/codec/ffmpeg/ffmpegencoder.h index a38955f3f..465f7c40a 100644 --- a/app/codec/ffmpeg/ffmpegencoder.h +++ b/app/codec/ffmpeg/ffmpegencoder.h @@ -47,7 +47,7 @@ public: virtual bool WriteFrame(olive::FramePtr frame, olive::rational time) override; - virtual bool WriteAudio(olive::SampleBufferPtr audio) override; + virtual bool WriteAudio(const olive::SampleBuffer &audio) override; bool WriteAudioData(const AudioParams &audio_params, const uint8_t **data, int input_sample_count); diff --git a/app/codec/oiio/oiioencoder.cpp b/app/codec/oiio/oiioencoder.cpp index f872a758b..679dbd550 100644 --- a/app/codec/oiio/oiioencoder.cpp +++ b/app/codec/oiio/oiioencoder.cpp @@ -62,7 +62,7 @@ bool OIIOEncoder::WriteFrame(FramePtr frame, rational time) return true; } -bool OIIOEncoder::WriteAudio(SampleBufferPtr audio) +bool OIIOEncoder::WriteAudio(const SampleBuffer &audio) { // Do nothing return false; diff --git a/app/codec/oiio/oiioencoder.h b/app/codec/oiio/oiioencoder.h index 7325cdf49..1099e68ca 100644 --- a/app/codec/oiio/oiioencoder.h +++ b/app/codec/oiio/oiioencoder.h @@ -35,7 +35,7 @@ public slots: virtual bool Open() override; virtual bool WriteFrame(olive::FramePtr frame, olive::rational time) override; - virtual bool WriteAudio(SampleBufferPtr audio) override; + virtual bool WriteAudio(const SampleBuffer &audio) override; virtual bool WriteSubtitle(const SubtitleBlock *sub_block) override; virtual void Close() override; diff --git a/app/codec/samplebuffer.cpp b/app/codec/samplebuffer.cpp index 1dede4ae5..b7d93ec83 100644 --- a/app/codec/samplebuffer.cpp +++ b/app/codec/samplebuffer.cpp @@ -20,6 +20,8 @@ #include "samplebuffer.h" +#include "common/cpuoptimize.h" + namespace olive { SampleBuffer::SampleBuffer() : @@ -27,25 +29,18 @@ SampleBuffer::SampleBuffer() : { } -SampleBufferPtr SampleBuffer::Create() +SampleBuffer::SampleBuffer(const AudioParams &audio_params, const rational &length) : + audio_params_(audio_params) { - return std::make_shared(); + sample_count_per_channel_ = audio_params_.time_to_samples(length); + allocate(); } -SampleBufferPtr SampleBuffer::CreateAllocated(const AudioParams &audio_params, const rational &length) +SampleBuffer::SampleBuffer(const AudioParams &audio_params, int samples_per_channel) : + audio_params_(audio_params), + sample_count_per_channel_(samples_per_channel) { - return CreateAllocated(audio_params, audio_params.time_to_samples(length)); -} - -SampleBufferPtr SampleBuffer::CreateAllocated(const AudioParams &audio_params, int samples_per_channel) -{ - SampleBufferPtr buffer = Create(); - - buffer->set_audio_params(audio_params); - buffer->set_sample_count(samples_per_channel); - buffer->allocate(); - - return buffer; + allocate(); } const AudioParams &SampleBuffer::audio_params() const @@ -104,14 +99,11 @@ void SampleBuffer::allocate() for (int i=0; i; - /** * @brief A buffer of audio samples * @@ -42,12 +39,8 @@ class SampleBuffer { public: SampleBuffer(); - - static SampleBufferPtr Create(); - static SampleBufferPtr CreateAllocated(const AudioParams& audio_params, const rational& length); - static SampleBufferPtr CreateAllocated(const AudioParams& audio_params, int samples_per_channel); - - DISABLE_COPY_MOVE(SampleBuffer) + SampleBuffer(const AudioParams& audio_params, const rational& length); + SampleBuffer(const AudioParams& audio_params, int samples_per_channel); const AudioParams& audio_params() const; void set_audio_params(const AudioParams& params); @@ -69,9 +62,13 @@ public: return data_.at(channel).constData(); } - float **to_raw_ptrs() + QVector to_raw_ptrs() { - return raw_ptrs_.data(); + QVector r(data_.size()); + for (int i=0; i > data_; - QVector raw_ptrs_; }; } -Q_DECLARE_METATYPE(olive::SampleBufferPtr) +Q_DECLARE_METATYPE(olive::SampleBuffer) #endif // SAMPLEBUFFER_H diff --git a/app/core.cpp b/app/core.cpp index eacde37e8..0010cae4d 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -108,7 +108,7 @@ void Core::DeclareTypesForQt() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); - qRegisterMetaType(); + qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); diff --git a/app/node/audio/pan/pan.cpp b/app/node/audio/pan/pan.cpp index 10661f30a..5951ef921 100644 --- a/app/node/audio/pan/pan.cpp +++ b/app/node/audio/pan/pan.cpp @@ -67,45 +67,48 @@ void PanNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeV Q_UNUSED(globals) // Create a sample job - SampleJob job(kSamplesInput, value); - - if (job.HasSamples()) { - bool push_job = false; + SampleBuffer samples = value[kSamplesInput].toSamples(); + if (samples.is_allocated()) { + bool pushed_job = false; // This node is only compatible with stereo audio - if (job.samples()->audio_params().channel_count() == 2) { + if (samples.audio_params().channel_count() == 2) { // If the input is static, we can just do it now which will be faster if (IsInputStatic(kPanningInput)) { - float pan_volume = job.GetValue(kPanningInput).toDouble(); + float pan_volume = value[kPanningInput].toDouble(); if (!qIsNull(pan_volume)) { if (pan_volume > 0) { - job.samples()->transform_volume_for_channel(0, 1.0f - pan_volume); + samples.transform_volume_for_channel(0, 1.0f - pan_volume); } else { - job.samples()->transform_volume_for_channel(1, 1.0f + pan_volume); + samples.transform_volume_for_channel(1, 1.0f + pan_volume); } } } else { // Requires job - push_job = true; + + pushed_job = true; + table->Push(NodeValue::kSamples, SampleJob(kSamplesInput, value), this); } } - table->Push(NodeValue::kSamples, push_job ? QVariant::fromValue(job) : QVariant::fromValue(job.samples()), this); + if (!pushed_job) { + table->Push(value[kSamplesInput]); + } } } -void PanNode::ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const +void PanNode::ProcessSamples(const NodeValueRow &values, const SampleBuffer &input, SampleBuffer &output, int index) const { float pan_val = values[kPanningInput].toDouble(); - for (int i=0;iaudio_params().channel_count();i++) { - output->data(i)[index] = input->data(i)[index]; + for (int i=0;i 0) { - output->data(0)[index] *= (1.0F - pan_val); + output.data(0)[index] *= (1.0F - pan_val); } else if (pan_val < 0) { - output->data(1)[index] *= (1.0F - qAbs(pan_val)); + output.data(1)[index] *= (1.0F - qAbs(pan_val)); } } diff --git a/app/node/audio/pan/pan.h b/app/node/audio/pan/pan.h index 075eafb02..8d915a6fa 100644 --- a/app/node/audio/pan/pan.h +++ b/app/node/audio/pan/pan.h @@ -40,7 +40,7 @@ public: virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override; - virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const override; + virtual void ProcessSamples(const NodeValueRow &values, const SampleBuffer &input, SampleBuffer &output, int index) const override; virtual void Retranslate() override; diff --git a/app/node/audio/volume/volume.cpp b/app/node/audio/volume/volume.cpp index e03d284b2..e0e05b6a4 100644 --- a/app/node/audio/volume/volume.cpp +++ b/app/node/audio/volume/volume.cpp @@ -73,7 +73,7 @@ void VolumeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, No table); } -void VolumeNode::ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const +void VolumeNode::ProcessSamples(const NodeValueRow &values, const SampleBuffer &input, SampleBuffer &output, int index) const { return ProcessSamplesInternal(values, kOpMultiply, kSamplesInput, kVolumeInput, input, output, index); } diff --git a/app/node/audio/volume/volume.h b/app/node/audio/volume/volume.h index 38ba243d8..73f0c43df 100644 --- a/app/node/audio/volume/volume.h +++ b/app/node/audio/volume/volume.h @@ -40,7 +40,7 @@ public: virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override; - virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const override; + virtual void ProcessSamples(const NodeValueRow &values, const SampleBuffer &input, SampleBuffer &output, int index) const override; virtual void Retranslate() override; diff --git a/app/node/block/transition/crossdissolve/crossdissolvetransition.cpp b/app/node/block/transition/crossdissolve/crossdissolvetransition.cpp index bc7466785..bba754160 100644 --- a/app/node/block/transition/crossdissolve/crossdissolvetransition.cpp +++ b/app/node/block/transition/crossdissolve/crossdissolvetransition.cpp @@ -60,27 +60,27 @@ void CrossDissolveTransition::ShaderJobEvent(const NodeValueRow &value, ShaderJo job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn); } -void CrossDissolveTransition::SampleJobEvent(SampleBufferPtr from_samples, SampleBufferPtr to_samples, SampleBufferPtr out_samples, double time_in) const +void CrossDissolveTransition::SampleJobEvent(const SampleBuffer &from_samples, const SampleBuffer &to_samples, SampleBuffer &out_samples, double time_in) const { - for (int i=0; isample_count(); i++) { - double this_sample_time = out_samples->audio_params().samples_to_time(i).toDouble() + time_in; + for (int i=0; iaudio_params().channel_count(); j++) { - out_samples->data(j)[i] = 0; + for (int j=0; jsample_count()) { - out_samples->data(j)[i] += from_samples->data(j)[i] * TransformCurve(1.0 - progress); + if (from_samples.is_allocated()) { + if (i < from_samples.sample_count()) { + out_samples.data(j)[i] += from_samples.data(j)[i] * TransformCurve(1.0 - progress); } } - if (to_samples) { + if (to_samples.is_allocated()) { // Offset input samples from the end - int in_index = i - (out_samples->sample_count() - to_samples->sample_count()); + int in_index = i - (out_samples.sample_count() - to_samples.sample_count()); if (in_index >= 0) { - out_samples->data(j)[i] += to_samples->data(j)[in_index] * TransformCurve(progress); + out_samples.data(j)[i] += to_samples.data(j)[in_index] * TransformCurve(progress); } } } diff --git a/app/node/block/transition/crossdissolve/crossdissolvetransition.h b/app/node/block/transition/crossdissolve/crossdissolvetransition.h index b1787dbf2..6cd7c8960 100644 --- a/app/node/block/transition/crossdissolve/crossdissolvetransition.h +++ b/app/node/block/transition/crossdissolve/crossdissolvetransition.h @@ -45,7 +45,7 @@ public: protected: virtual void ShaderJobEvent(const NodeValueRow &value, ShaderJob& job) const override; - virtual void SampleJobEvent(SampleBufferPtr from_samples, SampleBufferPtr to_samples, SampleBufferPtr out_samples, double time_in) const override; + virtual void SampleJobEvent(const SampleBuffer &from_samples, const SampleBuffer &to_samples, SampleBuffer &out_samples, double time_in) const override; }; diff --git a/app/node/block/transition/transition.cpp b/app/node/block/transition/transition.cpp index 9cfaf24c2..5a3ade0d8 100644 --- a/app/node/block/transition/transition.cpp +++ b/app/node/block/transition/transition.cpp @@ -206,25 +206,22 @@ void TransitionBlock::Value(const NodeValueRow &value, const NodeGlobals &global push_job = QVariant::fromValue(job); } else if (data_type == NodeValue::kSamples) { // This must be an audio transition - SampleBufferPtr from_samples = out_buffer.toSamples(); - SampleBufferPtr to_samples = in_buffer.toSamples(); + SampleBuffer from_samples = out_buffer.toSamples(); + SampleBuffer to_samples = in_buffer.toSamples(); - if (from_samples || to_samples) { + if (from_samples.is_allocated() || to_samples.is_allocated()) { double time_in = globals.time().in().toDouble(); double time_out = globals.time().out().toDouble(); - const AudioParams& params = (from_samples) ? from_samples->audio_params() : to_samples->audio_params(); + const AudioParams& params = (from_samples.is_allocated()) ? from_samples.audio_params() : to_samples.audio_params(); - SampleBufferPtr out_samples; + SampleBuffer out_samples; if (params.is_valid()) { int nb_samples = params.time_to_samples(time_out - time_in); - out_samples = SampleBuffer::CreateAllocated(params, nb_samples); + out_samples = SampleBuffer(params, nb_samples); SampleJobEvent(from_samples, to_samples, out_samples, time_in); - } else { - // Create dummy sample buffer - out_samples = SampleBuffer::Create(); } job_type = NodeValue::kSamples; @@ -251,20 +248,6 @@ void TransitionBlock::InvalidateCache(const TimeRange &range, const QString &fro super::InvalidateCache(r, from, element, options); } -void TransitionBlock::ShaderJobEvent(const NodeValueRow &value, ShaderJob &job) const -{ - Q_UNUSED(value) - Q_UNUSED(job) -} - -void TransitionBlock::SampleJobEvent(SampleBufferPtr from_samples, SampleBufferPtr to_samples, SampleBufferPtr out_samples, double time_in) const -{ - Q_UNUSED(from_samples) - Q_UNUSED(to_samples) - Q_UNUSED(out_samples) - Q_UNUSED(time_in) -} - double TransitionBlock::TransformCurve(double linear) const { switch (static_cast(GetStandardValue(kCurveInput).toInt())) { diff --git a/app/node/block/transition/transition.h b/app/node/block/transition/transition.h index e76888edd..0e3f740a6 100644 --- a/app/node/block/transition/transition.h +++ b/app/node/block/transition/transition.h @@ -73,9 +73,9 @@ public: static const QString kCenterInput; protected: - virtual void ShaderJobEvent(const NodeValueRow &value, ShaderJob& job) const; + virtual void ShaderJobEvent(const NodeValueRow &value, ShaderJob& job) const {} - virtual void SampleJobEvent(SampleBufferPtr from_samples, SampleBufferPtr to_samples, SampleBufferPtr out_samples, double time_in) const; + virtual void SampleJobEvent(const SampleBuffer &from_samples, const SampleBuffer &to_samples, SampleBuffer &out_samples, double time_in) const {} double TransformCurve(double linear) const; diff --git a/app/node/hashtraverser.cpp b/app/node/hashtraverser.cpp index cff52dd77..28948cef8 100644 --- a/app/node/hashtraverser.cpp +++ b/app/node/hashtraverser.cpp @@ -72,14 +72,8 @@ void HashTraverser::ProcessVideoFootage(TexturePtr destination, const FootageJob texture_ids_.insert(destination.get(), hash_.result()); } -void HashTraverser::ProcessAudioFootage(SampleBufferPtr destination, const FootageJob &stream, const TimeRange &input_time) +void HashTraverser::ProcessAudioFootage(SampleBuffer &destination, const FootageJob &stream, const TimeRange &input_time) { - Hash(FileFunctions::GetUniqueFileIdentifier(stream.filename())); - Hash(stream.loop_mode()); - Hash(stream.audio_params().stream_index()); - Hash(input_time); - - texture_ids_.insert(destination.get(), hash_.result()); } void HashTraverser::ProcessShader(TexturePtr destination, const Node *node, const TimeRange &range, const ShaderJob &job) @@ -104,9 +98,8 @@ void HashTraverser::ProcessColorTransform(TexturePtr destination, const Node *no texture_ids_.insert(destination.get(), hash_.result()); } -void HashTraverser::ProcessSamples(SampleBufferPtr destination, const Node *node, const TimeRange &range, const SampleJob &job) +void HashTraverser::ProcessSamples(SampleBuffer &destination, const Node *node, const TimeRange &range, const SampleJob &job) { - texture_ids_.insert(destination.get(), hash_.result()); } void HashTraverser::ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob &job) @@ -146,9 +139,6 @@ void HashTraverser::HashNodeValue(const NodeValue &value) if (value_type == NodeValue::kTexture) { TexturePtr texture = value.toTexture(); id_for_buffer = texture_ids_.value(texture.get()); - } else { - SampleBufferPtr samples = value.toSamples(); - id_for_buffer = texture_ids_.value(samples.get()); } if (!id_for_buffer.isEmpty()) { diff --git a/app/node/hashtraverser.h b/app/node/hashtraverser.h index c013f26b8..bdf0a70f4 100644 --- a/app/node/hashtraverser.h +++ b/app/node/hashtraverser.h @@ -35,13 +35,13 @@ public: protected: virtual void ProcessVideoFootage(TexturePtr destination, const FootageJob &stream, const rational &input_time) override; - virtual void ProcessAudioFootage(SampleBufferPtr destination, const FootageJob &stream, const TimeRange &input_time) override; + virtual void ProcessAudioFootage(SampleBuffer &destination, const FootageJob &stream, const TimeRange &input_time) override; virtual void ProcessShader(TexturePtr destination, const Node *node, const TimeRange &range, const ShaderJob& job) override; virtual void ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob& job) override; - virtual void ProcessSamples(SampleBufferPtr destination, const Node *node, const TimeRange &range, const SampleJob &job) override; + virtual void ProcessSamples(SampleBuffer &destination, const Node *node, const TimeRange &range, const SampleJob &job) override; virtual void ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob& job) override; diff --git a/app/node/math/math/math.cpp b/app/node/math/math/math.cpp index babe0b9a5..6bade4174 100644 --- a/app/node/math/math/math.cpp +++ b/app/node/math/math/math.cpp @@ -109,7 +109,7 @@ void MathNode::Value(const NodeValueRow &value, const NodeGlobals &globals, Node table); } -void MathNode::ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const +void MathNode::ProcessSamples(const NodeValueRow &values, const SampleBuffer &input, SampleBuffer &output, int index) const { return ProcessSamplesInternal(values, GetOperation(), kParamAIn, kParamBIn, input, output, index); } diff --git a/app/node/math/math/math.h b/app/node/math/math/math.h index 60c910140..65a63720e 100644 --- a/app/node/math/math/math.h +++ b/app/node/math/math/math.h @@ -54,7 +54,7 @@ public: virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override; - virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const override; + virtual void ProcessSamples(const NodeValueRow &values, const SampleBuffer &input, SampleBuffer &output, int index) const override; static const QString kMethodIn; static const QString kParamAIn; diff --git a/app/node/math/math/mathbase.cpp b/app/node/math/math/mathbase.cpp index 9a78b1f97..c1132fc7d 100644 --- a/app/node/math/math/mathbase.cpp +++ b/app/node/math/math/mathbase.cpp @@ -298,18 +298,18 @@ void MathNodeBase::ValueInternal(Operation operation, Pairing pairing, const QSt case kPairSampleSample: { - SampleBufferPtr samples_a = val_a.toSamples(); - SampleBufferPtr samples_b = val_b.toSamples(); + SampleBuffer samples_a = val_a.toSamples(); + SampleBuffer samples_b = val_b.toSamples(); - int max_samples = qMax(samples_a->sample_count(), samples_b->sample_count()); - int min_samples = qMin(samples_a->sample_count(), samples_b->sample_count()); + int max_samples = qMax(samples_a.sample_count(), samples_b.sample_count()); + int min_samples = qMin(samples_a.sample_count(), samples_b.sample_count()); - SampleBufferPtr mixed_samples = SampleBuffer::CreateAllocated(samples_a->audio_params(), max_samples); + SampleBuffer mixed_samples = SampleBuffer(samples_a.audio_params(), max_samples); - for (int i=0;iaudio_params().channel_count();i++) { + for (int i=0;idata(i)[j] = PerformAll(operation, samples_a->data(i)[j], samples_b->data(i)[j]); + mixed_samples.data(i)[j] = PerformAll(operation, samples_a.data(i)[j], samples_b.data(i)[j]); } } @@ -317,11 +317,11 @@ void MathNodeBase::ValueInternal(Operation operation, Pairing pairing, const QSt // Fill in remainder space with 0s int remainder = max_samples - min_samples; - SampleBufferPtr larger_buffer = (max_samples == samples_a->sample_count()) ? samples_a : samples_b; + const SampleBuffer &larger_buffer = (max_samples == samples_a.sample_count()) ? samples_a : samples_b; - for (int i=0;iaudio_params().channel_count();i++) { - memcpy(&mixed_samples->data(i)[min_samples], - &larger_buffer->data(i)[min_samples], + for (int i=0;iaudio_params().channel_count();i++) { + for (int i=0;idata(i), number, 0, job.samples()->sample_count()); + PerformAllOnFloatBufferSSE(operation, buffer.data(i), number, 0, buffer.sample_count()); #else - PerformAllOnFloatBuffer(operation, job.samples()->data(i), number, 0, job.samples()->sample_count()); + PerformAllOnFloatBuffer(operation, buffer.data(i), number, 0, buffer.sample_count()); #endif } } - output->Push(NodeValue::kSamples, QVariant::fromValue(job.samples()), this); + output->Push(NodeValue::kSamples, QVariant::fromValue(buffer), this); } else { + SampleJob job(val_a.type() == NodeValue::kSamples ? val_a : val_b); + job.InsertValue(number_param, NodeValue(NodeValue::kFloat, number, this)); output->Push(NodeValue::kSamples, QVariant::fromValue(job), this); } } @@ -426,7 +427,7 @@ void MathNodeBase::ValueInternal(Operation operation, Pairing pairing, const QSt } } -void MathNodeBase::ProcessSamplesInternal(const NodeValueRow &values, MathNodeBase::Operation operation, const QString ¶m_a_in, const QString ¶m_b_in, const SampleBufferPtr input, SampleBufferPtr output, int index) const +void MathNodeBase::ProcessSamplesInternal(const NodeValueRow &values, MathNodeBase::Operation operation, const QString ¶m_a_in, const QString ¶m_b_in, const olive::SampleBuffer &input, olive::SampleBuffer &output, int index) const { // This function is only used for sample+number pairing NodeValue number_val = values[param_a_in]; @@ -441,8 +442,8 @@ void MathNodeBase::ProcessSamplesInternal(const NodeValueRow &values, MathNodeBa float number_flt = RetrieveNumber(number_val); - for (int i=0;iaudio_params().channel_count();i++) { - output->data(i)[index] = PerformAll(operation, input->data(i)[index], number_flt); + for (int i=0;i(operation, input.data(i)[index], number_flt); } } diff --git a/app/node/math/math/mathbase.h b/app/node/math/math/mathbase.h index 77f3fe336..80cb792a7 100644 --- a/app/node/math/math/mathbase.h +++ b/app/node/math/math/mathbase.h @@ -121,7 +121,7 @@ protected: void ValueInternal(Operation operation, Pairing pairing, const QString& param_a_in, const NodeValue &val_a, const QString& param_b_in, const NodeValue& val_b, const NodeGlobals &globals, NodeValueTable *output) const; - void ProcessSamplesInternal(const NodeValueRow &values, Operation operation, const QString& param_a_in, const QString& param_b_in, const SampleBufferPtr input, SampleBufferPtr output, int index) const; + void ProcessSamplesInternal(const NodeValueRow &values, Operation operation, const QString& param_a_in, const QString& param_b_in, const SampleBuffer &input, SampleBuffer &output, int index) const; }; diff --git a/app/node/node.cpp b/app/node/node.cpp index b2eff40f2..e6c542f8d 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -1525,7 +1525,7 @@ ShaderCode Node::GetShaderCode(const ShaderRequest &request) const return ShaderCode(QString(), QString()); } -void Node::ProcessSamples(const NodeValueRow &, const SampleBufferPtr, SampleBufferPtr, int) const +void Node::ProcessSamples(const NodeValueRow &, const SampleBuffer &, SampleBuffer &, int) const { } diff --git a/app/node/node.h b/app/node/node.h index 949cd6890..61af71fd7 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -691,7 +691,7 @@ public: /** * @brief If Value() pushes a ShaderJob, this is the function that will process them. */ - virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const; + virtual void ProcessSamples(const NodeValueRow &values, const SampleBuffer &input, SampleBuffer &output, int index) const; /** * @brief If Value() pushes a GenerateJob, override this function for the image to create diff --git a/app/node/traverser.cpp b/app/node/traverser.cpp index 54cd8758c..2139bae4d 100644 --- a/app/node/traverser.cpp +++ b/app/node/traverser.cpp @@ -400,7 +400,7 @@ void NodeTraverser::ResolveJobs(NodeValue &val, const TimeRange &range) } else if (job.type() == Track::kAudio) { - SampleBufferPtr buffer = CreateSampleBuffer(GetCacheAudioParams(), range.length()); + SampleBuffer buffer = CreateSampleBuffer(GetCacheAudioParams(), range.length()); ProcessAudioFootage(buffer, job, range); val.set_value(buffer); @@ -409,7 +409,7 @@ void NodeTraverser::ResolveJobs(NodeValue &val, const TimeRange &range) } else if (val.canConvert()) { SampleJob job = val.value(); - SampleBufferPtr output_buffer = CreateSampleBuffer(job.samples()->audio_params(), job.samples()->sample_count()); + SampleBuffer output_buffer = CreateSampleBuffer(job.samples().audio_params(), job.samples().sample_count()); ProcessSamples(output_buffer, val.source(), range, job); val.set_value(QVariant::fromValue(output_buffer)); diff --git a/app/node/traverser.h b/app/node/traverser.h index b806230cb..090599673 100644 --- a/app/node/traverser.h +++ b/app/node/traverser.h @@ -85,13 +85,13 @@ protected: virtual void ProcessVideoFootage(TexturePtr destination, const FootageJob &stream, const rational &input_time){} - virtual void ProcessAudioFootage(SampleBufferPtr destination, const FootageJob &stream, const TimeRange &input_time){} + virtual void ProcessAudioFootage(SampleBuffer &destination, const FootageJob &stream, const TimeRange &input_time){} virtual void ProcessShader(TexturePtr destination, const Node *node, const TimeRange &range, const ShaderJob& job){} virtual void ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob& job){} - virtual void ProcessSamples(SampleBufferPtr destination, const Node *node, const TimeRange &range, const SampleJob &job){} + virtual void ProcessSamples(SampleBuffer &destination, const Node *node, const TimeRange &range, const SampleJob &job){} virtual void ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob& job){} @@ -102,18 +102,18 @@ protected: return CreateDummyTexture(p); } - virtual SampleBufferPtr CreateSampleBuffer(const AudioParams ¶ms, int sample_count) + virtual SampleBuffer CreateSampleBuffer(const AudioParams ¶ms, int sample_count) { // Return dummy by default - return SampleBuffer::Create(); + return SampleBuffer(); } - SampleBufferPtr CreateSampleBuffer(const AudioParams ¶ms, const rational &length) + SampleBuffer CreateSampleBuffer(const AudioParams ¶ms, const rational &length) { if (params.is_valid()) { return CreateSampleBuffer(params, params.time_to_samples(length)); } else { - return SampleBuffer::Create(); + return SampleBuffer(); } } diff --git a/app/node/value.h b/app/node/value.h index bb5b56dbe..6c8534a2a 100644 --- a/app/node/value.h +++ b/app/node/value.h @@ -307,7 +307,7 @@ public: static void ValidateVectorString(QStringList* list, int count); TexturePtr toTexture() const { return value(); } - SampleBufferPtr toSamples() const { return value(); } + SampleBuffer toSamples() const { return value(); } bool toBool() const { return value(); } double toDouble() const { return value(); } int64_t toInt() const { return value(); } diff --git a/app/render/audioplaybackcache.cpp b/app/render/audioplaybackcache.cpp index e96d6cead..f014a2cf6 100644 --- a/app/render/audioplaybackcache.cpp +++ b/app/render/audioplaybackcache.cpp @@ -58,7 +58,7 @@ void AudioPlaybackCache::SetParameters(const AudioParams ¶ms) emit ParametersChanged(); } -void AudioPlaybackCache::WritePCM(const TimeRange &range, const TimeRangeList &valid_ranges, SampleBufferPtr samples) +void AudioPlaybackCache::WritePCM(const TimeRange &range, const TimeRangeList &valid_ranges, const SampleBuffer &samples) { // Ensure if we have enough segments to write this data, creating more if not qint64 length_diff = params_.time_to_bytes_per_channel(range.out()) - playlist_.GetLength(); @@ -72,7 +72,7 @@ void AudioPlaybackCache::WritePCM(const TimeRange &range, const TimeRangeList &v TimeRangeList ranges_we_validated; // Calculate buffer size per channel - qint64 buffer_size_per_channel = samples ? samples->sample_count() * params_.bytes_per_sample_per_channel() : 0; + qint64 buffer_size_per_channel = samples.sample_count() * params_.bytes_per_sample_per_channel(); // Write each valid range to the segments foreach (const TimeRange& r, valid_ranges) { @@ -114,7 +114,7 @@ void AudioPlaybackCache::WritePCM(const TimeRange &range, const TimeRangeList &v if (possible_write_length > 0) { // Assume `samples` is valid if we're here, or else `buffer_size_per_channel` and // therefore `possible_write_length` will be 0. - seg_file.write(reinterpret_cast(samples->data(i)) + src_offset, possible_write_length); + seg_file.write(reinterpret_cast(samples.data(i)) + src_offset, possible_write_length); } if (possible_write_length < total_write_length) { @@ -167,7 +167,7 @@ void AudioPlaybackCache::WriteSilence(const TimeRange &range) { // WritePCM will automatically fill non-existent bytes with silence, so we just have to send // it an empty sample buffer - WritePCM(range, {range}, nullptr); + WritePCM(range, {range}, SampleBuffer()); } void AudioPlaybackCache::ShiftEvent(const rational &from_in_time, const rational &to_in_time) diff --git a/app/render/audioplaybackcache.h b/app/render/audioplaybackcache.h index 8394975a9..8a75b0173 100644 --- a/app/render/audioplaybackcache.h +++ b/app/render/audioplaybackcache.h @@ -66,7 +66,7 @@ public: void SetParameters(const AudioParams& params); - void WritePCM(const TimeRange &range, const TimeRangeList &valid_ranges, SampleBufferPtr samples); + void WritePCM(const TimeRange &range, const TimeRangeList &valid_ranges, const SampleBuffer &samples); void WriteWaveform(const TimeRange &range, const TimeRangeList &valid_ranges, const AudioVisualWaveform *waveform); diff --git a/app/render/job/samplejob.h b/app/render/job/samplejob.h index 65aca18f5..f2cd928e6 100644 --- a/app/render/job/samplejob.h +++ b/app/render/job/samplejob.h @@ -30,7 +30,6 @@ class SampleJob : public AcceleratedJob { public: SampleJob() { - samples_ = nullptr; } SampleJob(const NodeValue& value) @@ -43,18 +42,18 @@ public: samples_ = row[from].toSamples(); } - SampleBufferPtr samples() const + const SampleBuffer &samples() const { return samples_; } bool HasSamples() const { - return samples_ && samples_->is_allocated(); + return samples_.is_allocated(); } private: - SampleBufferPtr samples_; + SampleBuffer samples_; }; diff --git a/app/render/previewautocacher.cpp b/app/render/previewautocacher.cpp index c548b1f8f..6b17b1387 100644 --- a/app/render/previewautocacher.cpp +++ b/app/render/previewautocacher.cpp @@ -207,7 +207,7 @@ void PreviewAutoCacher::AudioRendered() // WritePCM is tolerant to its buffer being null, it will just write silence instead viewer_node_->audio_playback_cache()->WritePCM(range, valid_ranges, - watcher->Get().value()); + watcher->Get().value()); } viewer_node_->audio_playback_cache()->WriteWaveform(range, valid_ranges, &waveform); diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index e81a056f7..de733dec5 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -200,11 +200,11 @@ void RenderProcessor::Run() ResolveJobs(sample_val, time); - SampleBufferPtr samples = sample_val.toSamples(); - if (samples && ticket_->property("enablewaveforms").toBool()) { + SampleBuffer samples = sample_val.toSamples(); + if (samples.is_allocated() && ticket_->property("enablewaveforms").toBool()) { AudioVisualWaveform vis; - vis.set_channel_count(samples->audio_params().channel_count()); - vis.OverwriteSamples(samples, samples->audio_params().sample_rate()); + vis.set_channel_count(samples.audio_params().channel_count()); + vis.OverwriteSamples(samples, samples.audio_params().sample_rate()); ticket_->setProperty("waveform", QVariant::fromValue(vis)); } @@ -275,9 +275,8 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim QVector active_blocks = track->BlocksAtTimeRange(range); // All these blocks will need to output to a buffer so we create one here - SampleBufferPtr block_range_buffer = SampleBuffer::CreateAllocated(audio_params, - audio_params.time_to_samples(range.length())); - block_range_buffer->silence(); + SampleBuffer block_range_buffer(audio_params, range.length()); + block_range_buffer.silence(); NodeValueTable merged_table; @@ -292,10 +291,10 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim // Destination buffer NodeValueTable table = GenerateTable(b, track->GetValueHintForInput(Track::kBlockInput, track->GetArrayIndexFromBlock(b)),Track::TransformRangeForBlock(b, range_for_block)); - SampleBufferPtr samples_from_this_block = table.Take(NodeValue::kSamples).toSamples(); + SampleBuffer samples_from_this_block = table.Take(NodeValue::kSamples).toSamples(); ClipBlock *clip_cast = dynamic_cast(b); - if (samples_from_this_block) { + if (samples_from_this_block.is_allocated()) { // If this is a clip, we might have extra speed/reverse information if (clip_cast) { double speed_value = clip_cast->speed(); @@ -303,12 +302,12 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim if (qIsNull(speed_value)) { // Just silence, don't think there's any other practical application of 0 speed audio - samples_from_this_block->silence(); + samples_from_this_block.silence(); } else if (!qFuzzyCompare(speed_value, 1.0)) { if (clip_cast->maintain_audio_pitch()) { AudioProcessor processor; - if (processor.Open(samples_from_this_block->audio_params(), samples_from_this_block->audio_params(), speed_value)) { + if (processor.Open(samples_from_this_block.audio_params(), samples_from_this_block.audio_params(), speed_value)) { AudioProcessor::Buffer out; // FIXME: This is not the best way to do this, the TempoProcessor works best @@ -317,7 +316,7 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim // well on export (assuming audio is all generated at once on export), but // users may hear clicks and pops in the audio during preview due to this // approach. - int r = processor.Convert(samples_from_this_block->to_raw_ptrs(), samples_from_this_block->sample_count(), nullptr); + int r = processor.Convert(samples_from_this_block.to_raw_ptrs().data(), samples_from_this_block.sample_count(), nullptr); if (r < 0) { qCritical() << "Failed to change tempo of audio:" << r; @@ -327,16 +326,13 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim processor.Convert(nullptr, 0, &out); if (!out.empty()) { - int nb_samples = out.front().size() * samples_from_this_block->audio_params().bytes_per_sample_per_channel(); + int nb_samples = out.front().size() * samples_from_this_block.audio_params().bytes_per_sample_per_channel(); if (nb_samples) { - SampleBufferPtr new_samples = SampleBuffer::Create(); - new_samples->set_audio_params(samples_from_this_block->audio_params()); - new_samples->set_sample_count(nb_samples); - new_samples->allocate(); + SampleBuffer new_samples(samples_from_this_block.audio_params(), nb_samples); for (int i=0; idata(i), out[i].data(), out[i].size()); + memcpy(new_samples.data(i), out[i].data(), out[i].size()); } samples_from_this_block = new_samples; @@ -346,20 +342,20 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim } } else { // Multiply time - samples_from_this_block->speed(speed_value); + samples_from_this_block.speed(speed_value); } } if (reversed) { - samples_from_this_block->reverse(); + samples_from_this_block.reverse(); } } - int copy_length = qMin(max_dest_sz, samples_from_this_block->sample_count()); + int copy_length = qMin(max_dest_sz, samples_from_this_block.sample_count()); // Copy samples into destination buffer - for (int i=0; iaudio_params().channel_count(); i++) { - block_range_buffer->set(i, samples_from_this_block->data(i), destination_offset, copy_length); + for (int i=0; iin(); - if (!(waveform_info.silence = !samples_from_this_block.get())) { + if (!(waveform_info.silence = !samples_from_this_block.is_allocated())) { // Generate a visual waveform from the samples acquired from this block AudioVisualWaveform visual_waveform; visual_waveform.set_channel_count(audio_params.channel_count()); @@ -483,7 +479,7 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, const FootageJ } } -void RenderProcessor::ProcessAudioFootage(SampleBufferPtr destination, const FootageJob &stream, const TimeRange &input_time) +void RenderProcessor::ProcessAudioFootage(SampleBuffer &destination, const FootageJob &stream, const TimeRange &input_time) { DecoderPtr decoder = ResolveDecoderFromInput(stream.decoder(), Decoder::CodecStream(stream.filename(), stream.audio_params().stream_index())); @@ -526,9 +522,9 @@ void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node, co render_ctx_->BlitToTexture(shader, job, destination.get()); } -void RenderProcessor::ProcessSamples(SampleBufferPtr destination, const Node *node, const TimeRange &range, const SampleJob &job) +void RenderProcessor::ProcessSamples(SampleBuffer &destination, const Node *node, const TimeRange &range, const SampleJob &job) { - if (!job.samples() || !job.samples()->is_allocated()) { + if (!job.samples().is_allocated()) { return; } @@ -536,7 +532,7 @@ void RenderProcessor::ProcessSamples(SampleBufferPtr destination, const Node *no const AudioParams& audio_params = GetCacheAudioParams(); - for (int i=0;isample_count();i++) { + for (int i=0;i(i) / static_cast(audio_params.sample_rate()); diff --git a/app/render/renderprocessor.h b/app/render/renderprocessor.h index 8397b5f45..017cedada 100644 --- a/app/render/renderprocessor.h +++ b/app/render/renderprocessor.h @@ -46,11 +46,11 @@ protected: virtual void ProcessVideoFootage(TexturePtr destination, const FootageJob &stream, const rational &input_time) override; - virtual void ProcessAudioFootage(SampleBufferPtr destination, const FootageJob &stream, const TimeRange &input_time) override; + virtual void ProcessAudioFootage(SampleBuffer &destination, const FootageJob &stream, const TimeRange &input_time) override; virtual void ProcessShader(TexturePtr destination, const Node *node, const TimeRange &range, const ShaderJob& job) override; - virtual void ProcessSamples(SampleBufferPtr destination, const Node *node, const TimeRange &range, const SampleJob &job) override; + virtual void ProcessSamples(SampleBuffer &destination, const Node *node, const TimeRange &range, const SampleJob &job) override; virtual void ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob& job) override; @@ -63,9 +63,9 @@ protected: return render_ctx_->CreateTexture(p); } - virtual SampleBufferPtr CreateSampleBuffer(const AudioParams ¶ms, int sample_count) override + virtual SampleBuffer CreateSampleBuffer(const AudioParams ¶ms, int sample_count) override { - return SampleBuffer::CreateAllocated(params, sample_count); + return SampleBuffer(params, sample_count); } virtual void ConvertToReferenceSpace(TexturePtr destination, TexturePtr source, const QString &input_cs) override; diff --git a/app/task/export/export.cpp b/app/task/export/export.cpp index 819d9251e..21c330c29 100644 --- a/app/task/export/export.cpp +++ b/app/task/export/export.cpp @@ -192,7 +192,7 @@ bool ExportTask::FrameDownloaded(FramePtr f, const QByteArray &hash, const QVect return true; } -bool ExportTask::AudioDownloaded(const TimeRange &range, SampleBufferPtr samples) +bool ExportTask::AudioDownloaded(const TimeRange &range, const SampleBuffer &samples) { TimeRange adjusted_range = range; @@ -221,7 +221,7 @@ bool ExportTask::EncodeSubtitle(const SubtitleBlock *sub) } } -bool ExportTask::WriteAudioLoop(const TimeRange& time, SampleBufferPtr samples) +bool ExportTask::WriteAudioLoop(const TimeRange& time, const SampleBuffer &samples) { if (!encoder_->WriteAudio(samples)) { SetError(encoder_->GetError()); @@ -232,7 +232,7 @@ bool ExportTask::WriteAudioLoop(const TimeRange& time, SampleBufferPtr samples) for (auto it=audio_map_.begin(); it!=audio_map_.end(); it++) { TimeRange t = it.key(); - SampleBufferPtr s = it.value(); + SampleBuffer s = it.value(); if (t.in() == audio_time_) { // Erase from audio map since we're just about to write it diff --git a/app/task/export/export.h b/app/task/export/export.h index 2efade730..2ab27f917 100644 --- a/app/task/export/export.h +++ b/app/task/export/export.h @@ -40,7 +40,7 @@ protected: virtual bool FrameDownloaded(FramePtr frame, const QByteArray& hash, const QVector& times) override; - virtual bool AudioDownloaded(const TimeRange& range, SampleBufferPtr samples) override; + virtual bool AudioDownloaded(const TimeRange& range, const SampleBuffer &samples) override; virtual bool EncodeSubtitle(const SubtitleBlock *sub) override; @@ -50,11 +50,11 @@ protected: } private: - bool WriteAudioLoop(const TimeRange &time, SampleBufferPtr samples); + bool WriteAudioLoop(const TimeRange &time, const SampleBuffer &samples); QHash time_map_; - QHash audio_map_; + QHash audio_map_; ColorManager* color_manager_; diff --git a/app/task/precache/precachetask.cpp b/app/task/precache/precachetask.cpp index bb1af998f..71cedb900 100644 --- a/app/task/precache/precachetask.cpp +++ b/app/task/precache/precachetask.cpp @@ -97,7 +97,7 @@ bool PreCacheTask::FrameDownloaded(FramePtr frame, const QByteArray &hash, const return true; } -bool PreCacheTask::AudioDownloaded(const TimeRange &range, SampleBufferPtr samples) +bool PreCacheTask::AudioDownloaded(const TimeRange &range, const SampleBuffer &samples) { // Pre-cache doesn't cache any audio diff --git a/app/task/precache/precachetask.h b/app/task/precache/precachetask.h index 78e153744..dcd9369bf 100644 --- a/app/task/precache/precachetask.h +++ b/app/task/precache/precachetask.h @@ -40,7 +40,7 @@ protected: virtual bool FrameDownloaded(FramePtr frame, const QByteArray& hash, const QVector& times) override; - virtual bool AudioDownloaded(const TimeRange& range, SampleBufferPtr samples) override; + virtual bool AudioDownloaded(const TimeRange& range, const SampleBuffer &samples) override; private: Project* project_; diff --git a/app/task/render/render.cpp b/app/task/render/render.cpp index 56e9975a2..c37c7cd93 100644 --- a/app/task/render/render.cpp +++ b/app/task/render/render.cpp @@ -195,7 +195,7 @@ bool RenderTask::Render(ColorManager* manager, TimeRange range = watcher->property("range").value(); - if (!AudioDownloaded(range, watcher->Get().value())) { + if (!AudioDownloaded(range, watcher->Get().value())) { result = false; } diff --git a/app/task/render/render.h b/app/task/render/render.h index 75d6c73c0..01909081f 100644 --- a/app/task/render/render.h +++ b/app/task/render/render.h @@ -53,7 +53,7 @@ protected: virtual bool FrameDownloaded(FramePtr frame, const QByteArray& hash, const QVector& times) = 0; - virtual bool AudioDownloaded(const TimeRange& range, SampleBufferPtr samples) = 0; + virtual bool AudioDownloaded(const TimeRange& range, const SampleBuffer &samples) = 0; virtual bool EncodeSubtitle(const SubtitleBlock *subtitle); diff --git a/app/widget/audiomonitor/audiomonitor.cpp b/app/widget/audiomonitor/audiomonitor.cpp index 10777ba00..982bb152a 100644 --- a/app/widget/audiomonitor/audiomonitor.cpp +++ b/app/widget/audiomonitor/audiomonitor.cpp @@ -75,7 +75,7 @@ void AudioMonitor::Stop() // loop will stop itself since file_ and waveform_ are null. } -void AudioMonitor::PushSampleBuffer(SampleBufferPtr d) +void AudioMonitor::PushSampleBuffer(const SampleBuffer &d) { if (!params_.channel_count()) { return; @@ -83,7 +83,7 @@ void AudioMonitor::PushSampleBuffer(SampleBufferPtr d) QVector v(params_.channel_count(), 0); - AudioVisualWaveform::Sample summed = AudioVisualWaveform::SumSamples(d, 0, d->sample_count()); + AudioVisualWaveform::Sample summed = AudioVisualWaveform::SumSamples(d, 0, d.sample_count()); AudioVisualWaveformSampleToInternalValues(summed, v); diff --git a/app/widget/audiomonitor/audiomonitor.h b/app/widget/audiomonitor/audiomonitor.h index f532aa206..3c5e27d81 100644 --- a/app/widget/audiomonitor/audiomonitor.h +++ b/app/widget/audiomonitor/audiomonitor.h @@ -59,7 +59,7 @@ public: } } - static void PushSampleBufferOnAll(SampleBufferPtr d) + static void PushSampleBufferOnAll(const SampleBuffer &d) { foreach (AudioMonitor *m, instances_) { m->PushSampleBuffer(d); @@ -71,7 +71,7 @@ public slots: void Stop(); - void PushSampleBuffer(SampleBufferPtr samples); + void PushSampleBuffer(const SampleBuffer &samples); void StartWaveform(const AudioVisualWaveform *waveform, const rational& start, int playback_speed); diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 1568f3237..f638bc67c 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -511,16 +511,16 @@ void ViewerWidget::ReceivedAudioBufferForPlayback() audio_playback_queue_.pop_front(); if (watcher->HasResult()) { - SampleBufferPtr samples = watcher->Get().value(); - if (samples) { + SampleBuffer samples = watcher->Get().value(); + if (samples.is_allocated()) { // If the samples must be reversed, reverse them now if (playback_speed_ < 0) { - samples->reverse(); + samples.reverse(); } // Convert to packed data for audio output AudioProcessor::Buffer buf; - int r = audio_processor_.Convert(samples->to_raw_ptrs(), samples->sample_count(), &buf); + int r = audio_processor_.Convert(samples.to_raw_ptrs().data(), samples.sample_count(), &buf); // TempoProcessor may have emptied the array if (r >= 0) { @@ -556,8 +556,9 @@ void ViewerWidget::ReceivedAudioBufferForScrubbing() RenderTicketWatcher *watcher = static_cast(sender()); if (watcher->HasResult()) { - if (SampleBufferPtr samples = watcher->Get().value()) { - if (samples->audio_params().channel_count() > 0) { + SampleBuffer samples = watcher->Get().value(); + if (samples.is_allocated()) { + if (samples.audio_params().channel_count() > 0) { /* Fade code const int kFadeSz = qMin(200, samples->sample_count()/4); for (int i=0; ito_raw_ptrs(), samples->sample_count(), &buf); + int r = audio_processor_.Convert(samples.to_raw_ptrs().data(), samples.sample_count(), &buf); if (r >= 0) { if (!buf.empty()) {