Skip to content

Commit

Permalink
fix: Template type of const float causes a compile error.
Browse files Browse the repository at this point in the history
  • Loading branch information
AkiyukiOkayasu committed Dec 18, 2021
1 parent 049db14 commit 15b951d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 21 deletions.
51 changes: 30 additions & 21 deletions include/ame_Oscillator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <array>
#include <atomic>
#include <cassert>
#include <cmath>
#include <numeric>
#include <span>
Expand Down Expand Up @@ -57,24 +58,24 @@ constexpr std::array<float, N> makeSineTable()
@tparam numSamples
@todo 動作確認、単体テスト、doxygenコメントの英語化
*/
template <typename FloatType>
template <typename FloatType, size_t N>
class WavetableOscillator
{
static_assert (std::is_floating_point<FloatType>::value, "FloatType is must be floating point type.");

public:
WavetableOscillator (std::span<FloatType> wavetable, const FloatType sampleRate)
explicit WavetableOscillator (std::span<FloatType, N> wavetable, const float sampleRate)
: wavetable (wavetable)
{
tableIndex.changeLength (wavetable.size());
changeSampleRate (sampleRate);
setSampleRate (sampleRate);
}
~WavetableOscillator() = default;

/** Change sampling rate.
/** Set sampling rate.
@param sampleRate new sampling rate in Hz
*/
void changeSampleRate (const FloatType sampleRate)
void setSampleRate (const float sampleRate)
{
samplingPeriod = 1.0f / sampleRate;
}
Expand All @@ -87,36 +88,36 @@ class WavetableOscillator
tableIndexIncrement = freq * tableIndex.getLength() * samplingPeriod;
}

/** ウェーブテーブルのポインタ設定
@param wavetablePtr
@param numSamples number of wavetable samples
/** Set the wavetable.
@param newWavetable
*/
void resetWavetable (const FloatType* wavetablePtr, const uint32_t numSamples)
void setWavetable (std::span<FloatType, N> newWavetable)
{
wavetable = wavetablePtr;
tableIndex.changeLength (numSamples);
assert (! newWavetable.empty());
wavetable = newWavetable;
tableIndex.changeLength (wavetable.size());
}

/** Generate single sample
@return generated latest sample
*/
FloatType nextSample() noexcept
{
tableIndex += tableIndexIncrement;

const uint32_t aIndex = std::floor (tableIndex.get());
const uint32_t bIndex = std::floor (tableIndex.get (1));
const float t = tableIndex.get() - aIndex;
const auto a = wavetable[aIndex];
const auto b = wavetable[bIndex];

tableIndex += tableIndexIncrement;
return std::lerp (a, b, t);
}

private:
std::span<FloatType> wavetable;
std::span<FloatType, N> wavetable;
Wrap<float> tableIndex {};
FloatType samplingPeriod {};
std::atomic<FloatType> tableIndexIncrement {};
float samplingPeriod {};
std::atomic<float> tableIndexIncrement {};
};

/** Sine wave oscillator.
Expand All @@ -129,13 +130,20 @@ class SineOscillator
@param sampleRate The sample rate that will be used for calclate the oscillator phase increment.
@param frequency Initial frequency
*/
SineOscillator (const float sampleRate, const float frequency)
: samplingPeriod (1.0f / sampleRate)
SineOscillator (const float sampleRate)
{
setFrequency (frequency);
setSampleRate (sampleRate);
}
~SineOscillator() = default;

/** Set sampling rate.
@param sampleRate new sampling rate in Hz
*/
void setSampleRate (const float sampleRate)
{
samplingPeriod = 1.0f / sampleRate;
}

/** Set the sine wave frequency
@param freq frequency in Hz
*/
Expand All @@ -149,8 +157,9 @@ class SineOscillator
*/
float nextSample() noexcept
{
const float p = phase.load();
phase = addModulo2Pi (phase, phaseIncrement);
return ame::sin (phase);
return ame::sin (p);
}

/** Reset the phase to any value.
Expand All @@ -166,7 +175,7 @@ class SineOscillator
}

private:
const float samplingPeriod; // 1 /sampleRate
float samplingPeriod; // 1 /sampleRate
std::atomic<float> phaseIncrement {};
std::atomic<float> phase {}; //<[0, 2pi]

Expand Down
34 changes: 34 additions & 0 deletions test/test.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#include "ame_AudioBuffer.hpp"
#include "ame_Oscillator.hpp"
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "Tamtam.hpp"
#include "ame.hpp"
#include "sine440.hpp"

#include <doctest/doctest.h>
#include <iomanip>
#include <span>

using doctest::Approx;

Expand Down Expand Up @@ -150,6 +152,38 @@ TEST_CASE ("WaveTable")
REQUIRE (ar[3] == Approx (-1.0f).scale (1));
REQUIRE (ar[4] == Approx (0.0f).scale (1));
}

SUBCASE ("sinetable")
{
constexpr std::array<float, 512> wavetable = ame::makeSineTable<512>();
CHECK_EQ (wavetable[0], Approx (0.0f).scale (1));
CHECK_GT (wavetable[127], 0.97f);
CHECK_LT (wavetable[256], 0.03f);
CHECK_GT (wavetable[256], -0.03f);
CHECK_LT (wavetable[384], -0.97f);
CHECK_EQ (wavetable[511], Approx (0.0f).scale (1));
}
}

TEST_CASE ("Oscillator")
{
SUBCASE ("Wavetable")
{
constexpr std::array<float, 512> wavetable = ame::makeSineTable<512>();
ame::WavetableOscillator osc { std::span { wavetable }, 44100.0f };
CHECK_EQ (wavetable[0], Approx (0.0f).scale (1));
osc.setFrequency (440); //Hz
CHECK_EQ (osc.nextSample(), Approx (0.0f).scale (1));
CHECK_GT (osc.nextSample(), 0.001f);
CHECK_GT (osc.nextSample(), 0.01f);
CHECK_GT (osc.nextSample(), 0.1f);
}

SUBCASE ("SineWaveOsc")
{
ame::SineOscillator osc (44100.0f);
osc.setFrequency (440.0f);
}
}

TEST_CASE ("Filter")
Expand Down

0 comments on commit 15b951d

Please sign in to comment.