1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#pragma once
class SineWave
{
struct wave
{
float amp{}, freq{}, phase{}, dc{};
};
public:
SineWave() {}
template<typename _ty1, typename _ty2>
SineWave(_ty1 numChannels, _ty2 samplingRate) : _channel(unsigned(numChannels)), _sr(float(samplingRate)) {}
template<typename _ty1, typename _ty2>
inline void Initialize(_ty1 numChannels, _ty2 samplingRate)
{
_channel.resize(unsigned(numChannels));
_sr = unsigned(samplingRate);
}
template<typename _ty1>
inline void SetChannel(_ty1 channel, float freq, float amplitude = 0.f, float dc = 0.f, float phase = 0.f)
{
_channel[unsigned(channel)].amp = amplitude;
_channel[unsigned(channel)].freq = freq;
_channel[unsigned(channel)].phase = phase;
_channel[unsigned(channel)].dc = dc;
}
template<typename _ty1>
void FillFrames(void* buffer, _ty1 numFrames)
{
auto fb = reinterpret_cast<float*>(buffer);
for (unsigned i = 0; i < unsigned(numFrames); ++i)
{
for (unsigned ch = 0; ch < _channel.size(); ++ch)
{
fb[i * _channel.size() + ch] = Calculate(ch);
}
}
}
protected:
float Calculate(unsigned ch)
{
auto& w = _channel[ch];
float sample = w.amp * sinf(w.phase) + w.dc;
w.phase += 2 * float(M_PI) * w.freq / _sr;
w.phase = fmodf(w.phase, 2 * float(M_PI));
return sample;
}
private:
std::vector<wave> _channel;
float _sr{};
};
|