forked from thestk/stk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Mandolin.cpp
186 lines (157 loc) · 5.74 KB
/
Mandolin.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/***************************************************/
/*! \class Mandolin
\brief STK mandolin instrument model class.
This class uses two "twang" models and "commuted
synthesis" techniques to model a mandolin
instrument.
This is a digital waveguide model, making its
use possibly subject to patents held by Stanford
University, Yamaha, and others. Commuted
Synthesis, in particular, is covered by patents,
granted, pending, and/or applied-for. All are
assigned to the Board of Trustees, Stanford
University. For information, contact the Office
of Technology Licensing, Stanford University.
Control Change Numbers:
- Body Size = 2
- Pluck Position = 4
- String Sustain = 11
- String Detuning = 1
- Microphone Position = 128
by Perry R. Cook and Gary P. Scavone, 1995--2023.
*/
/***************************************************/
#include "Mandolin.h"
#include "SKINImsg.h"
namespace stk {
Mandolin :: Mandolin( StkFloat lowestFrequency )
{
if ( lowestFrequency <= 0.0 ) {
oStream_ << "Mandolin::Mandolin: argument is less than or equal to zero!";
handleError( StkError::FUNCTION_ARGUMENT );
}
// Concatenate the STK rawwave path to the rawwave files
soundfile_[0].openFile( (Stk::rawwavePath() + "mand1.raw").c_str(), true );
soundfile_[1].openFile( (Stk::rawwavePath() + "mand2.raw").c_str(), true );
soundfile_[2].openFile( (Stk::rawwavePath() + "mand3.raw").c_str(), true );
soundfile_[3].openFile( (Stk::rawwavePath() + "mand4.raw").c_str(), true );
soundfile_[4].openFile( (Stk::rawwavePath() + "mand5.raw").c_str(), true );
soundfile_[5].openFile( (Stk::rawwavePath() + "mand6.raw").c_str(), true );
soundfile_[6].openFile( (Stk::rawwavePath() + "mand7.raw").c_str(), true );
soundfile_[7].openFile( (Stk::rawwavePath() + "mand8.raw").c_str(), true );
soundfile_[8].openFile( (Stk::rawwavePath() + "mand9.raw").c_str(), true );
soundfile_[9].openFile( (Stk::rawwavePath() + "mand10.raw").c_str(), true );
soundfile_[10].openFile( (Stk::rawwavePath() + "mand11.raw").c_str(), true );
soundfile_[11].openFile( (Stk::rawwavePath() + "mand12.raw").c_str(), true );
mic_ = 0;
detuning_ = 0.995;
pluckAmplitude_ = 0.5;
strings_[0].setLowestFrequency( lowestFrequency );
strings_[1].setLowestFrequency( lowestFrequency );
this->setFrequency( 220.0 );
this->setPluckPosition( 0.4 );
}
Mandolin :: ~Mandolin( void )
{
}
void Mandolin :: clear( void )
{
strings_[0].clear();
strings_[1].clear();
}
void Mandolin :: setPluckPosition( StkFloat position )
{
if ( position < 0.0 || position > 1.0 ) {
oStream_ << "Mandolin::setPluckPosition: position parameter out of range!";
handleError( StkError::WARNING ); return;
}
strings_[0].setPluckPosition( position );
strings_[1].setPluckPosition( position );
}
void Mandolin :: setDetune( StkFloat detune )
{
if ( detune <= 0.0 ) {
oStream_ << "Mandolin::setDeturn: parameter is less than or equal to zero!";
handleError( StkError::WARNING ); return;
}
detuning_ = detune;
strings_[1].setFrequency( frequency_ * detuning_ );
}
void Mandolin :: setBodySize( StkFloat size )
{
// Scale the commuted body response by its sample rate (22050).
StkFloat rate = size * 22050.0 / Stk::sampleRate();
for ( int i=0; i<12; i++ )
soundfile_[i].setRate( rate );
}
void Mandolin :: setFrequency( StkFloat frequency )
{
#if defined(_STK_DEBUG_)
if ( frequency <= 0.0 ) {
oStream_ << "Mandolin::setFrequency: argument is less than or equal to zero!";
handleError( StkError::WARNING ); return;
}
#endif
frequency_ = frequency;
strings_[0].setFrequency( frequency_ );
strings_[1].setFrequency( frequency_ * detuning_ );
}
void Mandolin :: pluck( StkFloat amplitude )
{
if ( amplitude < 0.0 || amplitude > 1.0 ) {
oStream_ << "Mandolin::pluck: amplitude parameter out of range!";
handleError( StkError::WARNING ); return;
}
soundfile_[mic_].reset();
pluckAmplitude_ = amplitude;
//strings_[0].setLoopGain( 0.97 + pluckAmplitude_ * 0.03 );
//strings_[1].setLoopGain( 0.97 + pluckAmplitude_ * 0.03 );
}
void Mandolin :: pluck( StkFloat amplitude, StkFloat position )
{
this->setPluckPosition( position );
this->pluck( amplitude );
}
void Mandolin :: noteOn( StkFloat frequency, StkFloat amplitude )
{
this->setFrequency( frequency );
this->pluck( amplitude );
}
void Mandolin :: noteOff( StkFloat amplitude )
{
if ( amplitude < 0.0 || amplitude > 1.0 ) {
oStream_ << "Mandolin::noteOff: amplitude is out of range!";
handleError( StkError::WARNING ); return;
}
//strings_[0].setLoopGain( 0.97 + (1 - amplitude) * 0.03 );
//strings_[1].setLoopGain( 0.97 + (1 - amplitude) * 0.03 );
}
void Mandolin :: controlChange( int number, StkFloat value )
{
#if defined(_STK_DEBUG_)
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
oStream_ << "Mandolin::controlChange: value (" << value << ") is out of range!";
handleError( StkError::WARNING ); return;
}
#endif
StkFloat normalizedValue = value * ONE_OVER_128;
if ( number == __SK_BodySize_ ) // 2
this->setBodySize( normalizedValue * 2.0 );
else if ( number == __SK_PickPosition_ ) // 4
this->setPluckPosition( normalizedValue );
else if ( number == __SK_StringDamping_ ) { // 11
strings_[0].setLoopGain( 0.97 + (normalizedValue * 0.03) );
strings_[1].setLoopGain( 0.97 + (normalizedValue * 0.03) );
}
else if ( number == __SK_StringDetune_ ) // 1
this->setDetune( 1.0 - (normalizedValue * 0.1) );
else if ( number == __SK_AfterTouch_Cont_ ) // 128
mic_ = (int) (normalizedValue * 11.0);
#if defined(_STK_DEBUG_)
else {
oStream_ << "Mandolin::controlChange: undefined control number (" << number << ")!";
handleError( StkError::WARNING );
}
#endif
}
} // stk namespace