diff --git a/libraries/lib-stretching-sequence/AudioSegment.h b/libraries/lib-stretching-sequence/AudioSegment.h index 9470641d484c..dfb852cc28d8 100644 --- a/libraries/lib-stretching-sequence/AudioSegment.h +++ b/libraries/lib-stretching-sequence/AudioSegment.h @@ -27,13 +27,12 @@ class STRETCHING_SEQUENCE_API AudioSegment /** * @brief Fills `buffers` with as many as `numSamples` or the number of * remaining samples, whichever is smaller. - * @param buffers A vector of pointers to buffers, one for each channel. + * @param buffers Pointers to buffers, one for each channel. * @param numSamples The max. number of samples to write to each buffer. - * @pre `buffers.size() == GetWidth()` * @return The number of samples actually provided in each buffer. */ virtual size_t - GetFloats(std::vector& buffers, size_t numSamples) = 0; + GetFloats(float *const *buffers, size_t numSamples) = 0; /** * @brief The number of channels in the segment. diff --git a/libraries/lib-stretching-sequence/ClipSegment.cpp b/libraries/lib-stretching-sequence/ClipSegment.cpp index 167b40d0f8db..090c163b462f 100644 --- a/libraries/lib-stretching-sequence/ClipSegment.cpp +++ b/libraries/lib-stretching-sequence/ClipSegment.cpp @@ -46,12 +46,11 @@ ClipSegment::ClipSegment( { } -size_t ClipSegment::GetFloats(std::vector& buffers, size_t numSamples) +size_t ClipSegment::GetFloats(float *const *buffers, size_t numSamples) { - assert(buffers.size() == mSource.GetWidth()); const auto numSamplesToProduce = limitSampleBufferSize( numSamples, mTotalNumSamplesToProduce - mTotalNumSamplesProduced); - mStretcher->GetSamples(buffers.data(), numSamplesToProduce); + mStretcher->GetSamples(buffers, numSamplesToProduce); mTotalNumSamplesProduced += numSamplesToProduce; return numSamplesToProduce; } diff --git a/libraries/lib-stretching-sequence/ClipSegment.h b/libraries/lib-stretching-sequence/ClipSegment.h index 2acce0962b3c..1e1e516f05c3 100644 --- a/libraries/lib-stretching-sequence/ClipSegment.h +++ b/libraries/lib-stretching-sequence/ClipSegment.h @@ -26,7 +26,7 @@ class STRETCHING_SEQUENCE_API ClipSegment final : public AudioSegment const ClipInterface&, double durationToDiscard, PlaybackDirection); // AudioSegment - size_t GetFloats(std::vector& buffers, size_t numSamples) override; + size_t GetFloats(float *const *buffers, size_t numSamples) override; bool Empty() const override; size_t GetWidth() const override; diff --git a/libraries/lib-stretching-sequence/SilenceSegment.cpp b/libraries/lib-stretching-sequence/SilenceSegment.cpp index 9aa0f01b5d5f..7339aa2c98a0 100644 --- a/libraries/lib-stretching-sequence/SilenceSegment.cpp +++ b/libraries/lib-stretching-sequence/SilenceSegment.cpp @@ -20,9 +20,8 @@ SilenceSegment::SilenceSegment(size_t numChannels, sampleCount numSamples) } size_t -SilenceSegment::GetFloats(std::vector& buffers, size_t numSamples) +SilenceSegment::GetFloats(float *const *buffers, size_t numSamples) { - assert(buffers.size() == mNumChannels); const size_t numSamplesToProduce = std::min(mNumRemainingSamples.as_long_long(), numSamples); for (auto i = 0u; i < mNumChannels; ++i) diff --git a/libraries/lib-stretching-sequence/SilenceSegment.h b/libraries/lib-stretching-sequence/SilenceSegment.h index 3e6533425ea9..a12300237cad 100644 --- a/libraries/lib-stretching-sequence/SilenceSegment.h +++ b/libraries/lib-stretching-sequence/SilenceSegment.h @@ -18,7 +18,7 @@ class STRETCHING_SEQUENCE_API SilenceSegment final : public AudioSegment { public: SilenceSegment(size_t numChannels, sampleCount numSamples); - size_t GetFloats(std::vector& buffers, size_t numSamples) override; + size_t GetFloats(float *const *buffers, size_t numSamples) override; bool Empty() const override; size_t GetWidth() const override; diff --git a/libraries/lib-stretching-sequence/StretchingSequence.cpp b/libraries/lib-stretching-sequence/StretchingSequence.cpp index 5496786a958b..4647a4027728 100644 --- a/libraries/lib-stretching-sequence/StretchingSequence.cpp +++ b/libraries/lib-stretching-sequence/StretchingSequence.cpp @@ -17,13 +17,14 @@ namespace { -std::vector -GetOffsetBuffer(float* const* buffer, size_t numChannels, size_t offset) +#define stackAllocate(T, count) static_cast(alloca(count * sizeof(T))) + +void +GetOffsetBuffer(float **offsetBuffer, + float* const* buffer, size_t numChannels, size_t offset) { - std::vector offsetBuffer(numChannels); for (auto i = 0u; i < numChannels; ++i) offsetBuffer[i] = buffer[i] + offset; - return offsetBuffer; } } // namespace @@ -54,8 +55,9 @@ bool StretchingSequence::GetNext( mActiveAudioSegmentIt != mAudioSegments.end()) { const auto& segment = *mActiveAudioSegmentIt; - auto offsetBuffers = - GetOffsetBuffer(buffers, mSequence.NChannels(), numProcessedSamples); + const auto offsetBuffers = stackAllocate(float *, mSequence.NChannels()); + GetOffsetBuffer(offsetBuffers, + buffers, mSequence.NChannels(), numProcessedSamples); numProcessedSamples += segment->GetFloats( offsetBuffers, numSamples - numProcessedSamples); // No need to reverse, we feed the @@ -67,8 +69,9 @@ bool StretchingSequence::GetNext( const auto remaining = numSamples - numProcessedSamples; if (remaining > 0u) { - const auto offsetBuffers = - GetOffsetBuffer(buffers, mSequence.NChannels(), numProcessedSamples); + const auto offsetBuffers = stackAllocate(float *, mSequence.NChannels()); + GetOffsetBuffer( + offsetBuffers, buffers, mSequence.NChannels(), numProcessedSamples); for (auto i = 0u; i < mSequence.NChannels(); ++i) std::fill(offsetBuffers[i], offsetBuffers[i] + remaining, 0.f); } diff --git a/libraries/lib-stretching-sequence/tests/ClipSegmentTest.cpp b/libraries/lib-stretching-sequence/tests/ClipSegmentTest.cpp index 15d63d2d50c4..6fefda1996b7 100644 --- a/libraries/lib-stretching-sequence/tests/ClipSegmentTest.cpp +++ b/libraries/lib-stretching-sequence/tests/ClipSegmentTest.cpp @@ -38,7 +38,7 @@ TEST_CASE("ClipSegment") FloatVectorVector { { 1.f, 2.f, 3.f }, { -1.f, -2.f, -3.f } }); ClipSegment sut { *clip, 0., direction }; AudioContainer output(sampleRate, numChannels); - REQUIRE(sut.GetFloats(output.channelPointers, sampleRate) == sampleRate); + REQUIRE(sut.GetFloats(output.channelPointers.data(), sampleRate) == sampleRate); if (numChannels == 1u) { const auto expected = direction == PlaybackDirection::forward ? @@ -69,7 +69,7 @@ TEST_CASE("ClipSegment") constexpr auto playbackOffset = 2 / static_cast(sampleRate); ClipSegment sut { *clip, playbackOffset, direction }; AudioContainer output(numSamples, 1u); - REQUIRE(sut.GetFloats(output.channelPointers, numSamples) == 3); + REQUIRE(sut.GetFloats(output.channelPointers.data(), numSamples) == 3); const auto expected = direction == PlaybackDirection::forward ? std::vector { 3.f, 4.f, 5.f, 0.f, 0.f } : std::vector { 3.f, 2.f, 1.f, 0.f, 0.f }; diff --git a/libraries/lib-stretching-sequence/tests/MockAudioSegmentFactory.h b/libraries/lib-stretching-sequence/tests/MockAudioSegmentFactory.h index b76ef56a1023..50a1ff122ddc 100644 --- a/libraries/lib-stretching-sequence/tests/MockAudioSegmentFactory.h +++ b/libraries/lib-stretching-sequence/tests/MockAudioSegmentFactory.h @@ -16,7 +16,7 @@ class NiceAudioSegment final : public AudioSegment { public: - size_t GetFloats(std::vector&, size_t numSamples) override + size_t GetFloats(float *const *, size_t numSamples) override { return numSamples; } diff --git a/libraries/lib-stretching-sequence/tests/SilenceSegmentTest.cpp b/libraries/lib-stretching-sequence/tests/SilenceSegmentTest.cpp index 5a13b29f7c39..a0b981d559eb 100644 --- a/libraries/lib-stretching-sequence/tests/SilenceSegmentTest.cpp +++ b/libraries/lib-stretching-sequence/tests/SilenceSegmentTest.cpp @@ -21,8 +21,8 @@ TEST_CASE("SilenceSegment", "behaves as expected") SilenceSegment sut(numChannels, silenceSegmentLength); REQUIRE(!sut.Empty()); AudioContainer container(3u, numChannels); - REQUIRE(sut.GetFloats(container.channelPointers, 1) == 1); + REQUIRE(sut.GetFloats(container.channelPointers.data(), 1) == 1); REQUIRE(!sut.Empty()); - REQUIRE(sut.GetFloats(container.channelPointers, 3) == 2); + REQUIRE(sut.GetFloats(container.channelPointers.data(), 3) == 2); REQUIRE(sut.Empty()); } diff --git a/libraries/lib-time-and-pitch/StaffPadTimeAndPitch.cpp b/libraries/lib-time-and-pitch/StaffPadTimeAndPitch.cpp index 6ee28edc4861..5181c46ce1ee 100644 --- a/libraries/lib-time-and-pitch/StaffPadTimeAndPitch.cpp +++ b/libraries/lib-time-and-pitch/StaffPadTimeAndPitch.cpp @@ -10,15 +10,14 @@ namespace // to be specified in the `setup` call.) constexpr auto maxBlockSize = 1024; -std::vector -GetOffsetBuffer(float* const* buffer, size_t numChannels, size_t offset) +#define stackAllocate(T, count) static_cast(alloca(count * sizeof(T))) + +void +GetOffsetBuffer(float **offsetBuffer, + float* const* buffer, size_t numChannels, size_t offset) { - std::vector offsetBuffer(numChannels); for (auto i = 0u; i < numChannels; ++i) - { offsetBuffer[i] = buffer[i] + offset; - } - return offsetBuffer; } std::unique_ptr MaybeCreateTimeAndPitch( @@ -82,9 +81,9 @@ void StaffPadTimeAndPitch::GetSamples(float* const* output, size_t outputLen) const auto numSamplesToGet = std::min({ maxBlockSize, numOutputSamplesAvailable, static_cast(outputLen - numOutputSamples) }); - const auto buffer = - GetOffsetBuffer(output, mNumChannels, numOutputSamples); - mTimeAndPitch->retrieveAudio(buffer.data(), numSamplesToGet); + const auto buffer = stackAllocate(float*, mNumChannels); + GetOffsetBuffer(buffer, output, mNumChannels, numOutputSamples); + mTimeAndPitch->retrieveAudio(buffer, numSamplesToGet); numOutputSamplesAvailable -= numSamplesToGet; numOutputSamples += numSamplesToGet; }