~ubuntu-branches/ubuntu/hardy/lmms/hardy

« back to all changes in this revision

Viewing changes to src/lib/oscillator.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Tobias Doerffel
  • Date: 2007-09-17 15:00:24 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070917150024-mo0zk4ks81jawqii
Tags: 0.3.0-1ubuntu1
* Resynchronized with Debian (LP: #139759, LP: #90806, LP: #102639,
  LP: #113447, LP: #121172, LP: #124890)
* reverted changes from 0.2.1-1.1ubuntu1 as upstream merged/included them

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
/*
4
4
 * oscillator.cpp - implementation of powerful oscillator-class
5
5
 *
6
 
 * Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
 
6
 * Copyright (c) 2004-2007 Tobias Doerffel <tobydox/at/users.sourceforge.net>
7
7
 * 
8
8
 * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
9
9
 *
19
19
 *
20
20
 * You should have received a copy of the GNU General Public
21
21
 * License along with this program (see COPYING); if not, write to the
22
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23
 
 * Boston, MA 02111-1307, USA.
 
22
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
23
 * Boston, MA 02110-1301 USA.
24
24
 *
25
25
 */
26
26
 
29
29
 
30
30
 
31
31
 
32
 
oscillator::oscillator( const waveShapes * _wave_shape,
33
 
                        const modulationAlgos * _modulation_algo,
34
 
                        const float * _freq,
35
 
                        const float * _detuning,
36
 
                        const float * _phase_offset,
37
 
                        const float * _volume,
 
32
oscillator::oscillator( const waveShapes & _wave_shape,
 
33
                        const modulationAlgos & _modulation_algo,
 
34
                        const float & _freq,
 
35
                        const float & _detuning,
 
36
                        const float & _phase_offset,
 
37
                        const float & _volume,
38
38
                        oscillator * _sub_osc ) :
39
39
        m_waveShape( _wave_shape ),
40
40
        m_modulationAlgo( _modulation_algo ),
43
43
        m_volume( _volume ),
44
44
        m_ext_phaseOffset( _phase_offset ),
45
45
        m_subOsc( _sub_osc ),
 
46
        m_phaseOffset( _phase_offset ),
 
47
        m_phase( _phase_offset ),
46
48
        m_userWave( NULL )
47
49
{
48
 
        m_phaseOffset = *m_ext_phaseOffset;
49
 
        m_phase = m_phaseOffset;
50
50
}
51
51
 
52
52
 
53
53
 
54
54
 
55
 
void oscillator::update( sampleFrame * _ab, const fpab_t _frames,
 
55
void oscillator::update( sampleFrame * _ab, const fpp_t _frames,
56
56
                                                        const ch_cnt_t _chnl )
57
57
{
58
58
        if( m_subOsc != NULL )
59
59
        {
60
 
                switch( *m_modulationAlgo )
 
60
                switch( m_modulationAlgo )
61
61
                {
62
62
                        case PHASE_MODULATION:
63
63
                                updatePM( _ab, _frames, _chnl );
84
84
 
85
85
 
86
86
 
87
 
// if we have no sub-osc, we can't do any modulation... just get our samples
88
 
void oscillator::updateNoSub( sampleFrame * _ab, const fpab_t _frames,
89
 
                                                const ch_cnt_t _chnl )
90
 
{
91
 
        recalcPhase();
92
 
        float osc_coeff = *m_freq * *m_detuning;
93
 
 
94
 
        for( fpab_t frame = 0; frame < _frames; ++frame )
95
 
        {
96
 
                _ab[frame][_chnl] = getSample( m_phase ) * *m_volume;
97
 
                m_phase += osc_coeff;
98
 
        }
99
 
}
100
 
 
101
 
 
102
 
// do pm by using sub-osc as modulator
103
 
void oscillator::updatePM( sampleFrame * _ab, const fpab_t _frames,
104
 
                                                const ch_cnt_t _chnl )
105
 
{
106
 
        m_subOsc->update( _ab, _frames, _chnl );
107
 
        recalcPhase();
108
 
        float osc_coeff = *m_freq * *m_detuning;
109
 
 
110
 
        for( fpab_t frame = 0; frame < _frames; ++frame )
111
 
        {
112
 
                _ab[frame][_chnl] = getSample( m_phase + _ab[frame][_chnl] )
113
 
                                                                * *m_volume;
114
 
                m_phase += osc_coeff;
115
 
        }
116
 
}
117
 
 
118
 
 
119
 
// do am by using sub-osc as modulator
120
 
void oscillator::updateAM( sampleFrame * _ab, const fpab_t _frames,
121
 
                                                const ch_cnt_t _chnl )
122
 
{
123
 
        m_subOsc->update( _ab, _frames, _chnl );
124
 
        recalcPhase();
125
 
        float osc_coeff = *m_freq * *m_detuning;
126
 
 
127
 
        for( fpab_t frame = 0; frame < _frames; ++frame )
128
 
        {
129
 
                _ab[frame][_chnl] *= getSample( m_phase ) * *m_volume;
130
 
                m_phase += osc_coeff;
131
 
        }
132
 
}
133
 
 
134
 
 
135
 
// do mix by using sub-osc as mix-sample
136
 
void oscillator::updateMix( sampleFrame * _ab, const fpab_t _frames,
137
 
                                                const ch_cnt_t _chnl )
138
 
{
139
 
        m_subOsc->update( _ab, _frames, _chnl );
140
 
        recalcPhase();
141
 
        float osc_coeff = *m_freq * *m_detuning;
142
 
 
143
 
        for( fpab_t frame = 0; frame < _frames; ++frame )
144
 
        {
145
 
                _ab[frame][_chnl] += getSample( m_phase ) * *m_volume;
146
 
                m_phase += osc_coeff;
147
 
        }
148
 
}
149
 
 
150
 
 
151
 
// sync with sub-osc (every time sub-osc starts new period, we also start new
152
 
// period)
153
 
void oscillator::updateSync( sampleFrame * _ab, const fpab_t _frames,
154
 
                                                const ch_cnt_t _chnl )
155
 
{
156
 
        float sub_osc_coeff = m_subOsc->syncInit( _ab, _frames, _chnl );
157
 
        recalcPhase();
158
 
        float osc_coeff = *m_freq * *m_detuning;
159
 
 
160
 
        for( fpab_t frame = 0; frame < _frames ; ++frame )
161
 
        {
162
 
                if( m_subOsc->syncOk( sub_osc_coeff ) )
163
 
                {
164
 
                        m_phase = m_phaseOffset;
165
 
                }
166
 
                _ab[frame][_chnl] = getSample( m_phase ) * *m_volume;
167
 
                m_phase += osc_coeff;
168
 
        }
169
 
}
170
 
 
171
 
 
172
 
 
173
 
 
174
 
// do fm by using sub-osc as modulator
175
 
void oscillator::updateFM( sampleFrame * _ab, const fpab_t _frames,
176
 
                                                const ch_cnt_t _chnl )
177
 
{
178
 
        m_subOsc->update( _ab, _frames, _chnl );
179
 
        recalcPhase();
180
 
        float osc_coeff = *m_freq * *m_detuning;
181
 
 
182
 
        for( fpab_t frame = 0; frame < _frames; ++frame )
183
 
        {
184
 
                m_phase += _ab[frame][_chnl];
185
 
                _ab[frame][_chnl] = getSample( m_phase ) * *m_volume;
186
 
                m_phase += osc_coeff;
187
 
        }
188
 
}
189
 
 
190
 
 
191
 
 
192
 
 
193
 
inline sample_t oscillator::getSample( const float _sample )
194
 
{
195
 
        switch( *m_waveShape )
196
 
        {
197
 
                case SIN_WAVE:
198
 
                        return( sinSample( _sample ) );
199
 
                case TRIANGLE_WAVE:
200
 
                        return( triangleSample( _sample ) );
201
 
                case SAW_WAVE:
202
 
                        return( sawSample( _sample ) );
203
 
                case SQUARE_WAVE:
204
 
                        return( squareSample( _sample ) );
205
 
                case MOOG_SAW_WAVE:
206
 
                        return( moogSawSample( _sample ) );
207
 
                case EXP_WAVE:
208
 
                        return( expSample( _sample ) );
209
 
                case WHITE_NOISE_WAVE:
210
 
                        return( noiseSample( _sample ) );
211
 
                case USER_DEF_WAVE:
212
 
                        return( userWaveSample( _sample ) );
213
 
                default:
214
 
                        return( sinSample( _sample ) );
215
 
        }
216
 
 
 
87
void oscillator::updateNoSub( sampleFrame * _ab, const fpp_t _frames,
 
88
                                                        const ch_cnt_t _chnl )
 
89
{
 
90
        switch( m_waveShape )
 
91
        {
 
92
                case SIN_WAVE:
 
93
                default:
 
94
                        updateNoSub<SIN_WAVE>( _ab, _frames, _chnl );
 
95
                        break;
 
96
                case TRIANGLE_WAVE:
 
97
                        updateNoSub<TRIANGLE_WAVE>( _ab, _frames, _chnl );
 
98
                        break;
 
99
                case SAW_WAVE:
 
100
                        updateNoSub<SAW_WAVE>( _ab, _frames, _chnl );
 
101
                        break;
 
102
                case SQUARE_WAVE:
 
103
                        updateNoSub<SQUARE_WAVE>( _ab, _frames, _chnl );
 
104
                        break;
 
105
                case MOOG_SAW_WAVE:
 
106
                        updateNoSub<MOOG_SAW_WAVE>( _ab, _frames, _chnl );
 
107
                        break;
 
108
                case EXP_WAVE:
 
109
                        updateNoSub<EXP_WAVE>( _ab, _frames, _chnl );
 
110
                        break;
 
111
                case WHITE_NOISE_WAVE:
 
112
                        updateNoSub<WHITE_NOISE_WAVE>( _ab, _frames, _chnl );
 
113
                        break;
 
114
                case USER_DEF_WAVE:
 
115
                        updateNoSub<USER_DEF_WAVE>( _ab, _frames, _chnl );
 
116
                        break;
 
117
        }
 
118
}
 
119
 
 
120
 
 
121
 
 
122
 
 
123
void oscillator::updatePM( sampleFrame * _ab, const fpp_t _frames,
 
124
                                                        const ch_cnt_t _chnl )
 
125
{
 
126
        switch( m_waveShape )
 
127
        {
 
128
                case SIN_WAVE:
 
129
                default:
 
130
                        updatePM<SIN_WAVE>( _ab, _frames, _chnl );
 
131
                        break;
 
132
                case TRIANGLE_WAVE:
 
133
                        updatePM<TRIANGLE_WAVE>( _ab, _frames, _chnl );
 
134
                        break;
 
135
                case SAW_WAVE:
 
136
                        updatePM<SAW_WAVE>( _ab, _frames, _chnl );
 
137
                        break;
 
138
                case SQUARE_WAVE:
 
139
                        updatePM<SQUARE_WAVE>( _ab, _frames, _chnl );
 
140
                        break;
 
141
                case MOOG_SAW_WAVE:
 
142
                        updatePM<MOOG_SAW_WAVE>( _ab, _frames, _chnl );
 
143
                        break;
 
144
                case EXP_WAVE:
 
145
                        updatePM<EXP_WAVE>( _ab, _frames, _chnl );
 
146
                        break;
 
147
                case WHITE_NOISE_WAVE:
 
148
                        updatePM<WHITE_NOISE_WAVE>( _ab, _frames, _chnl );
 
149
                        break;
 
150
                case USER_DEF_WAVE:
 
151
                        updatePM<USER_DEF_WAVE>( _ab, _frames, _chnl );
 
152
                        break;
 
153
        }
 
154
}
 
155
 
 
156
 
 
157
 
 
158
 
 
159
void oscillator::updateAM( sampleFrame * _ab, const fpp_t _frames,
 
160
                                                        const ch_cnt_t _chnl )
 
161
{
 
162
        switch( m_waveShape )
 
163
        {
 
164
                case SIN_WAVE:
 
165
                default:
 
166
                        updateAM<SIN_WAVE>( _ab, _frames, _chnl );
 
167
                        break;
 
168
                case TRIANGLE_WAVE:
 
169
                        updateAM<TRIANGLE_WAVE>( _ab, _frames, _chnl );
 
170
                        break;
 
171
                case SAW_WAVE:
 
172
                        updateAM<SAW_WAVE>( _ab, _frames, _chnl );
 
173
                        break;
 
174
                case SQUARE_WAVE:
 
175
                        updateAM<SQUARE_WAVE>( _ab, _frames, _chnl );
 
176
                        break;
 
177
                case MOOG_SAW_WAVE:
 
178
                        updateAM<MOOG_SAW_WAVE>( _ab, _frames, _chnl );
 
179
                        break;
 
180
                case EXP_WAVE:
 
181
                        updateAM<EXP_WAVE>( _ab, _frames, _chnl );
 
182
                        break;
 
183
                case WHITE_NOISE_WAVE:
 
184
                        updateAM<WHITE_NOISE_WAVE>( _ab, _frames, _chnl );
 
185
                        break;
 
186
                case USER_DEF_WAVE:
 
187
                        updateAM<USER_DEF_WAVE>( _ab, _frames, _chnl );
 
188
                        break;
 
189
        }
 
190
}
 
191
 
 
192
 
 
193
 
 
194
 
 
195
void oscillator::updateMix( sampleFrame * _ab, const fpp_t _frames,
 
196
                                                        const ch_cnt_t _chnl )
 
197
{
 
198
        switch( m_waveShape )
 
199
        {
 
200
                case SIN_WAVE:
 
201
                default:
 
202
                        updateMix<SIN_WAVE>( _ab, _frames, _chnl );
 
203
                        break;
 
204
                case TRIANGLE_WAVE:
 
205
                        updateMix<TRIANGLE_WAVE>( _ab, _frames, _chnl );
 
206
                        break;
 
207
                case SAW_WAVE:
 
208
                        updateMix<SAW_WAVE>( _ab, _frames, _chnl );
 
209
                        break;
 
210
                case SQUARE_WAVE:
 
211
                        updateMix<SQUARE_WAVE>( _ab, _frames, _chnl );
 
212
                        break;
 
213
                case MOOG_SAW_WAVE:
 
214
                        updateMix<MOOG_SAW_WAVE>( _ab, _frames, _chnl );
 
215
                        break;
 
216
                case EXP_WAVE:
 
217
                        updateMix<EXP_WAVE>( _ab, _frames, _chnl );
 
218
                        break;
 
219
                case WHITE_NOISE_WAVE:
 
220
                        updateMix<WHITE_NOISE_WAVE>( _ab, _frames, _chnl );
 
221
                        break;
 
222
                case USER_DEF_WAVE:
 
223
                        updateMix<USER_DEF_WAVE>( _ab, _frames, _chnl );
 
224
                        break;
 
225
        }
 
226
}
 
227
 
 
228
 
 
229
 
 
230
 
 
231
void oscillator::updateSync( sampleFrame * _ab, const fpp_t _frames,
 
232
                                                        const ch_cnt_t _chnl )
 
233
{
 
234
        switch( m_waveShape )
 
235
        {
 
236
                case SIN_WAVE:
 
237
                default:
 
238
                        updateSync<SIN_WAVE>( _ab, _frames, _chnl );
 
239
                        break;
 
240
                case TRIANGLE_WAVE:
 
241
                        updateSync<TRIANGLE_WAVE>( _ab, _frames, _chnl );
 
242
                        break;
 
243
                case SAW_WAVE:
 
244
                        updateSync<SAW_WAVE>( _ab, _frames, _chnl );
 
245
                        break;
 
246
                case SQUARE_WAVE:
 
247
                        updateSync<SQUARE_WAVE>( _ab, _frames, _chnl );
 
248
                        break;
 
249
                case MOOG_SAW_WAVE:
 
250
                        updateSync<MOOG_SAW_WAVE>( _ab, _frames, _chnl );
 
251
                        break;
 
252
                case EXP_WAVE:
 
253
                        updateSync<EXP_WAVE>( _ab, _frames, _chnl );
 
254
                        break;
 
255
                case WHITE_NOISE_WAVE:
 
256
                        updateSync<WHITE_NOISE_WAVE>( _ab, _frames, _chnl );
 
257
                        break;
 
258
                case USER_DEF_WAVE:
 
259
                        updateSync<USER_DEF_WAVE>( _ab, _frames, _chnl );
 
260
                        break;
 
261
        }
 
262
}
 
263
 
 
264
 
 
265
 
 
266
 
 
267
void oscillator::updateFM( sampleFrame * _ab, const fpp_t _frames,
 
268
                                                        const ch_cnt_t _chnl )
 
269
{
 
270
        switch( m_waveShape )
 
271
        {
 
272
                case SIN_WAVE:
 
273
                default:
 
274
                        updateFM<SIN_WAVE>( _ab, _frames, _chnl );
 
275
                        break;
 
276
                case TRIANGLE_WAVE:
 
277
                        updateFM<TRIANGLE_WAVE>( _ab, _frames, _chnl );
 
278
                        break;
 
279
                case SAW_WAVE:
 
280
                        updateFM<SAW_WAVE>( _ab, _frames, _chnl );
 
281
                        break;
 
282
                case SQUARE_WAVE:
 
283
                        updateFM<SQUARE_WAVE>( _ab, _frames, _chnl );
 
284
                        break;
 
285
                case MOOG_SAW_WAVE:
 
286
                        updateFM<MOOG_SAW_WAVE>( _ab, _frames, _chnl );
 
287
                        break;
 
288
                case EXP_WAVE:
 
289
                        updateFM<EXP_WAVE>( _ab, _frames, _chnl );
 
290
                        break;
 
291
                case WHITE_NOISE_WAVE:
 
292
                        updateFM<WHITE_NOISE_WAVE>( _ab, _frames, _chnl );
 
293
                        break;
 
294
                case USER_DEF_WAVE:
 
295
                        updateFM<USER_DEF_WAVE>( _ab, _frames, _chnl );
 
296
                        break;
 
297
        }
217
298
}
218
299
 
219
300
 
222
303
// should be called every time phase-offset is changed...
223
304
inline void oscillator::recalcPhase( void )
224
305
{
225
 
        if( m_phaseOffset != *m_ext_phaseOffset )
 
306
        if( m_phaseOffset != m_ext_phaseOffset )
226
307
        {
227
308
                m_phase -= m_phaseOffset;
228
 
                m_phaseOffset = *m_ext_phaseOffset;
 
309
                m_phaseOffset = m_ext_phaseOffset;
229
310
                m_phase += m_phaseOffset;
230
311
        }
231
312
        m_phase = fraction( m_phase );
245
326
 
246
327
 
247
328
 
248
 
float oscillator::syncInit( sampleFrame * _ab, const fpab_t _frames,
 
329
float oscillator::syncInit( sampleFrame * _ab, const fpp_t _frames,
249
330
                                                const ch_cnt_t _chnl )
250
331
{
251
332
        if( m_subOsc != NULL )
253
334
                m_subOsc->update( _ab, _frames, _chnl );
254
335
        }
255
336
        recalcPhase();
256
 
        return( *m_freq * *m_detuning );
257
 
}
 
337
        return( m_freq * m_detuning );
 
338
}
 
339
 
 
340
 
 
341
 
 
342
 
 
343
// if we have no sub-osc, we can't do any modulation... just get our samples
 
344
template<oscillator::waveShapes W>
 
345
void oscillator::updateNoSub( sampleFrame * _ab, const fpp_t _frames,
 
346
                                                        const ch_cnt_t _chnl )
 
347
{
 
348
        recalcPhase();
 
349
        const float osc_coeff = m_freq * m_detuning;
 
350
 
 
351
        for( fpp_t frame = 0; frame < _frames; ++frame )
 
352
        {
 
353
                _ab[frame][_chnl] = getSample<W>( m_phase ) * m_volume;
 
354
                m_phase += osc_coeff;
 
355
        }
 
356
}
 
357
 
 
358
 
 
359
 
 
360
 
 
361
// do pm by using sub-osc as modulator
 
362
template<oscillator::waveShapes W>
 
363
void oscillator::updatePM( sampleFrame * _ab, const fpp_t _frames,
 
364
                                                        const ch_cnt_t _chnl )
 
365
{
 
366
        m_subOsc->update( _ab, _frames, _chnl );
 
367
        recalcPhase();
 
368
        const float osc_coeff = m_freq * m_detuning;
 
369
 
 
370
        for( fpp_t frame = 0; frame < _frames; ++frame )
 
371
        {
 
372
                _ab[frame][_chnl] = getSample<W>( m_phase + _ab[frame][_chnl] )
 
373
                                                                * m_volume;
 
374
                m_phase += osc_coeff;
 
375
        }
 
376
}
 
377
 
 
378
 
 
379
 
 
380
 
 
381
// do am by using sub-osc as modulator
 
382
template<oscillator::waveShapes W>
 
383
void oscillator::updateAM( sampleFrame * _ab, const fpp_t _frames,
 
384
                                                        const ch_cnt_t _chnl )
 
385
{
 
386
        m_subOsc->update( _ab, _frames, _chnl );
 
387
        recalcPhase();
 
388
        const float osc_coeff = m_freq * m_detuning;
 
389
 
 
390
        for( fpp_t frame = 0; frame < _frames; ++frame )
 
391
        {
 
392
                _ab[frame][_chnl] *= getSample<W>( m_phase ) * m_volume;
 
393
                m_phase += osc_coeff;
 
394
        }
 
395
}
 
396
 
 
397
 
 
398
 
 
399
 
 
400
// do mix by using sub-osc as mix-sample
 
401
template<oscillator::waveShapes W>
 
402
void oscillator::updateMix( sampleFrame * _ab, const fpp_t _frames,
 
403
                                                        const ch_cnt_t _chnl )
 
404
{
 
405
        m_subOsc->update( _ab, _frames, _chnl );
 
406
        recalcPhase();
 
407
        const float osc_coeff = m_freq * m_detuning;
 
408
 
 
409
        for( fpp_t frame = 0; frame < _frames; ++frame )
 
410
        {
 
411
                _ab[frame][_chnl] += getSample<W>( m_phase ) * m_volume;
 
412
                m_phase += osc_coeff;
 
413
        }
 
414
}
 
415
 
 
416
 
 
417
 
 
418
 
 
419
// sync with sub-osc (every time sub-osc starts new period, we also start new
 
420
// period)
 
421
template<oscillator::waveShapes W>
 
422
void oscillator::updateSync( sampleFrame * _ab, const fpp_t _frames,
 
423
                                                        const ch_cnt_t _chnl )
 
424
{
 
425
        const float sub_osc_coeff = m_subOsc->syncInit( _ab, _frames, _chnl );
 
426
        recalcPhase();
 
427
        const float osc_coeff = m_freq * m_detuning;
 
428
 
 
429
        for( fpp_t frame = 0; frame < _frames ; ++frame )
 
430
        {
 
431
                if( m_subOsc->syncOk( sub_osc_coeff ) )
 
432
                {
 
433
                        m_phase = m_phaseOffset;
 
434
                }
 
435
                _ab[frame][_chnl] = getSample<W>( m_phase ) * m_volume;
 
436
                m_phase += osc_coeff;
 
437
        }
 
438
}
 
439
 
 
440
 
 
441
 
 
442
 
 
443
// do fm by using sub-osc as modulator
 
444
template<oscillator::waveShapes W>
 
445
void oscillator::updateFM( sampleFrame * _ab, const fpp_t _frames,
 
446
                                                        const ch_cnt_t _chnl )
 
447
{
 
448
        m_subOsc->update( _ab, _frames, _chnl );
 
449
        recalcPhase();
 
450
        const float osc_coeff = m_freq * m_detuning;
 
451
 
 
452
        for( fpp_t frame = 0; frame < _frames; ++frame )
 
453
        {
 
454
                m_phase += _ab[frame][_chnl];
 
455
                _ab[frame][_chnl] = getSample<W>( m_phase ) * m_volume;
 
456
                m_phase += osc_coeff;
 
457
        }
 
458
}
 
459
 
 
460
 
 
461
 
 
462
 
 
463
template<>
 
464
inline sample_t oscillator::getSample<oscillator::SIN_WAVE>(
 
465
                                                        const float _sample )
 
466
{
 
467
        return( sinSample( _sample ) );
 
468
}
 
469
 
 
470
 
 
471
 
 
472
 
 
473
template<>
 
474
inline sample_t oscillator::getSample<oscillator::TRIANGLE_WAVE>(
 
475
                                                        const float _sample )
 
476
{
 
477
        return( triangleSample( _sample ) );
 
478
}
 
479
 
 
480
 
 
481
 
 
482
 
 
483
template<>
 
484
inline sample_t oscillator::getSample<oscillator::SAW_WAVE>(
 
485
                                                        const float _sample )
 
486
{
 
487
        return( sawSample( _sample ) );
 
488
}
 
489
 
 
490
 
 
491
 
 
492
 
 
493
template<>
 
494
inline sample_t oscillator::getSample<oscillator::SQUARE_WAVE>(
 
495
                                                        const float _sample )
 
496
{
 
497
        return( squareSample( _sample ) );
 
498
}
 
499
 
 
500
 
 
501
 
 
502
 
 
503
template<>
 
504
inline sample_t oscillator::getSample<oscillator::MOOG_SAW_WAVE>(
 
505
                                                        const float _sample )
 
506
{
 
507
        return( moogSawSample( _sample ) );
 
508
}
 
509
 
 
510
 
 
511
 
 
512
 
 
513
template<>
 
514
inline sample_t oscillator::getSample<oscillator::EXP_WAVE>(
 
515
                                                        const float _sample )
 
516
{
 
517
        return( expSample( _sample ) );
 
518
}
 
519
 
 
520
 
 
521
 
 
522
 
 
523
template<>
 
524
inline sample_t oscillator::getSample<oscillator::WHITE_NOISE_WAVE>(
 
525
                                                        const float _sample )
 
526
{
 
527
        return( noiseSample( _sample ) );
 
528
}
 
529
 
 
530
 
 
531
 
 
532
 
 
533
template<>
 
534
inline sample_t oscillator::getSample<oscillator::USER_DEF_WAVE>(
 
535
                                                        const float _sample )
 
536
{
 
537
        return( userWaveSample( _sample ) );
 
538
}
 
539
 
 
540
 
 
541
 
258
542
 
259
543
#endif