Skip to content

Commit

Permalink
added chorus
Browse files Browse the repository at this point in the history
  • Loading branch information
ozguronsoy committed Nov 8, 2024
1 parent 34b987e commit fa5924c
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 9 deletions.
2 changes: 1 addition & 1 deletion HephAudio/HeaderFiles/AudioEffects/AudioEffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace HephAudio
{
protected:
/**
* number of threads that will be used, 1 by default.
* number of threads that will be used.
*/
size_t threadCount;

Expand Down
57 changes: 57 additions & 0 deletions HephAudio/HeaderFiles/AudioEffects/Chorus.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once
#include "HephAudioShared.h"
#include "Flanger.h"

/** @file */

namespace HephAudio
{
/**
* @brief delays the audio data and changes its pitch periodically.
* Then mixes the result with the input signal.
*
* @note this is a non-causal effect.
*/
class Chorus : public Flanger
{
protected:
/**
* maximum pitch change in terms of semitones.
*/
double extent;

public:
/** @copydoc default_constructor */
Chorus();

/**
* @copydoc Flanger(double, double, double, const Oscillator&)
*
* @param extent @copydetails extent
*/
Chorus(double depth, double constantDelay, double variableDelay, double extent, const Oscillator& lfo);

/** @copydoc destructor */
virtual ~Chorus() = default;

virtual std::string Name() const override;
virtual size_t CalculateRequiredFrameCount(size_t outputFrameCount, const AudioFormatInfo& formatInfo) const override;

/**
* gets the @copydetails extent.
*
*/
virtual double GetExtent() const;

/**
* sets extent.
*
* @param extent @copydetails extent
*
*/
virtual void SetExtent(double extent);

protected:
virtual void ProcessST(const AudioBuffer& inputBuffer, AudioBuffer& outputBuffer, size_t startIndex, size_t frameCount) override;
};
}
1 change: 0 additions & 1 deletion HephAudio/HeaderFiles/AudioEffects/Vibrato.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ namespace HephAudio
virtual ~Vibrato() = default;

virtual std::string Name() const override;

virtual size_t CalculateRequiredFrameCount(size_t outputFrameCount, const AudioFormatInfo& formatInfo) const override;

/**
Expand Down
2 changes: 2 additions & 0 deletions HephAudio/HephAudio.vcxitems
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<ProjectCapability Include="SourceItemsFromImports" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(MSBuildThisFileDirectory)HeaderFiles\AudioEffects\Chorus.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)HeaderFiles\AudioEffects\Flanger.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)HeaderFiles\AudioEffects\DoubleBufferedAudioEffect.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)HeaderFiles\AudioEffects\AudioEffect.h" />
Expand Down Expand Up @@ -92,6 +93,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)HeaderFiles\AudioEffects\Vibrato.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(MSBuildThisFileDirectory)SourceFiles\AudioEffects\Chorus.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)SourceFiles\AudioEffects\Flanger.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)SourceFiles\AudioEffects\DoubleBufferedAudioEffect.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)SourceFiles\AudioEffects\ModulationEffect.cpp" />
Expand Down
2 changes: 2 additions & 0 deletions HephAudio/HephAudio.vcxitems.filters
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)HeaderFiles\AudioEffects\Vibrato.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)HeaderFiles\AudioEffects\DoubleBufferedAudioEffect.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)HeaderFiles\AudioEffects\Flanger.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)HeaderFiles\AudioEffects\Chorus.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(MSBuildThisFileDirectory)SourceFiles\AudioProcessor.cpp">
Expand Down Expand Up @@ -404,5 +405,6 @@
<ClCompile Include="$(MSBuildThisFileDirectory)SourceFiles\AudioEffects\Vibrato.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)SourceFiles\AudioEffects\DoubleBufferedAudioEffect.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)SourceFiles\AudioEffects\Flanger.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)SourceFiles\AudioEffects\Chorus.cpp" />
</ItemGroup>
</Project>
82 changes: 82 additions & 0 deletions HephAudio/SourceFiles/AudioEffects/Chorus.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include "AudioEffects/Chorus.h"
#include "Exceptions/InvalidArgumentException.h"

using namespace Heph;

namespace HephAudio
{
Chorus::Chorus() : Flanger(), extent(1.0) {}

Chorus::Chorus(double depth, double constantDelay, double variableDelay, double extent, const Oscillator& lfo)
: Flanger(depth, constantDelay, variableDelay, lfo), extent(1.0)
{
this->SetExtent(extent);
}

std::string Chorus::Name() const
{
return "Chorus";
}

size_t Chorus::CalculateRequiredFrameCount(size_t outputFrameCount, const AudioFormatInfo& formatInfo) const
{
const double peakAmplitude = this->lfoBuffer.AbsMax();
const double extent_sample = fabs(formatInfo.sampleRate * (pow(2, HephAudio::SemitoneToOctave(this->extent)) - 1.0));
return outputFrameCount + peakAmplitude * extent_sample + 1;
}

double Chorus::GetExtent() const
{
return this->extent;
}

void Chorus::SetExtent(double extent)
{
if (extent < 0)
{
HEPH_RAISE_AND_THROW_EXCEPTION(this, InvalidArgumentException(HEPH_FUNC, "extent cannot be negative."));
}

this->extent = extent;
}

void Chorus::ProcessST(const AudioBuffer& inputBuffer, AudioBuffer& outputBuffer, size_t startIndex, size_t frameCount)
{
const size_t endIndex = startIndex + frameCount;
const AudioFormatInfo& formatInfo = inputBuffer.FormatInfo();
const double extent_sample = formatInfo.sampleRate * (pow(2, HephAudio::SemitoneToOctave(this->extent)) - 1.0);
const size_t constantDelay_sample = ceil(this->constantDelay * 1e-3 * formatInfo.sampleRate);
const size_t variableDelay_sample = ceil(this->variableDelay * 1e-3 * formatInfo.sampleRate);

for (size_t i = startIndex; i < endIndex; ++i)
{
const double lfoSample = this->lfoBuffer[(i + this->lfoIndex) % this->lfoBuffer.Size()];
const double delaySampleIndex = i - round(lfoSample * variableDelay_sample + constantDelay_sample);
double resampleIndex = delaySampleIndex + lfoSample * extent_sample;
const double resampleFactor = fabs(resampleIndex - floor(resampleIndex));

resampleIndex = floor(resampleIndex);

for (size_t j = 0; j < formatInfo.channelLayout.count; ++j)
{
heph_audio_sample_t wetSample = 0;
if (resampleIndex >= 0)
{
if (resampleIndex + 1 < inputBuffer.FrameCount())
{
wetSample = inputBuffer[resampleIndex][j] * (1.0 - resampleFactor) + inputBuffer[resampleIndex + 1.0][j] * resampleFactor;
}
}
else
{
wetSample = this->pastSamples[resampleIndex + this->pastSamples.FrameCount()][j] * (1.0 - resampleFactor);
wetSample += (resampleIndex == -1)
? (inputBuffer[0][j] * resampleFactor)
: (this->pastSamples[resampleIndex + this->pastSamples.FrameCount() + 1.0][j] * resampleFactor);
}

outputBuffer[i][j] = wetSample * this->depth + inputBuffer[i][j] * (1.0 - this->depth);
}
}
}
}
18 changes: 11 additions & 7 deletions HephAudio/SourceFiles/AudioEffects/Flanger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ namespace HephAudio
Flanger::Flanger() : ModulationEffect(), constantDelay(0), variableDelay(0) {}

Flanger::Flanger(double depth, double constantDelay, double variableDelay, const Oscillator& lfo)
: ModulationEffect(depth, lfo), constantDelay(constantDelay), variableDelay(variableDelay) {}
: ModulationEffect(depth, lfo), constantDelay(0), variableDelay(0)
{
this->SetConstantDelay(constantDelay);
this->SetVariableDelay(variableDelay);
}

std::string Flanger::Name() const
{
Expand Down Expand Up @@ -40,9 +44,9 @@ namespace HephAudio
}

AudioBuffer tempBuffer = this->pastSamples;
if (buffer.FrameCount() >= maxDelay_sample)
if (frameCount >= maxDelay_sample)
{
const size_t startIndex = buffer.FrameCount() - maxDelay_sample;
const size_t startIndex = frameCount - maxDelay_sample;
for (size_t i = 0; i < maxDelay_sample; ++i)
{
for (size_t j = 0; j < formatInfo.channelLayout.count; ++j)
Expand All @@ -53,8 +57,8 @@ namespace HephAudio
}
else
{
const size_t startIndex = maxDelay_sample - buffer.FrameCount();
tempBuffer <<= buffer.FrameCount();
const size_t startIndex = maxDelay_sample - frameCount;
tempBuffer <<= frameCount;
for (size_t i = startIndex; i < maxDelay_sample; ++i)
{
for (size_t j = 0; j < formatInfo.channelLayout.count; ++j)
Expand Down Expand Up @@ -103,8 +107,8 @@ namespace HephAudio
{
const size_t endIndex = startIndex + frameCount;
const AudioFormatInfo& formatInfo = inputBuffer.FormatInfo();
const double constantDelay_sample = ceil(this->constantDelay * 1e-3 * formatInfo.sampleRate);
const double variableDelay_sample = ceil(this->variableDelay * 1e-3 * formatInfo.sampleRate);
const size_t constantDelay_sample = ceil(this->constantDelay * 1e-3 * formatInfo.sampleRate);
const size_t variableDelay_sample = ceil(this->variableDelay * 1e-3 * formatInfo.sampleRate);

for (size_t i = startIndex; i < endIndex; ++i)
{
Expand Down

0 comments on commit fa5924c

Please sign in to comment.