-
Notifications
You must be signed in to change notification settings - Fork 182
/
FormSwep.cpp
136 lines (113 loc) · 3.56 KB
/
FormSwep.cpp
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
/***************************************************/
/*! \class FormSwep
\brief STK sweepable formant filter class.
This class implements a formant (resonance) which can be "swept"
over time from one frequency setting to another. It provides
methods for controlling the sweep rate and target frequency.
by Perry R. Cook and Gary P. Scavone, 1995--2023.
*/
/***************************************************/
#include "FormSwep.h"
#include <cmath>
namespace stk {
FormSwep :: FormSwep( void )
{
frequency_ = 0.0;
radius_ = 0.0;
targetGain_ = 1.0;
targetFrequency_ = 0.0;
targetRadius_ = 0.0;
deltaGain_ = 0.0;
deltaFrequency_ = 0.0;
deltaRadius_ = 0.0;
sweepState_ = 0.0;
sweepRate_ = 0.002;
dirty_ = false;
b_.resize( 3, 0.0 );
a_.resize( 3, 0.0 );
a_[0] = 1.0;
inputs_.resize( 3, 1, 0.0 );
outputs_.resize( 3, 1, 0.0 );
Stk::addSampleRateAlert( this );
}
FormSwep :: ~FormSwep()
{
Stk::removeSampleRateAlert( this );
}
void FormSwep :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
{
if ( !ignoreSampleRateChange_ ) {
oStream_ << "FormSwep::sampleRateChanged: you may need to recompute filter coefficients!";
handleError( StkError::WARNING );
}
}
void FormSwep :: setResonance( StkFloat frequency, StkFloat radius )
{
#if defined(_STK_DEBUG_)
if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
oStream_ << "FormSwep::setResonance: frequency argument (" << frequency << ") is out of range!";
handleError( StkError::WARNING ); return;
}
if ( radius < 0.0 || radius >= 1.0 ) {
oStream_ << "FormSwep::setResonance: radius argument (" << radius << ") is out of range!";
handleError( StkError::WARNING ); return;
}
#endif
radius_ = radius;
frequency_ = frequency;
a_[2] = radius * radius;
a_[1] = -2.0 * radius * cos( TWO_PI * frequency / Stk::sampleRate() );
// Use zeros at +- 1 and normalize the filter peak gain.
b_[0] = 0.5 - 0.5 * a_[2];
b_[1] = 0.0;
b_[2] = -b_[0];
}
void FormSwep :: setStates( StkFloat frequency, StkFloat radius, StkFloat gain )
{
dirty_ = false;
if ( frequency_ != frequency || radius_ != radius )
this->setResonance( frequency, radius );
gain_ = gain;
targetFrequency_ = frequency;
targetRadius_ = radius;
targetGain_ = gain;
}
void FormSwep :: setTargets( StkFloat frequency, StkFloat radius, StkFloat gain )
{
if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
oStream_ << "FormSwep::setTargets: frequency argument (" << frequency << ") is out of range!";
handleError( StkError::WARNING ); return;
}
if ( radius < 0.0 || radius >= 1.0 ) {
oStream_ << "FormSwep::setTargets: radius argument (" << radius << ") is out of range!";
handleError( StkError::WARNING ); return;
}
dirty_ = true;
startFrequency_ = frequency_;
startRadius_ = radius_;
startGain_ = gain_;
targetFrequency_ = frequency;
targetRadius_ = radius;
targetGain_ = gain;
deltaFrequency_ = frequency - frequency_;
deltaRadius_ = radius - radius_;
deltaGain_ = gain - gain_;
sweepState_ = 0.0;
}
void FormSwep :: setSweepRate( StkFloat rate )
{
if ( rate < 0.0 || rate > 1.0 ) {
oStream_ << "FormSwep::setSweepRate: argument (" << rate << ") is out of range!";
handleError( StkError::WARNING ); return;
}
sweepRate_ = rate;
}
void FormSwep :: setSweepTime( StkFloat time )
{
if ( time <= 0.0 ) {
oStream_ << "FormSwep::setSweepTime: argument (" << time << ") must be > 0.0!";
handleError( StkError::WARNING ); return;
}
this->setSweepRate( 1.0 / ( time * Stk::sampleRate() ) );
}
} // stk namespace