11namespace tracktion {
inline namespace engine
17 return {
"Sin",
"Triangle",
"Saw Up",
"Saw Down",
"Square",
"Noise" };
21ToneGeneratorPlugin::ToneGeneratorPlugin (PluginCreationInfo info)
24 initialiseOscilators();
26 auto um = getUndoManager();
28 oscType.referTo (state, IDs::oscType, um,
static_cast<float> (OscType::sin));
29 bandLimit.referTo (state, IDs::bandLimit, um, 0.0f);
30 frequency.referTo (state, IDs::frequency, um, 220.0f);
31 level.referTo (state, IDs::level, um, 1.0f);
33 oscTypeParam = createDiscreteParameter (*
this,
"oscType",
TRANS(
"OSC Type"), { 0.0f, (
float) getOscTypeNames().size() - 1 }, oscType, getOscTypeNames());
34 bandLimitParam = createDiscreteParameter (*
this,
"bandLimit",
TRANS(
"Band Limit"), { 0.0f, 1.0f }, bandLimit, {
NEEDS_TRANS(
"Aliased"),
NEEDS_TRANS(
"Band Limited") });
35 frequencyParam = createSuffixedParameter (*
this,
"frequency",
TRANS(
"Frequency"), { 1.0f, 22050.0f }, 1000.0f, frequency, {});
36 levelParam = createSuffixedParameter (*
this,
"level",
TRANS(
"Level"), { 0.00001f, 1.0f }, 0.5f, level, {});
38 addAutomatableParameter (oscTypeParam);
39 addAutomatableParameter (bandLimitParam);
40 addAutomatableParameter (frequencyParam);
41 addAutomatableParameter (levelParam);
44ToneGeneratorPlugin::~ToneGeneratorPlugin()
46 notifyListenersOfDeletion();
49const char* ToneGeneratorPlugin::xmlTypeName =
"toneGenerator";
53 scratch.setSize (1, info.blockSizeSamples);
54 auto samplesPerBlock =
static_cast<uint32_t> (info.blockSizeSamples);
56 sine.prepare ({ sampleRate,
static_cast<uint32_t> (samplesPerBlock), 1 });
57 triangle.prepare ({ sampleRate,
static_cast<uint32_t> (samplesPerBlock), 1 });
58 sawUp.prepare ({ sampleRate,
static_cast<uint32_t> (samplesPerBlock), 1 });
59 sawDown.prepare ({ sampleRate,
static_cast<uint32_t> (samplesPerBlock), 1 });
60 square.prepare ({ sampleRate,
static_cast<uint32_t> (samplesPerBlock), 1 });
61 noise.prepare ({ sampleRate,
static_cast<uint32_t> (samplesPerBlock), 1 });
64void ToneGeneratorPlugin::deinitialise()
74 float gain = levelParam->getCurrentValue();
83 scratch.setSize (1, numSamples,
false,
false,
true);
86 float freq = frequencyParam->getCurrentValue();
87 sine.setFrequency (freq);
88 triangle.setFrequency (freq);
89 sawUp.setFrequency (freq);
90 sawDown.setFrequency (freq);
91 square.setFrequency (freq);
97 switch (getTypedParamValue<OscType> (*oscTypeParam))
99 case OscType::sin: sine.process (context);
break;
100 case OscType::triangle: triangle.process (context);
break;
101 case OscType::sawUp: sawUp.process (context);
break;
102 case OscType::sawDown: sawDown.process (context);
break;
103 case OscType::square: square.process (context);
break;
104 case OscType::noise: noise.process (context);
break;
107 scratch.applyGain (gain);
113void ToneGeneratorPlugin::restorePluginStateFromValueTree (
const juce::ValueTree& v)
115 copyPropertiesToCachedValues (v, oscType, bandLimit, frequency, level);
117 for (
auto p : getAutomatableParameters())
118 p->updateFromAttachedValue();
122namespace ToneGenHelpers
124 inline int oddEven (
int x)
126 return (x % 2 == 0) ? 1 : -1;
130void ToneGeneratorPlugin::initialiseOscilators()
132 auto sineFunc = [&] (
float in) ->
float
137 auto triangleFunc = [&] (
float in) ->
float
139 if (bandLimitOsc.load())
141 const double f = frequencyParam->getCurrentValue();
142 const double sr = sampleRate;
147 while (f * k < sr / 2)
149 sum +=
std::pow (-1, (k - 1) / 2.0f) / (k * k) * sin (k * in);
159 auto sawUpFunc = [&] (
float in) ->
float
161 if (bandLimitOsc.load())
163 const double f = frequencyParam->getCurrentValue();
164 const double sr = sampleRate;
169 while (f * k < sr / 2)
171 sum += ToneGenHelpers::oddEven (k) *
std::sin (k * in) / k;
181 auto sawDownFunc = [&] (
float in) ->
float
183 if (bandLimitOsc.load())
185 const double f = frequencyParam->getCurrentValue();
186 const double sr = sampleRate;
191 while (f * k < sr / 2)
193 sum += ToneGenHelpers::oddEven (k) *
std::sin (k * in) / k;
203 auto squareFunc = [&] (
float in) ->
float
205 if (bandLimitOsc.load())
207 const double f = frequencyParam->getCurrentValue();
208 const double sr = sampleRate;
213 while (f * (2 * i - 1) < sr / 2)
215 sum +=
std::sin ((2 * i - 1) * in) / ((2 * i - 1));
222 return in < 0 ? -1.0f : 1.0f;
225 auto noiseFunc = [&] (
float) ->
float
227 const float mean = 0.0f;
228 const float stddev = 0.1f;
233 return dist (generator);
236 sine.initialise (sineFunc);
237 triangle.initialise (triangleFunc);
238 sawUp.initialise (sawUpFunc);
239 sawDown.initialise (sawDownFunc);
240 square.initialise (squareFunc);
241 noise.initialise (noiseFunc);
int getNumChannels() const noexcept
void copyFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples) noexcept
#define TRANS(stringLiteral)
#define NEEDS_TRANS(stringLiteral)
bool isWithin(Type a, Type b, Type tolerance) noexcept
constexpr NumericType square(NumericType n) noexcept
bool getBoolParamValue(const AutomatableParameter &ap)
Returns a bool version of an AutomatableParameter.
Passed into Plugins when they are being initialised, to give them useful contextual information that ...
The context passed to plugin render methods to provide it with buffers to fill.
int bufferNumSamples
The number of samples to write into the audio buffer.
juce::AudioBuffer< float > * destBuffer
The target audio buffer which needs to be filled.
int bufferStartSample
The index of the start point in the audio buffer from which data must be written.