Skip to content

Commit

Permalink
Merge pull request audacity#6176 from saintmatthieu/6158-buzz-when-to…
Browse files Browse the repository at this point in the history
…ggling-formant-preservation

6158 buzz when toggling formant preservation
  • Loading branch information
saintmatthieu authored Mar 26, 2024
2 parents f3116d6 + 96cc610 commit 7baedbd
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 9 deletions.
32 changes: 25 additions & 7 deletions libraries/lib-stretching-sequence/ClipSegment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "ClipInterface.h"
#include "SampleFormat.h"
#include "StaffPadTimeAndPitch.h"

#include <cassert>
#include <cmath>
#include <functional>
Expand Down Expand Up @@ -44,28 +43,47 @@ ClipSegment::ClipSegment(
: mTotalNumSamplesToProduce { GetTotalNumSamplesToProduce(
clip, durationToDiscard) }
, mSource { clip, durationToDiscard, direction }
, mPreserveFormants { clip.GetPitchAndSpeedPreset() ==
PitchAndSpeedPreset::OptimizeForVoice }
, mCentShift { clip.GetCentShift() }
, mStretcher { std::make_unique<StaffPadTimeAndPitch>(
clip.GetRate(), clip.GetWidth(), mSource,
GetStretchingParameters(clip)) }
, mOnSemitoneShiftChangeSubscription { clip.SubscribeToCentShiftChange(
[this](int cents) {
std::lock_guard<std::mutex> lock(mStretcherMutex);
mStretcher->OnCentShiftChange(cents);
mCentShift = cents;
mUpdateCentShift = true;
}) }
, mOnFormantPreservationChangeSubscription {
clip.SubscribeToPitchAndSpeedPresetChange(
[this](PitchAndSpeedPreset preset) {
std::lock_guard<std::mutex> lock(mStretcherMutex);
mStretcher->OnFormantPreservationChange(
preset == PitchAndSpeedPreset::OptimizeForVoice);
mPreserveFormants =
preset == PitchAndSpeedPreset::OptimizeForVoice;
mUpdateFormantPreservation = true;
})
}
{
}

ClipSegment::~ClipSegment()
{
mOnSemitoneShiftChangeSubscription.Reset();
mOnFormantPreservationChangeSubscription.Reset();
}

size_t ClipSegment::GetFloats(float* const* buffers, size_t numSamples)
{
std::lock_guard<std::mutex> lock(mStretcherMutex);
// Check if formant preservation of pitch shift needs to be updated.
// This approach is not immune to a race condition, but it is unlikely and
// not critical, as it would only affect one playback pass, during which the
// user could easily correct the mistake if needed. On the other hand, we
// cannot trust that the observer subscriptions do not get called after
// destruction of this object, so better not do anything too sophisticated
// there.
if (mUpdateFormantPreservation.exchange(false))
mStretcher->OnFormantPreservationChange(mPreserveFormants);
if (mUpdateCentShift.exchange(false))
mStretcher->OnCentShiftChange(mCentShift);
const auto numSamplesToProduce = limitSampleBufferSize(
numSamples, mTotalNumSamplesToProduce - mTotalNumSamplesProduced);
mStretcher->GetSamples(buffers, numSamplesToProduce);
Expand Down
8 changes: 6 additions & 2 deletions libraries/lib-stretching-sequence/ClipSegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
#include "ClipTimeAndPitchSource.h"
#include "Observer.h"
#include "PlaybackDirection.h"
#include <atomic>
#include <memory>
#include <mutex>

class ClipInterface;
class TimeAndPitchInterface;
Expand All @@ -31,6 +31,7 @@ class STRETCHING_SEQUENCE_API ClipSegment final : public AudioSegment
{
public:
ClipSegment(ClipInterface&, double durationToDiscard, PlaybackDirection);
~ClipSegment() override;

// AudioSegment
size_t GetFloats(float* const* buffers, size_t numSamples) override;
Expand All @@ -41,7 +42,10 @@ class STRETCHING_SEQUENCE_API ClipSegment final : public AudioSegment
const sampleCount mTotalNumSamplesToProduce;
sampleCount mTotalNumSamplesProduced = 0;
ClipTimeAndPitchSource mSource;
std::mutex mStretcherMutex;
bool mPreserveFormants;
int mCentShift;
std::atomic<bool> mUpdateFormantPreservation = false;
std::atomic<bool> mUpdateCentShift = false;
// Careful that this guy is constructed after `mSource`, which it refers to
// in its ctor.
// todo(mhodgkinson) make this safe.
Expand Down
5 changes: 5 additions & 0 deletions libraries/lib-stretching-sequence/ClipTimeAndPitchSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ void ClipTimeAndPitchSource::Pull(
// become a reasonably small value again :)
-sampleCount { numSamplesToRead };
}
else
{
for (auto i = 0u; i < mClip.GetWidth(); ++i)
std::fill(buffers[i], buffers[i] + samplesPerChannel, 0.f);
}
}

size_t ClipTimeAndPitchSource::GetWidth() const
Expand Down

0 comments on commit 7baedbd

Please sign in to comment.