Skip to content

Commit

Permalink
Connect time stretch toggle with UI
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiashienzsch committed Jun 12, 2022
1 parent 11f012e commit 209f5ea
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 14 deletions.
37 changes: 25 additions & 12 deletions src/DSP/DJPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,30 @@ auto DJPlayer::prepareToPlay(int samplesPerBlockExpected, double sampleRate) ->
_stretcher = std::make_unique<RubberBand::RubberBandStretcher>(
sampleRate, 2, RubberBand::RubberBandStretcher::OptionProcessRealTime);

_stretcherBuffer.setSize(2, samplesPerBlockExpected);
_stretcherBuffer.setSize(2, 16);
}

auto DJPlayer::getNextAudioBlock(juce::AudioSourceChannelInfo const& bufferToFill) -> void
{
jassert(bufferToFill.buffer->getNumChannels() == 2);
jassert(bufferToFill.startSample == 0);

_stretcher->setTimeRatio(_stretchRatio.load());
_stretcherBuffer.setSize(2, bufferToFill.numSamples, false, false, true);

while (_stretcher->available() < bufferToFill.numSamples)
if (_timeStretchEnabled)
{
auto ctx = juce::AudioSourceChannelInfo{_stretcherBuffer};
_resampleSource.getNextAudioBlock(ctx);
_stretcher->process(ctx.buffer->getArrayOfReadPointers(), ctx.buffer->getNumSamples(), false);
_stretcher->setTimeRatio(1.0 / _stretchRatio.load());

while (_stretcher->available() < bufferToFill.numSamples)
{
auto ctx = juce::AudioSourceChannelInfo{_stretcherBuffer};
_resampleSource.getNextAudioBlock(ctx);
_stretcher->process(ctx.buffer->getArrayOfReadPointers(), ctx.numSamples, false);
}

_stretcher->retrieve(bufferToFill.buffer->getArrayOfWritePointers(), bufferToFill.buffer->getNumSamples());
return;
}

// _stretcher->process(bufferToFill.buffer->getArrayOfReadPointers(), bufferToFill.buffer->getNumSamples(), false);
_stretcher->retrieve(bufferToFill.buffer->getArrayOfWritePointers(), bufferToFill.buffer->getNumSamples());
_resampleSource.getNextAudioBlock(bufferToFill);
}

auto DJPlayer::releaseResources() -> void
Expand Down Expand Up @@ -73,8 +77,9 @@ auto DJPlayer::gain(double gain) -> void
auto DJPlayer::speed(double ratio) -> void
{
jassert(juce::isPositiveAndBelow(ratio, 4.0));
// _resampleSource.setResamplingRatio(ratio);
_stretchRatio.store(1.0 / ratio);

_stretchRatio.store(ratio);
_resampleSource.setResamplingRatio(_timeStretchEnabled.load() ? 1.0 : ratio);
}

auto DJPlayer::position(double posInSecs) -> void { _transportSource.setPosition(posInSecs); }
Expand All @@ -85,6 +90,14 @@ auto DJPlayer::positionRelative(double pos) -> void
position(_transportSource.getLengthInSeconds() * pos);
}

auto DJPlayer::timeStretch(bool isEnabled) -> void
{
_timeStretchEnabled.store(isEnabled);
_resampleSource.setResamplingRatio(isEnabled ? 1.0 : _stretchRatio.load());
}

auto DJPlayer::timeStretch() const noexcept -> bool { return _timeStretchEnabled.load(); }

auto DJPlayer::startPlayback() -> void { _transportSource.start(); }

auto DJPlayer::stopPlayback() -> void { _transportSource.stop(); }
Expand Down
3 changes: 3 additions & 0 deletions src/DSP/DJPlayer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ struct DJPlayer final : juce::AudioSource

auto gain(double gain) -> void;
auto speed(double ratio) -> void;
auto timeStretch(bool isEnabled) -> void;
auto timeStretch() const noexcept -> bool;

auto position(double posInSecs) -> void;
auto positionRelative(double pos) -> void;
Expand Down Expand Up @@ -65,6 +67,7 @@ struct DJPlayer final : juce::AudioSource
std::unique_ptr<RubberBand::RubberBandStretcher> _stretcher;
juce::AudioBuffer<float> _stretcherBuffer;
std::atomic<double> _stretchRatio{1.0};
std::atomic<bool> _timeStretchEnabled{false};

juce::ListenerList<Listener> _listeners;
};
Expand Down
6 changes: 4 additions & 2 deletions src/MainComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ MainComponent::MainComponent() : _djPlayer{_formatManager}
else { _djPlayer.startPlayback(); }
};

_sideBarLeft.onCueClicked = [this]() { _djPlayer.positionRelative(0.0); };
_sideBarRight.onTempoDeltaChanged = [this](double delta) { _djPlayer.speed((100.0 + delta) / 100.0); };
_sideBarLeft.onCueClicked = [this]() { _djPlayer.positionRelative(0.0); };
_sideBarRight.onTempoDeltaChanged = [this](double delta) { _djPlayer.speed((100.0 + delta) / 100.0); };
_sideBarRight.onTimeStretchToggled = [this](bool isEnabled) { _djPlayer.timeStretch(isEnabled); };

setSize(640, 800);
}
MainComponent::~MainComponent()
Expand Down
6 changes: 6 additions & 0 deletions src/UI/Section/SideBarRight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ SideBarRight::SideBarRight()
addAndMakeVisible(_tempoRange);
addAndMakeVisible(_tempo);

_warpButton.setClickingTogglesState(true);
_warpButton.onClick = [this]()
{
if (onTimeStretchToggled) { onTimeStretchToggled(_warpButton.getToggleState()); }
};

_tempoRange.setEditableText(false);
_tempoRange.setJustificationType(juce::Justification::centred);
_tempoRange.addItemList({"6%", "10%", "20%", "100%"}, 1);
Expand Down
1 change: 1 addition & 0 deletions src/UI/Section/SideBarRight.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct SideBarRight final : juce::Component
auto resized() -> void override;

std::function<void(double)> onTempoDeltaChanged{};
std::function<void(bool)> onTimeStretchToggled{};

private:
auto updateSpeedRange() -> void;
Expand Down

0 comments on commit 209f5ea

Please sign in to comment.