AME
ame_Oscillator.hpp
Go to the documentation of this file.
1
9#pragma once
10
11#include "ame_Math.hpp"
12#include "ame_Util.hpp"
13
14#include <algorithm>
15#include <array>
16#include <atomic>
17#include <cassert>
18#include <cmath>
19#include <concepts>
20#include <numeric>
21#include <span>
22
23namespace ame
24{
32template <std::floating_point FloatType, size_t NumSamples, class Function>
33constexpr std::array<FloatType, NumSamples> makeWaveTable (Function func)
34{
35 std::array<FloatType, NumSamples> ar;
36 std::iota (ar.begin(), ar.end(), 0);
37 std::for_each (ar.begin(), ar.end(), [] (auto& x)
38 { x = x / (NumSamples - 1); }); // ar: 0~1が順に並んだ配列
39 std::for_each (ar.begin(), ar.end(), func);
40 return ar;
41}
42
48template <std::floating_point FloatType, size_t N>
49constexpr std::array<FloatType, N> makeSineTable()
50{
51 auto f = [] (auto& x)
52 {
53 x = ame::sin (x * ame::twoPi<float>);
54 };
55 return ame::makeWaveTable<FloatType, N> (f);
56}
57
62template <std::floating_point FloatType, size_t N>
64{
65 using FloatTypeBase = typename std::remove_cv<FloatType>::type;
66
67public:
68 explicit WavetableOscillator (std::span<FloatType, N> wavetable, const FloatTypeBase sampleRate)
69 : wavetable (wavetable)
70 {
71 tableIndex.changeLength (wavetable.size());
72 setSampleRate (sampleRate);
73 }
74 ~WavetableOscillator() = default;
75
79 void setSampleRate (const FloatTypeBase sampleRate)
80 {
81 samplingPeriod = 1.0f / sampleRate;
82 }
83
87 void setFrequency (const FloatTypeBase freq) noexcept
88 {
89 tableIndexIncrement = freq * tableIndex.getLength() * samplingPeriod;
90 }
91
95 void setWavetable (std::span<FloatType, N> newWavetable)
96 {
97 assert (! newWavetable.empty());
98 wavetable = newWavetable;
99 tableIndex.changeLength (wavetable.size());
100 }
101
105 FloatTypeBase nextSample() noexcept
106 {
107 const uint32_t aIndex = std::floor (tableIndex.get());
108 const uint32_t bIndex = std::floor (tableIndex.get (1));
109 const auto t = tableIndex.get() - aIndex;
110 const auto a = wavetable[aIndex];
111 const auto b = wavetable[bIndex];
112
113 tableIndex += tableIndexIncrement;
114 return std::lerp (a, b, t);
115 }
116
117private:
118 std::span<FloatType, N> wavetable;
119 Wrap<FloatTypeBase> tableIndex {};
120 FloatTypeBase samplingPeriod {};
121 std::atomic<FloatTypeBase> tableIndexIncrement {};
122};
123
127template <std::floating_point FloatType>
129{
130 static_assert (! std::is_const<FloatType>::value, "FloatType is must NOT be const.");
131
132public:
137 SineOscillator (FloatType sampleRate) noexcept
138 {
139 setSampleRate (sampleRate);
140 }
141 ~SineOscillator() = default;
142
146 void setSampleRate (FloatType sampleRate)
147 {
148 samplingPeriod = FloatType (1.0) / sampleRate;
149 }
150
154 void setFrequency (FloatType freq) noexcept
155 {
156 phaseIncrement = freq * twoPi<FloatType> * samplingPeriod;
157 }
158
162 float nextSample() noexcept
163 {
164 const auto p = phase.load();
165 phase = addModulo2Pi (p, phaseIncrement.load());
166 return ame::sin (p);
167 }
168
172 void resetPhase (FloatType newPhase = 0.0f)
173 {
174 assert (0 <= newPhase && newPhase <= twoPi<FloatType>);
175 if (FloatType (0.0) <= newPhase && newPhase <= twoPi<FloatType>)
176 {
177 phase = newPhase;
178 }
179 }
180
181private:
182 FloatType samplingPeriod; // 1 /sampleRate
183 std::atomic<FloatType> phaseIncrement {};
184 std::atomic<FloatType> phase {}; //<[0, 2pi]
185
186 // Disallow copy constructor and assignment
187 SineOscillator (const SineOscillator&) = delete;
188 SineOscillator& operator= (const SineOscillator&) = delete;
189};
190} // namespace ame
Math functions.
constexpr float sin(float x)
sin for float
Definition: ame_Math.hpp:61
constexpr std::array< FloatType, N > makeSineTable()
Sine wave wavetable generator.
Definition: ame_Oscillator.hpp:49
constexpr std::array< FloatType, NumSamples > makeWaveTable(Function func)
Wavetable generator.
Definition: ame_Oscillator.hpp:33
Some utilities functions.
constexpr FloatType addModulo2Pi(FloatType phase, FloatType increment) noexcept
Increment the phase and returns in the range of 0~2pi.
Definition: ame_Util.hpp:43
Sine wave oscillator.
Definition: ame_Oscillator.hpp:129
void setFrequency(FloatType freq) noexcept
Set the sine wave frequency.
Definition: ame_Oscillator.hpp:154
void setSampleRate(FloatType sampleRate)
Set sampling rate.
Definition: ame_Oscillator.hpp:146
float nextSample() noexcept
Generate single sample.
Definition: ame_Oscillator.hpp:162
SineOscillator(FloatType sampleRate) noexcept
Create sine wave oscillator instance.
Definition: ame_Oscillator.hpp:137
void resetPhase(FloatType newPhase=0.0f)
Reset the phase to any value.
Definition: ame_Oscillator.hpp:172
Wavetable oscillator.
Definition: ame_Oscillator.hpp:64
void setSampleRate(const FloatTypeBase sampleRate)
Set sampling rate.
Definition: ame_Oscillator.hpp:79
FloatTypeBase nextSample() noexcept
Generate single sample.
Definition: ame_Oscillator.hpp:105
void setFrequency(const FloatTypeBase freq) noexcept
Set the frequency.
Definition: ame_Oscillator.hpp:87
void setWavetable(std::span< FloatType, N > newWavetable)
Set the wavetable.
Definition: ame_Oscillator.hpp:95
A number to wrap between 0~length.
Definition: ame_Util.hpp:254