2
* triple_oscillator.cpp - powerful sound-generator-plugin with 3 oscillators
4
* Linux MultiMedia Studio
5
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* General Public License for more details.
17
* You should have received a copy of the GNU General Public
18
* License along with this program (see COPYING); if not, write to the
19
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
* Boston, MA 02111-1307, USA.
25
#include "qt3support.h"
30
#include <QButtonGroup>
36
#include <qbuttongroup.h>
41
#define setChecked setOn
46
#include "triple_oscillator.h"
47
#include "song_editor.h"
48
#include "channel_track.h"
50
#include "note_play_handle.h"
52
#include "pixmap_button.h"
53
#include "buffer_allocator.h"
59
const QString tripleOscillator::s_pluginName = "TripleOscillator";
60
const QString tripleOscillator::s_pluginNodeName = "tripleoscillator";
63
tripleOscillator::tripleOscillator (channelTrack * _channel_track ) :
64
soundGenerator( _channel_track ),
65
m_modulationAlgo1( oscillator::MIX ),
66
m_modulationAlgo2( oscillator::MIX )
70
pal.setBrush( backgroundRole(),
71
embed::getIconPixmap( "triple_osc_artwork" ) );
74
setErasePixmap( embed::getIconPixmap( "triple_osc_artwork" ) );
77
m_fm1OscBtn = new pixmapButton( this );
78
m_fm1OscBtn->move( 80, 50 );
79
m_fm1OscBtn->setActiveGraphic( embed::getIconPixmap( "fm_active" ) );
80
m_fm1OscBtn->setInactiveGraphic( embed::getIconPixmap(
82
m_fm1OscBtn->setMask( QBitmap( embed::getIconPixmap(
83
"triple_osc_btn_mask" ).
84
createHeuristicMask() ) );
85
connect( m_fm1OscBtn, SIGNAL( toggled( bool ) ), this,
86
SLOT( fm1BtnToggled( bool ) ) );
87
toolTip::add( m_fm1OscBtn, tr( "use frequency modulation for "
88
"modulating oscillator 2 with "
91
m_am1OscBtn = new pixmapButton( this );
92
m_am1OscBtn->move( 120, 50 );
93
m_am1OscBtn->setActiveGraphic( embed::getIconPixmap( "am_active" ) );
94
m_am1OscBtn->setInactiveGraphic( embed::getIconPixmap(
96
m_am1OscBtn->setMask( QBitmap( embed::getIconPixmap(
97
"triple_osc_btn_mask" ).
98
createHeuristicMask() ) );
99
connect( m_am1OscBtn, SIGNAL( toggled( bool ) ), this,
100
SLOT( am1BtnToggled( bool ) ) );
101
toolTip::add( m_am1OscBtn, tr( "use amplitude modulation for "
102
"modulating oscillator 2 with "
105
m_mix1OscBtn = new pixmapButton( this );
106
m_mix1OscBtn->move( 160, 50 );
107
m_mix1OscBtn->setActiveGraphic( embed::getIconPixmap( "mix_active" ) );
108
m_mix1OscBtn->setInactiveGraphic( embed::getIconPixmap(
110
m_mix1OscBtn->setMask( QBitmap( embed::getIconPixmap(
111
"triple_osc_btn_mask" ).
112
createHeuristicMask() ) );
113
connect( m_mix1OscBtn, SIGNAL( toggled( bool ) ), this,
114
SLOT( mix1BtnToggled( bool ) ) );
115
toolTip::add( m_mix1OscBtn, tr( "mix output of oscillator 1 & 2" ) );
117
m_sync1OscBtn = new pixmapButton( this );
118
m_sync1OscBtn->move( 200, 50 );
119
m_sync1OscBtn->setActiveGraphic( embed::getIconPixmap(
121
m_sync1OscBtn->setInactiveGraphic( embed::getIconPixmap(
123
m_sync1OscBtn->setMask( QBitmap( embed::getIconPixmap(
124
"triple_osc_btn_mask" ).
125
createHeuristicMask() ) );
126
connect( m_sync1OscBtn, SIGNAL( toggled( bool ) ), this, SLOT(
127
sync1BtnToggled( bool ) ) );
128
toolTip::add( m_sync1OscBtn, tr( "synchronize oscillator 1 with "
131
if( m_modulationAlgo1 == oscillator::FREQ_MODULATION )
133
m_fm1OscBtn->setChecked( TRUE );
135
else if( m_modulationAlgo1 == oscillator::AMP_MODULATION )
137
m_am1OscBtn->setChecked( TRUE );
139
else if( m_modulationAlgo1 == oscillator::MIX )
141
m_mix1OscBtn->setChecked( TRUE );
143
else if( m_modulationAlgo1 == oscillator::SYNC )
145
m_sync1OscBtn->setChecked( TRUE );
148
QButtonGroup * modulation_algo_group1 = new QButtonGroup( this );
149
modulation_algo_group1->addButton( m_fm1OscBtn );
150
modulation_algo_group1->addButton( m_am1OscBtn );
151
modulation_algo_group1->addButton( m_mix1OscBtn );
152
modulation_algo_group1->addButton( m_sync1OscBtn );
153
modulation_algo_group1->setExclusive( TRUE );
155
modulation_algo_group1->hide();
158
m_fm2OscBtn = new pixmapButton( this );
159
m_fm2OscBtn->move( 80, 70 );
160
m_fm2OscBtn->setActiveGraphic( embed::getIconPixmap( "fm_active" ) );
161
m_fm2OscBtn->setInactiveGraphic( embed::getIconPixmap(
163
m_fm2OscBtn->setMask( QBitmap( embed::getIconPixmap(
164
"triple_osc_btn_mask" ).
165
createHeuristicMask() ) );
166
connect( m_fm2OscBtn, SIGNAL( toggled( bool ) ), this, SLOT(
167
fm2BtnToggled( bool ) ) );
168
toolTip::add( m_fm2OscBtn, tr( "use frequency modulation for "
169
"modulating oscillator 3 with "
172
m_am2OscBtn = new pixmapButton( this );
173
m_am2OscBtn->move( 120, 70 );
174
m_am2OscBtn->setActiveGraphic( embed::getIconPixmap( "am_active" ) );
175
m_am2OscBtn->setInactiveGraphic( embed::getIconPixmap("am_inactive" ) );
176
m_am2OscBtn->setMask( QBitmap( embed::getIconPixmap(
177
"triple_osc_btn_mask" ).
178
createHeuristicMask() ) );
179
connect( m_am2OscBtn, SIGNAL( toggled( bool ) ), this,
180
SLOT( am2BtnToggled( bool ) ) );
181
toolTip::add( m_am2OscBtn, tr( "use amplitude modulation for "
182
"modulating oscillator 3 with "
185
m_mix2OscBtn = new pixmapButton( this );
186
m_mix2OscBtn->move( 160, 70 );
187
m_mix2OscBtn->setActiveGraphic( embed::getIconPixmap( "mix_active" ) );
188
m_mix2OscBtn->setInactiveGraphic( embed::getIconPixmap(
190
m_mix2OscBtn->setMask( QBitmap( embed::getIconPixmap(
191
"triple_osc_btn_mask" ).
192
createHeuristicMask() ) );
193
connect( m_mix2OscBtn, SIGNAL( toggled( bool ) ), this,
194
SLOT( mix2BtnToggled( bool ) ) );
195
toolTip::add( m_mix2OscBtn, tr("mix output of oscillator 2 & 3" ) );
197
m_sync2OscBtn = new pixmapButton( this );
198
m_sync2OscBtn->move( 200, 70 );
199
m_sync2OscBtn->setActiveGraphic( embed::getIconPixmap(
201
m_sync2OscBtn->setInactiveGraphic( embed::getIconPixmap(
203
m_sync2OscBtn->setMask( QBitmap( embed::getIconPixmap(
204
"triple_osc_btn_mask" ).
205
createHeuristicMask() ) );
206
connect( m_sync2OscBtn, SIGNAL( toggled( bool ) ), this,
207
SLOT( sync2BtnToggled( bool ) ) );
208
toolTip::add( m_sync2OscBtn, tr( "synchronize oscillator 2 with "
211
if( m_modulationAlgo2 == oscillator::FREQ_MODULATION )
213
m_fm2OscBtn->setChecked( TRUE );
215
else if( m_modulationAlgo2 == oscillator::AMP_MODULATION )
217
m_am2OscBtn->setChecked( TRUE );
219
else if( m_modulationAlgo2 == oscillator::MIX )
221
m_mix2OscBtn->setChecked( TRUE );
223
else if( m_modulationAlgo2 == oscillator::SYNC )
225
m_sync2OscBtn->setChecked( TRUE );
228
QButtonGroup * modulation_algo_group2 = new QButtonGroup( this );
229
modulation_algo_group2->addButton( m_fm2OscBtn );
230
modulation_algo_group2->addButton( m_am2OscBtn );
231
modulation_algo_group2->addButton( m_mix2OscBtn );
232
modulation_algo_group2->addButton( m_sync2OscBtn );
233
modulation_algo_group2->setExclusive( TRUE );
235
modulation_algo_group2->hide();
239
for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
241
// reset current m_osc-structure
242
m_osc[i].waveShape = oscillator::SIN_WAVE;
245
m_osc[i].volKnob = new knob( knobSmall_17, this, tr(
246
"Osc %1 volume" ).arg( i+1 ) );
247
m_osc[i].volKnob->move( 6, 104+i*50 );
248
m_osc[i].volKnob->setRange( MIN_VOLUME, MAX_VOLUME, 1.0f );
249
m_osc[i].volKnob->setValue( DEFAULT_VOLUME, TRUE );
250
m_osc[i].volKnob->setHintText( tr( "Osc %1 volume:" ).arg(
253
m_osc[i].volKnob->setWhatsThis(
255
QWhatsThis::add( m_osc[i].volKnob,
257
tr( "With this knob you can set the volume of "
258
"oscillator %1. When setting a value of 0 the "
259
"oscillator is turned off. Otherwise you can "
260
"hear the oscillator as loud as you set it "
261
"here.").arg( i+1 ) );
263
// setup panning-knob
264
m_osc[i].panKnob = new knob( knobSmall_17, this,
265
tr( "Osc %1 panning" ).arg( i + 1 ) );
266
m_osc[i].panKnob->move( 33, 104+i*50 );
267
m_osc[i].panKnob->setRange( PANNING_LEFT, PANNING_RIGHT, 1.0f );
268
m_osc[i].panKnob->setValue( DEFAULT_PANNING, TRUE );
269
m_osc[i].panKnob->setHintText( tr("Osc %1 panning:").arg( i+1 )
272
m_osc[i].panKnob->setWhatsThis(
274
QWhatsThis::add( m_osc[i].panKnob,
276
tr( "With this knob you can set the panning of the "
277
"oscillator %1. A value of -100 means 100% "
278
"left and a value of 100 moves oscillator-"
279
"output right.").arg( i+1 ) );
282
m_osc[i].coarseKnob = new knob( knobSmall_17, this,
283
tr("Osc %1 coarse detuning").arg( i + 1 ) );
284
m_osc[i].coarseKnob->move( 66, 104 + i * 50 );
285
m_osc[i].coarseKnob->setRange( -2 * NOTES_PER_OCTAVE,
286
2 * NOTES_PER_OCTAVE, 1.0f );
287
m_osc[i].coarseKnob->setValue( 0.0f, TRUE );
288
m_osc[i].coarseKnob->setHintText( tr( "Osc %1 coarse detuning:"
289
).arg( i + 1 ) + " ",
290
" " + tr( "semitones" ) );
292
m_osc[i].coarseKnob->setWhatsThis(
294
QWhatsThis::add( m_osc[i].coarseKnob,
296
tr( "With this knob you can set the coarse detuning of "
297
"oscillator %1. You can detune the oscillator "
298
"12 semitones (1 octave) up and down. This is "
299
"useful for creating sounds with a chord." ).
302
// setup knob for left fine-detuning
303
m_osc[i].fineLKnob = new knob( knobSmall_17, this,
304
tr( "Osc %1 fine detuning left" ).arg( i+1 ) );
305
m_osc[i].fineLKnob->move( 90, 104 + i * 50 );
306
m_osc[i].fineLKnob->setRange( -100.0f, 100.0f, 1.0f );
307
m_osc[i].fineLKnob->setValue( 0.0f, TRUE );
308
m_osc[i].fineLKnob->setHintText( tr( "Osc %1 fine detuning "
309
"left:" ).arg( i + 1 )
313
m_osc[i].fineLKnob->setWhatsThis(
315
QWhatsThis::add( m_osc[i].fineLKnob,
317
tr( "With this knob you can set the fine detuning of "
318
"oscillator %1 for the left channel. The fine-"
319
"detuning is ranged between -100 cents and "
320
"+100 cents. This is useful for creating "
321
"\"fat\" sounds." ).arg( i + 1 ) );
323
// setup knob for right fine-detuning
324
m_osc[i].fineRKnob = new knob( knobSmall_17, this,
325
tr( "Osc %1 fine detuning right"
327
m_osc[i].fineRKnob->move( 110, 104 + i * 50 );
328
m_osc[i].fineRKnob->setRange( -100.0f, 100.0f, 1.0f );
329
m_osc[i].fineRKnob->setValue( 0.0f, TRUE );
330
m_osc[i].fineRKnob->setHintText( tr( "Osc %1 fine detuning "
331
"right:").arg( i + 1 ) +
332
" ", " " + tr( "cents" ) );
334
m_osc[i].fineRKnob->setWhatsThis(
336
QWhatsThis::add( m_osc[i].fineRKnob,
338
tr( "With this knob you can set the fine detuning of "
339
"oscillator %1 for the right channel. The "
340
"fine-detuning is ranged between -100 cents "
341
"and +100 cents. This is useful for creating "
342
"\"fat\" sounds." ).arg( i+1 ) );
344
// setup phase-offset-knob
345
m_osc[i].phaseOffsetKnob = new knob( knobSmall_17, this,
347
"offset" ).arg( i+1 ) );
348
m_osc[i].phaseOffsetKnob->move( 142, 104 + i * 50 );
349
m_osc[i].phaseOffsetKnob->setRange( 0.0f, 360.0f, 1.0f );
350
m_osc[i].phaseOffsetKnob->setValue( 0.0f, TRUE );
351
m_osc[i].phaseOffsetKnob->setHintText( tr( "Osc %1 phase-"
354
" ", " " + tr( "degrees" ) );
356
m_osc[i].phaseOffsetKnob->setWhatsThis(
358
QWhatsThis::add( m_osc[i].phaseOffsetKnob,
360
tr( "With this knob you can set the phase-offset of "
361
"oscillator %1. That means you can move the "
362
"point within an oscillation where the "
363
"oscillator begins to oscillate. For example "
364
"if you have a sine-wave and have a phase-"
365
"offset of 180 degrees the wave will first go "
366
"down. It's the same with a square-wave."
369
// setup stereo-phase-detuning-knob
370
m_osc[i].stereoPhaseDetuningKnob = new knob( knobSmall_17, this,
371
tr( "Osc %1 stereo phase-"
372
"detuning" ).arg( i+1 )
374
m_osc[i].stereoPhaseDetuningKnob->move( 166, 104 + i * 50 );
375
m_osc[i].stereoPhaseDetuningKnob->setRange( 0.0f, 360.0f,
377
m_osc[i].stereoPhaseDetuningKnob->setValue( 0.0f, TRUE );
378
m_osc[i].stereoPhaseDetuningKnob->setHintText( tr("Osc %1 "
385
m_osc[i].stereoPhaseDetuningKnob->setWhatsThis(
387
QWhatsThis::add( m_osc[i].stereoPhaseDetuningKnob,
389
tr( "With this knob you can set the stereo phase-"
390
"detuning of oscillator %1. The stereo phase-"
391
"detuning specifies the size of the difference "
392
"between the phase-offset of left and right "
393
"channel. This is very good for creating wide "
394
"stereo-sounds." ).arg( i+1 ) );
396
m_osc[i].sinWaveBtn = new pixmapButton( this );
397
m_osc[i].sinWaveBtn->move( 188, 105 + i * 50 );
398
m_osc[i].sinWaveBtn->setActiveGraphic( embed::getIconPixmap(
399
"sin_wave_active" ) );
400
m_osc[i].sinWaveBtn->setInactiveGraphic( embed::getIconPixmap(
401
"sin_wave_inactive" ) );
402
m_osc[i].sinWaveBtn->setChecked( TRUE );
403
toolTip::add( m_osc[i].sinWaveBtn,
404
tr( "Click here if you want a sine-wave for "
405
"current oscillator." ) );
407
m_osc[i].triangleWaveBtn = new pixmapButton( this );
408
m_osc[i].triangleWaveBtn->move( 203, 105 + i * 50 );
409
m_osc[i].triangleWaveBtn->setActiveGraphic(
410
embed::getIconPixmap( "triangle_wave_active" ) );
411
m_osc[i].triangleWaveBtn->setInactiveGraphic(
412
embed::getIconPixmap( "triangle_wave_inactive" ) );
413
toolTip::add( m_osc[i].triangleWaveBtn,
414
tr( "Click here if you want a triangle-wave "
415
"for current oscillator." ) );
417
m_osc[i].sawWaveBtn = new pixmapButton( this );
418
m_osc[i].sawWaveBtn->move( 218, 105 + i * 50 );
419
m_osc[i].sawWaveBtn->setActiveGraphic( embed::getIconPixmap(
420
"saw_wave_active" ) );
421
m_osc[i].sawWaveBtn->setInactiveGraphic( embed::getIconPixmap(
422
"saw_wave_inactive" ) );
423
toolTip::add( m_osc[i].sawWaveBtn,
424
tr( "Click here if you want a saw-wave for "
425
"current oscillator." ) );
427
m_osc[i].sqrWaveBtn = new pixmapButton( this );
428
m_osc[i].sqrWaveBtn->move( 233, 105 + i * 50 );
429
m_osc[i].sqrWaveBtn->setActiveGraphic( embed::getIconPixmap(
430
"square_wave_active" ) );
431
m_osc[i].sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
432
"square_wave_inactive" ) );
433
toolTip::add( m_osc[i].sqrWaveBtn,
434
tr( "Click here if you want a square-wave for "
435
"current oscillator." ) );
437
m_osc[i].moogSawWaveBtn = new pixmapButton( this );
438
m_osc[i].moogSawWaveBtn->move( 188, 120+i*50 );
439
m_osc[i].moogSawWaveBtn->setActiveGraphic(
440
embed::getIconPixmap( "moog_saw_wave_active" ) );
441
m_osc[i].moogSawWaveBtn->setInactiveGraphic(
442
embed::getIconPixmap( "moog_saw_wave_inactive" ) );
443
toolTip::add( m_osc[i].moogSawWaveBtn,
444
tr( "Click here if you want a moog-saw-wave "
445
"for current oscillator." ) );
447
m_osc[i].expWaveBtn = new pixmapButton( this );
448
m_osc[i].expWaveBtn->move( 203, 120+i*50 );
449
m_osc[i].expWaveBtn->setActiveGraphic( embed::getIconPixmap(
450
"exp_wave_active" ) );
451
m_osc[i].expWaveBtn->setInactiveGraphic( embed::getIconPixmap(
452
"exp_wave_inactive" ) );
453
toolTip::add( m_osc[i].expWaveBtn,
454
tr( "Click here if you want an exponential "
455
"wave for current oscillator." ) );
457
m_osc[i].whiteNoiseWaveBtn = new pixmapButton( this );
458
m_osc[i].whiteNoiseWaveBtn->move( 218, 120+i*50 );
459
m_osc[i].whiteNoiseWaveBtn->setActiveGraphic(
460
embed::getIconPixmap( "white_noise_wave_active" ) );
461
m_osc[i].whiteNoiseWaveBtn->setInactiveGraphic(
462
embed::getIconPixmap( "white_noise_wave_inactive" ) );
463
toolTip::add( m_osc[i].whiteNoiseWaveBtn,
464
tr( "Click here if you want a white-noise for "
465
"current oscillator." ) );
467
m_osc[i].usrWaveBtn = new pixmapButton( this );
468
m_osc[i].usrWaveBtn->move( 233, 120+i*50 );
469
m_osc[i].usrWaveBtn->setActiveGraphic( embed::getIconPixmap(
470
"usr_wave_active" ) );
471
m_osc[i].usrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
472
"usr_wave_inactive" ) );
473
toolTip::add( m_osc[i].usrWaveBtn,
474
tr( "Click here if you want a user-defined "
475
"wave-shape for current oscillator." ) );
477
QButtonGroup * wave_btn_group = new QButtonGroup( this );
478
wave_btn_group->addButton( m_osc[i].sinWaveBtn );
479
wave_btn_group->addButton( m_osc[i].triangleWaveBtn );
480
wave_btn_group->addButton( m_osc[i].sawWaveBtn );
481
wave_btn_group->addButton( m_osc[i].sqrWaveBtn );
482
wave_btn_group->addButton( m_osc[i].moogSawWaveBtn );
483
wave_btn_group->addButton( m_osc[i].expWaveBtn );
484
wave_btn_group->addButton( m_osc[i].whiteNoiseWaveBtn );
485
wave_btn_group->addButton( m_osc[i].usrWaveBtn );
486
wave_btn_group->setExclusive( TRUE );
488
wave_btn_group->hide();
493
connect( m_osc[i].sinWaveBtn,
494
SIGNAL( toggled( bool ) ), this,
495
SLOT( osc01SinWaveCh( bool ) ) );
496
connect( m_osc[i].triangleWaveBtn,
497
SIGNAL( toggled( bool ) ), this,
498
SLOT( osc01TriangleWaveCh( bool ) ) );
499
connect( m_osc[i].sawWaveBtn,
500
SIGNAL( toggled( bool ) ), this,
501
SLOT( osc01SawWaveCh( bool ) ) );
502
connect( m_osc[i].sqrWaveBtn,
503
SIGNAL( toggled( bool ) ), this,
504
SLOT( osc01SquareWaveCh( bool ) ) );
505
connect( m_osc[i].moogSawWaveBtn,
506
SIGNAL(toggled( bool ) ), this,
507
SLOT( osc01MoogSawWaveCh( bool ) ) );
508
connect( m_osc[i].expWaveBtn,
509
SIGNAL( toggled( bool ) ), this,
510
SLOT( osc01ExpWaveCh( bool ) ) );
511
connect( m_osc[i].whiteNoiseWaveBtn,
512
SIGNAL( toggled( bool ) ), this,
513
SLOT( osc01WhiteNoiseCh( bool ) ) );
514
connect( m_osc[i].usrWaveBtn,
515
SIGNAL( toggled( bool ) ), this,
516
SLOT( osc01UserDefWaveCh( bool ) ) );
517
connect( m_osc[i].usrWaveBtn,
518
SIGNAL( doubleClicked() ), this,
519
SLOT( osc01UserDefWaveDblClick() ) );
523
connect( m_osc[i].sinWaveBtn,
524
SIGNAL( toggled( bool ) ), this,
525
SLOT( osc02SinWaveCh( bool ) ) );
526
connect( m_osc[i].triangleWaveBtn,
527
SIGNAL( toggled( bool ) ), this,
528
SLOT( osc02TriangleWaveCh( bool ) ) );
529
connect( m_osc[i].sawWaveBtn,
530
SIGNAL( toggled( bool ) ), this,
531
SLOT( osc02SawWaveCh( bool ) ) );
532
connect( m_osc[i].sqrWaveBtn,
533
SIGNAL( toggled( bool ) ), this,
534
SLOT( osc02SquareWaveCh( bool ) ) );
535
connect( m_osc[i].moogSawWaveBtn,
536
SIGNAL( toggled( bool ) ), this,
537
SLOT( osc02MoogSawWaveCh( bool ) ) );
538
connect( m_osc[i].expWaveBtn,
539
SIGNAL( toggled( bool ) ), this,
540
SLOT( osc02ExpWaveCh( bool ) ) );
541
connect( m_osc[i].whiteNoiseWaveBtn,
542
SIGNAL( toggled( bool ) ), this,
543
SLOT( osc02WhiteNoiseCh( bool ) ) );
544
connect( m_osc[i].usrWaveBtn,
545
SIGNAL( toggled( bool ) ), this,
546
SLOT( osc02UserDefWaveCh( bool ) ) );
547
connect( m_osc[i].usrWaveBtn,
548
SIGNAL( doubleClicked() ), this,
549
SLOT( osc02UserDefWaveDblClick() ) );
553
connect( m_osc[i].sinWaveBtn,
554
SIGNAL( toggled( bool ) ), this,
555
SLOT( osc03SinWaveCh( bool ) ) );
556
connect( m_osc[i].triangleWaveBtn,
557
SIGNAL( toggled( bool ) ), this,
558
SLOT( osc03TriangleWaveCh( bool ) ) );
559
connect( m_osc[i].sawWaveBtn,
560
SIGNAL( toggled( bool ) ), this,
561
SLOT( osc03SawWaveCh( bool ) ) );
562
connect( m_osc[i].sqrWaveBtn,
563
SIGNAL( toggled( bool ) ), this,
564
SLOT( osc03SquareWaveCh( bool ) ) );
565
connect( m_osc[i].moogSawWaveBtn,
566
SIGNAL( toggled( bool ) ), this,
567
SLOT( osc03MoogSawWaveCh( bool ) ) );
568
connect( m_osc[i].expWaveBtn,
569
SIGNAL( toggled( bool ) ), this,
570
SLOT( osc03ExpWaveCh( bool ) ) );
571
connect( m_osc[i].whiteNoiseWaveBtn,
572
SIGNAL( toggled( bool ) ), this,
573
SLOT( osc03WhiteNoiseCh( bool ) ) );
574
connect( m_osc[i].usrWaveBtn,
575
SIGNAL( toggled( bool ) ), this,
576
SLOT( osc03UserDefWaveCh( bool ) ) );
577
connect( m_osc[i].usrWaveBtn,
578
SIGNAL( doubleClicked() ), this,
579
SLOT( osc03UserDefWaveDblClick() ) );
587
tripleOscillator::~tripleOscillator()
594
void tripleOscillator::saveSettings( QDomDocument & _doc,
595
QDomElement & _parent )
597
QDomElement to_de = _doc.createElement( nodeName() );
598
to_de.setAttribute( "modalgo1", QString::number( m_modulationAlgo1 ) );
599
to_de.setAttribute( "modalgo2", QString::number( m_modulationAlgo2 ) );
601
for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
603
QString is = QString::number( i );
604
to_de.setAttribute( "vol" + is, QString::number(
605
m_osc[i].volKnob->value() ) );
606
to_de.setAttribute( "pan" + is, QString::number(
607
m_osc[i].panKnob->value() ) );
608
to_de.setAttribute( "coarse" + is, QString::number(
609
m_osc[i].coarseKnob->value() ) );
610
to_de.setAttribute( "finel" + is, QString::number(
611
m_osc[i].fineLKnob->value() ) );
612
to_de.setAttribute( "finer" + is, QString::number(
613
m_osc[i].fineRKnob->value() ) );
614
to_de.setAttribute( "phoffset" + is, QString::number(
615
m_osc[i].phaseOffsetKnob->value() ) );
616
to_de.setAttribute( "stphdetun" + is, QString::number(
617
m_osc[i].stereoPhaseDetuningKnob->value() ) );
618
to_de.setAttribute( "wavetype" + is, QString::number(
619
m_osc[i].waveShape ) );
620
to_de.setAttribute( "userwavefile" + is,
621
m_osc[i].m_sampleBuffer.audioFile() );
624
_parent.appendChild( to_de );
630
void tripleOscillator::loadSettings( const QDomElement & _this )
632
m_modulationAlgo1 = static_cast<oscillator::modulationAlgos>(
633
_this.attribute( "modalgo1" ).toInt() );
634
m_modulationAlgo2 = static_cast<oscillator::modulationAlgos>(
635
_this.attribute( "modalgo2" ).toInt() );
637
getModulationButton( m_modulationAlgo1, 1 )->setChecked( TRUE );
638
getModulationButton( m_modulationAlgo2, 2 )->setChecked( TRUE );
640
for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
642
QString is = QString::number( i );
643
m_osc[i].volKnob->setValue( _this.attribute( "vol" + is ).
645
m_osc[i].panKnob->setValue( _this.attribute( "pan" + is ).
647
m_osc[i].coarseKnob->setValue( _this.attribute( "coarse" + is ).
649
m_osc[i].fineLKnob->setValue( _this.attribute( "finel" + is ).
651
m_osc[i].fineRKnob->setValue( _this.attribute( "finer" + is ).
653
m_osc[i].phaseOffsetKnob->setValue( _this.attribute(
654
"phoffset" + is ).toFloat() );
655
m_osc[i].stereoPhaseDetuningKnob->setValue( _this.attribute(
656
"stphdetun" + is ).toFloat() );
657
m_osc[i].m_sampleBuffer.setAudioFile( _this.attribute(
658
"userwavefile" + is ) );
659
switch( _this.attribute( "wavetype" + is ).toInt() )
661
case oscillator::TRIANGLE_WAVE:
662
m_osc[i].triangleWaveBtn->setChecked( TRUE );
664
case oscillator::SAW_WAVE:
665
m_osc[i].sawWaveBtn->setChecked( TRUE );
667
case oscillator::SQUARE_WAVE:
668
m_osc[i].sqrWaveBtn->setChecked( TRUE );
670
case oscillator::MOOG_SAW_WAVE:
671
m_osc[i].moogSawWaveBtn->setChecked( TRUE );
673
case oscillator::EXP_WAVE:
674
m_osc[i].expWaveBtn->setChecked( TRUE );
676
case oscillator::WHITE_NOISE_WAVE:
677
m_osc[i].whiteNoiseWaveBtn->setChecked( TRUE );
679
case oscillator::USER_DEF_WAVE:
680
toolTip::add( m_osc[i].usrWaveBtn,
681
m_osc[i].m_sampleBuffer.audioFile() );
682
m_osc[i].usrWaveBtn->setChecked( TRUE );
684
case oscillator::SIN_WAVE:
686
m_osc[i].sinWaveBtn->setChecked( TRUE );
695
QDomElement tripleOscillator::defaultSettings( void )
698
QDomElement e = d.createElement( s_pluginNodeName );
699
e.setAttribute( "modalgo1", QString::number( oscillator::MIX ) );
700
e.setAttribute( "modalgo2", QString::number( oscillator::MIX ) );
702
for( int i = 0; i < NUM_OF_OSCILLATORS; ++i )
704
QString is = QString::number( i );
705
e.setAttribute( "vol" + is, QString::number( DEFAULT_VOLUME ) );
706
e.setAttribute( "pan" + is,
707
QString::number( DEFAULT_PANNING ) );
708
e.setAttribute( "coarse" + is, QString::number( 0 ) );
709
e.setAttribute( "finel" + is, QString::number( 0 ) );
710
e.setAttribute( "finer" + is, QString::number( 0 ) );
711
e.setAttribute( "phoffset" + is, QString::number( 0 ) );
712
e.setAttribute( "stphdetun" + is, QString::number( 0 ) );
713
e.setAttribute( "wavetype" + is, QString::number(
714
oscillator::SIN_WAVE ) );
715
e.setAttribute( "userwavefile" + is, "" );
723
void tripleOscillator::playNote( notePlayHandle * _n )
725
if( _n->totalFramesPlayed() == 0 )
727
float freq = getChannelTrack()->frequency( _n );
729
oscillator * oscs_l[NUM_OF_OSCILLATORS];
730
oscillator * oscs_r[NUM_OF_OSCILLATORS];
732
for( Sint8 i = NUM_OF_OSCILLATORS-1; i >= 0; --i )
735
float osc_detuning_l = pow( 2.0, (
736
(float)m_osc[i].coarseKnob->value() * 100.0f +
737
(float)m_osc[i].fineLKnob->value() ) / 1200.0f);
738
float osc_detuning_r = pow( 2.0, (
739
(float)m_osc[i].coarseKnob->value() * 100.0f +
740
(float)m_osc[i].fineRKnob->value() ) / 1200.0f);
742
float vol_fac_l = ( m_osc[i].panKnob->value() +
743
PANNING_RIGHT ) / 100.0f;
744
float vol_fac_r = ( PANNING_RIGHT -
745
m_osc[i].panKnob->value() ) /
748
if( vol_fac_l > 1.0f )
752
if( vol_fac_r > 1.0f )
757
vol_fac_l *= m_osc[i].volKnob->value() / 100.0f;
758
vol_fac_r *= m_osc[i].volKnob->value() / 100.0f;
760
// the third oscs needs no sub-oscs...
763
oscs_l[i] = oscillator::createNewOsc(
768
m_osc[i].phaseOffsetKnob->value() +
769
m_osc[i].stereoPhaseDetuningKnob->value() ),
771
oscs_r[i] = oscillator::createNewOsc(
776
m_osc[i].phaseOffsetKnob->value() ),
781
oscs_l[i] = oscillator::createNewOsc(
783
getModulationAlgo( i + 1 ),
786
m_osc[i].phaseOffsetKnob->value() +
787
m_osc[i].stereoPhaseDetuningKnob->value() ),
788
vol_fac_l, oscs_l[i + 1] );
789
oscs_r[i] = oscillator::createNewOsc(
791
getModulationAlgo( i + 1 ),
794
m_osc[i].phaseOffsetKnob->value() ),
799
if( m_osc[i].waveShape == oscillator::USER_DEF_WAVE )
801
oscs_l[i]->setUserWave(
802
m_osc[i].m_sampleBuffer.data(),
803
m_osc[i].m_sampleBuffer.frames() );
804
oscs_r[i]->setUserWave(
805
m_osc[i].m_sampleBuffer.data(),
806
m_osc[i].m_sampleBuffer.frames() );
811
_n->m_pluginData = new oscPtr;
812
static_cast<oscPtr *>( _n->m_pluginData )->oscLeft = oscs_l[0];
813
static_cast< oscPtr *>( _n->m_pluginData )->oscRight =
817
oscillator * osc_l = static_cast<oscPtr *>( _n->m_pluginData )->oscLeft;
818
oscillator * osc_r = static_cast<oscPtr *>( _n->m_pluginData
821
const Uint32 frames = mixer::inst()->framesPerAudioBuffer();
822
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( frames );
824
osc_l->update( buf, frames, 0 );
825
osc_r->update( buf, frames, 1 );
827
processAudioBuffer( buf, frames, _n );
829
bufferAllocator::free( buf );
835
void tripleOscillator::deleteNotePluginData( notePlayHandle * _n )
837
if( _n->m_pluginData == NULL )
841
delete static_cast<oscillator *>( static_cast<oscPtr *>(
842
_n->m_pluginData )->oscLeft );
843
delete static_cast<oscillator *>( static_cast<oscPtr *>(
844
_n->m_pluginData )->oscRight );
845
delete static_cast<oscPtr *>( _n->m_pluginData );
851
// now follows all the stupid UI-Code...
853
void tripleOscillator::setModulationAlgo(
854
oscillator::modulationAlgos _new_modulation_algo, int _n )
858
m_modulationAlgo1 = _new_modulation_algo;
862
m_modulationAlgo2 = _new_modulation_algo;
865
songEditor::inst()->setModified();
871
oscillator::modulationAlgos tripleOscillator::getModulationAlgo( int _n )
875
return( m_modulationAlgo1 );
879
return( m_modulationAlgo2 );
886
void tripleOscillator::doSinWaveBtn( oscillatorData * _osc )
888
_osc->waveShape = oscillator::SIN_WAVE;
889
songEditor::inst()->setModified();
895
void tripleOscillator::doTriangleWaveBtn( oscillatorData * _osc )
897
_osc->waveShape = oscillator::TRIANGLE_WAVE;
898
songEditor::inst()->setModified();
904
void tripleOscillator::doSawWaveBtn( oscillatorData * _osc )
906
_osc->waveShape = oscillator::SAW_WAVE;
907
songEditor::inst()->setModified();
913
void tripleOscillator::doSqrWaveBtn( oscillatorData * _osc )
915
_osc->waveShape = oscillator::SQUARE_WAVE;
916
songEditor::inst()->setModified();
922
void tripleOscillator::doMoogSawWaveBtn( oscillatorData * _osc )
924
_osc->waveShape = oscillator::MOOG_SAW_WAVE;
925
songEditor::inst()->setModified();
931
void tripleOscillator::doExpWaveBtn( oscillatorData * _osc )
933
_osc->waveShape = oscillator::EXP_WAVE;
934
songEditor::inst()->setModified();
940
void tripleOscillator::doWhiteNoiseWaveBtn( oscillatorData * _osc )
942
_osc->waveShape = oscillator::WHITE_NOISE_WAVE;
943
songEditor::inst()->setModified();
949
void tripleOscillator::doUsrWaveBtn( oscillatorData * _osc )
951
_osc->waveShape = oscillator::USER_DEF_WAVE;
952
songEditor::inst()->setModified();
958
void tripleOscillator::osc01SinWaveCh( bool _on )
960
if( _on ) doSinWaveBtn( &m_osc[0] );
963
void tripleOscillator::osc01TriangleWaveCh( bool _on )
965
if( _on ) doTriangleWaveBtn( &m_osc[0] );
968
void tripleOscillator::osc01SawWaveCh( bool _on )
970
if( _on ) doSawWaveBtn( &m_osc[0] );
973
void tripleOscillator::osc01SquareWaveCh( bool _on )
975
if( _on ) doSqrWaveBtn( &m_osc[0] );
978
void tripleOscillator::osc01MoogSawWaveCh( bool _on )
980
if( _on ) doMoogSawWaveBtn( &m_osc[0] );
983
void tripleOscillator::osc01ExpWaveCh( bool _on )
985
if( _on ) doExpWaveBtn( &m_osc[0] );
988
void tripleOscillator::osc01WhiteNoiseCh( bool _on )
990
if( _on ) doWhiteNoiseWaveBtn( &m_osc[0] );
993
void tripleOscillator::osc01UserDefWaveCh( bool _on )
995
if( _on ) doUsrWaveBtn( &m_osc[0] );
998
void tripleOscillator::osc01UserDefWaveDblClick( void )
1000
QString af = m_osc[0].m_sampleBuffer.openAudioFile();
1003
m_osc[0].m_sampleBuffer.setAudioFile( af );
1005
toolTip::remove( m_osc[0].usrWaveBtn );
1007
toolTip::add( m_osc[0].usrWaveBtn,
1008
m_osc[0].m_sampleBuffer.audioFile() );
1015
void tripleOscillator::osc02SinWaveCh( bool _on )
1017
if( _on ) doSinWaveBtn( &m_osc[1] );
1020
void tripleOscillator::osc02TriangleWaveCh( bool _on )
1022
if( _on ) doTriangleWaveBtn( &m_osc[1] );
1025
void tripleOscillator::osc02SawWaveCh( bool _on )
1027
if( _on ) doSawWaveBtn( &m_osc[1] );
1030
void tripleOscillator::osc02SquareWaveCh( bool _on )
1032
if( _on ) doSqrWaveBtn( &m_osc[1] );
1035
void tripleOscillator::osc02MoogSawWaveCh( bool _on )
1037
if( _on ) doMoogSawWaveBtn( &m_osc[1] );
1040
void tripleOscillator::osc02ExpWaveCh( bool _on )
1042
if( _on ) doExpWaveBtn( &m_osc[1] );
1045
void tripleOscillator::osc02WhiteNoiseCh( bool _on )
1047
if( _on ) doWhiteNoiseWaveBtn( &m_osc[1] );
1050
void tripleOscillator::osc02UserDefWaveCh( bool _on )
1052
if( _on ) doUsrWaveBtn( &m_osc[1] );
1055
void tripleOscillator::osc02UserDefWaveDblClick( void )
1057
QString af = m_osc[1].m_sampleBuffer.openAudioFile();
1060
m_osc[1].m_sampleBuffer.setAudioFile( af );
1062
toolTip::remove( m_osc[1].usrWaveBtn );
1064
toolTip::add( m_osc[1].usrWaveBtn,
1065
m_osc[1].m_sampleBuffer.audioFile() );
1071
void tripleOscillator::osc03SinWaveCh( bool _on )
1073
if( _on ) doSinWaveBtn( &m_osc[2] );
1076
void tripleOscillator::osc03TriangleWaveCh( bool _on )
1078
if( _on ) doTriangleWaveBtn( &m_osc[2] );
1081
void tripleOscillator::osc03SawWaveCh( bool _on )
1083
if( _on ) doSawWaveBtn( &m_osc[2] );
1086
void tripleOscillator::osc03SquareWaveCh( bool _on )
1088
if( _on ) doSqrWaveBtn( &m_osc[2] );
1091
void tripleOscillator::osc03MoogSawWaveCh( bool _on )
1093
if( _on ) doMoogSawWaveBtn( &m_osc[2] );
1096
void tripleOscillator::osc03ExpWaveCh( bool _on )
1098
if( _on ) doExpWaveBtn( &m_osc[2] );
1101
void tripleOscillator::osc03WhiteNoiseCh( bool _on )
1103
if( _on ) doWhiteNoiseWaveBtn( &m_osc[2] );
1106
void tripleOscillator::osc03UserDefWaveCh( bool _on )
1108
if( _on ) doUsrWaveBtn( &m_osc[2] );
1111
void tripleOscillator::osc03UserDefWaveDblClick( void )
1113
QString af = m_osc[2].m_sampleBuffer.openAudioFile();
1116
m_osc[2].m_sampleBuffer.setAudioFile( af );
1118
toolTip::remove( m_osc[2].usrWaveBtn );
1120
toolTip::add( m_osc[2].usrWaveBtn,
1121
m_osc[2].m_sampleBuffer.audioFile() );
1128
void tripleOscillator::fm1BtnToggled( bool _on )
1130
if( _on ) setModulationAlgo( oscillator::FREQ_MODULATION, 1 );
1135
void tripleOscillator::am1BtnToggled( bool _on )
1137
if( _on ) setModulationAlgo( oscillator::AMP_MODULATION, 1 );
1142
void tripleOscillator::mix1BtnToggled( bool _on )
1144
if( _on ) setModulationAlgo( oscillator::MIX, 1 );
1149
void tripleOscillator::sync1BtnToggled( bool _on )
1151
if( _on ) setModulationAlgo( oscillator::SYNC, 1 );
1156
void tripleOscillator::fm2BtnToggled( bool _on )
1158
if( _on ) setModulationAlgo( oscillator::FREQ_MODULATION, 2 );
1163
void tripleOscillator::am2BtnToggled( bool _on )
1165
if( _on ) setModulationAlgo( oscillator::AMP_MODULATION, 2 );
1170
void tripleOscillator::mix2BtnToggled( bool _on )
1172
if( _on ) setModulationAlgo( oscillator::MIX, 2 );
1177
void tripleOscillator::sync2BtnToggled( bool _on )
1179
if( _on ) setModulationAlgo( oscillator::SYNC, 2 );
1185
pixmapButton * tripleOscillator::getModulationButton(
1186
oscillator::modulationAlgos _modulation_algo, int _n )
1190
switch( _modulation_algo )
1192
case oscillator::FREQ_MODULATION: return( m_fm1OscBtn );
1193
case oscillator::AMP_MODULATION: return( m_am1OscBtn );
1194
case oscillator::MIX: return( m_mix1OscBtn );
1195
case oscillator::SYNC: return( m_sync1OscBtn );
1200
switch( _modulation_algo )
1202
case oscillator::FREQ_MODULATION: return( m_fm2OscBtn );
1203
case oscillator::AMP_MODULATION: return( m_am2OscBtn );
1204
case oscillator::MIX: return( m_mix2OscBtn );
1205
case oscillator::SYNC: return( m_sync2OscBtn );
1209
// there's something really not ok, if this case occurs, so let's exit
1220
#include "triple_oscillator.moc"