-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathWaveGen.h
More file actions
150 lines (114 loc) · 3.53 KB
/
Copy pathWaveGen.h
File metadata and controls
150 lines (114 loc) · 3.53 KB
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright (C) 2022-2025 Theo Niessink <theo@taletn.com>
// This work is free. You can redistribute it and/or modify it under the
// terms of the Do What The Fuck You Want To Public License, Version 2,
// as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.
#pragma once
#include "WaveTbl.h"
#include <assert.h>
#include "WDL/wdltypes.h"
namespace TG101 {
class WaveGen
{
public:
inline void Reset() { mFlags = 0; }
void LoadWave(const WaveTblHeader* header, const float* samplePtr, double samplePeriod);
inline void SetEGAttackRate(const int rate)
{
assert(rate >= 0 && rate <= 15);
mAttackRate = rate;
}
inline void SetEGDecay1Rate(const int rate)
{
assert(rate >= 0 && rate <= 15);
mDecay1Rate = rate;
}
inline void SetEGDecay2Rate(const int rate)
{
assert(rate >= 0 && rate <= 15);
mDecay2Rate = rate;
}
void SetEGDecayLevel(int level);
inline void SetEGReleaseRate(const int rate)
{
assert(rate >= 0 && rate <= 15);
mReleaseRate = rate;
}
inline void SetEGRateScale(const int scale)
{
assert(scale >= 0 && scale <= 15);
mEGRateScale = scale;
}
void SetPitch(int oct, int fNumber);
void SetLFOSpeed(int speed, double samplePeriod);
void SetVibratoDepth(int depth);
void SetTremoloDepth(int depth);
void SetTotalLevel(int level, bool smooth);
void SetPan(int pan);
void SetReverbDepth(int depth);
void EnableLFO(const bool enable)
{
const int flags = mFlags & ~kFlagLFO;
mFlags = (enable ? kFlagLFO : 0) | flags;
}
void KeyOn(double samplePeriod);
void KeyOff(double samplePeriod);
inline bool IsLFOEnabled() const { return !!(mFlags & kFlagLFO); }
inline bool IsKeyOn() const { return !!(mFlags & kFlagKeyOn); }
inline bool IsActive() const { return !!(mFlags & kFlagActive); }
// Stores dry output in stereo[], and returns mono reverb send.
float GetSample(float stereo[2], double samplePeriod);
private:
enum EFlags
{
kFlagLFO = 1,
kFlagVibrato = 2,
kFlagLoop = 4,
kFlagTremolo = 8,
kFlagLevelSmooth = 16,
kFlagKeyOn = 64,
kFlagActive = 128
};
enum EEGState
{
kEGStateAttack = 0,
kEGStateDecay1,
kEGStateDecay2,
kEGStateRelease
};
template <class T> struct FloatOsc
{
T mPhase, mPeriod;
};
double GetLFOPhase();
double GetVibrato(double phase) const;
float ProcessEG(const double lfoPhase, double samplePeriod);
void SmoothTotalLevel(double level, double samplePeriod);
void SetEGDecayRate(int decay, double level, double samplePeriod);
int ApplyEGRateScale(int rate) const;
unsigned char mFlags;
unsigned char mEGState;
unsigned char mAttackRate, mDecay1Rate, mDecay2Rate, mReleaseRate;
unsigned char mEGRateScale;
signed char mKeyRateScale;
FloatOsc<double> WDL_FIXALIGN mLFO, mSamplePos;
double WDL_FIXALIGN mVibratoDepth[2];
double WDL_FIXALIGN mSampleLoop, mSampleLen;
const float* mSamplePtr;
double WDL_FIXALIGN mEGLevel, mEGRate;
double WDL_FIXALIGN mDecayLevel;
double WDL_FIXALIGN mTremoloDepth;
double WDL_FIXALIGN mTotalLevel, mLevelDirect;
float mPanL, mPanR;
float mReverbDepth;
static const double mLFOSpeedTbl[8];
static const double mVibratoDepthTbl[8][2];
static const float mTremoloDepthTbl[8];
static const float mEGLevelTbl[18];
static const unsigned char mPanMixTbl[16];
static const float mPanGainTbl[8];
static const float mReverbDepthTbl[9];
static const double mAttackRateTbl[57];
static const double mDecayRateTbl[57];
}
WDL_FIXALIGN;
} // namespace TG101