2
* Watsyn.cpp - a 4-oscillator modulating wavetable synth
4
* Copyright (c) 2014 Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>
6
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
8
* This program is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* General Public License for more details.
18
* You should have received a copy of the GNU General Public
19
* License along with this program (see COPYING); if not, write to the
20
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21
* Boston, MA 02110-1301 USA.
25
#include <QtXml/QDomElement>
29
#include "InstrumentTrack.h"
30
#include "templates.h"
33
#include "lmms_math.h"
40
Plugin::Descriptor PLUGIN_EXPORT watsyn_plugin_descriptor =
42
STRINGIFY( PLUGIN_NAME ),
44
QT_TRANSLATE_NOOP( "pluginBrowser",
45
"4-oscillator modulatable wavetable synth" ),
46
"Vesa Kivimäki <contact/dot/diizy/at/nbl/dot/fi>",
49
new PluginPixmapLoader( "logo" ),
59
WatsynObject::WatsynObject( float * _A1wave, float * _A2wave,
60
float * _B1wave, float * _B2wave,
61
int _amod, int _bmod, const sample_rate_t _samplerate, NotePlayHandle * _nph, fpp_t _frames,
62
WatsynInstrument * _w ) :
65
m_samplerate( _samplerate ),
70
m_abuf = new sampleFrame[_frames];
71
m_bbuf = new sampleFrame[_frames];
73
m_lphase[A1_OSC] = 0.0f;
74
m_lphase[A2_OSC] = 0.0f;
75
m_lphase[B1_OSC] = 0.0f;
76
m_lphase[B2_OSC] = 0.0f;
78
m_rphase[A1_OSC] = 0.0f;
79
m_rphase[A2_OSC] = 0.0f;
80
m_rphase[B1_OSC] = 0.0f;
81
m_rphase[B2_OSC] = 0.0f;
83
// copy wavegraphs to the synth object to prevent race conditions
85
memcpy( &m_A1wave, _A1wave, sizeof( m_A1wave ) );
86
memcpy( &m_A2wave, _A2wave, sizeof( m_A2wave ) );
87
memcpy( &m_B1wave, _B1wave, sizeof( m_B1wave ) );
88
memcpy( &m_B2wave, _B2wave, sizeof( m_B2wave ) );
93
WatsynObject::~WatsynObject()
100
void WatsynObject::renderOutput( fpp_t _frames )
103
m_abuf = new sampleFrame[m_fpp];
105
m_bbuf = new sampleFrame[m_fpp];
107
for( fpp_t frame = 0; frame < _frames; frame++ )
109
// put phases of 1-series oscs into variables because phase modulation might happen
110
float A1_lphase = m_lphase[A1_OSC];
111
float A1_rphase = m_rphase[A1_OSC];
112
float B1_lphase = m_lphase[B1_OSC];
113
float B1_rphase = m_rphase[B1_OSC];
115
///////////// A-series /////////////////
118
sample_t A2_L = m_A2wave[ static_cast<int>( m_lphase[A2_OSC] ) ] * m_parent->m_lvol[A2_OSC];
119
/*interpolate( m_A2wave[ static_cast<int>( m_lphase[A2_OSC] ) % WAVELEN ],
120
m_A2wave[ static_cast<int>( m_lphase[A2_OSC] + 1 ) % WAVELEN ],
121
fraction( m_lphase[A2_OSC] ) ) * m_parent->m_lvol[A2_OSC];*/
122
sample_t A2_R = m_A2wave[ static_cast<int>( m_rphase[A2_OSC] ) ] * m_parent->m_rvol[A2_OSC];
123
/*interpolate( m_A2wave[ static_cast<int>( m_rphase[A2_OSC] ) % WAVELEN ],
124
m_A2wave[ static_cast<int>( m_rphase[A2_OSC] + 1 ) % WAVELEN ],
125
fraction( m_rphase[A2_OSC] ) ) * m_parent->m_rvol[A2_OSC];*/
126
// if phase mod, add to phases
127
if( m_amod == MOD_PM )
129
A1_lphase = fmodf( A1_lphase + A2_L * PMOD_AMT, WAVELEN );
130
if( A1_lphase < 0 ) A1_lphase += WAVELEN;
131
A1_rphase = fmodf( A1_rphase + A2_R * PMOD_AMT, WAVELEN );
132
if( A1_rphase < 0 ) A1_rphase += WAVELEN;
135
sample_t A1_L = interpolate( m_A1wave[ static_cast<int>( A1_lphase ) ],
136
m_A1wave[ static_cast<int>( A1_lphase + 1 ) % WAVELEN ],
137
fraction( A1_lphase ) ) * m_parent->m_lvol[A1_OSC];
138
sample_t A1_R = interpolate( m_A1wave[ static_cast<int>( A1_rphase ) ],
139
m_A1wave[ static_cast<int>( A1_rphase + 1 ) % WAVELEN ],
140
fraction( A1_rphase ) ) * m_parent->m_rvol[A1_OSC];
142
///////////// B-series /////////////////
145
sample_t B2_L = m_B2wave[ static_cast<int>( m_lphase[B2_OSC] ) ] * m_parent->m_lvol[B2_OSC];
146
/*interpolate( m_B2wave[ static_cast<int>( m_lphase[B2_OSC] ) % WAVELEN ],
147
m_B2wave[ static_cast<int>( m_lphase[B2_OSC] + 1 ) % WAVELEN ],
148
fraction( m_lphase[B2_OSC] ) ) * m_parent->m_lvol[B2_OSC];*/
149
sample_t B2_R = m_B2wave[ static_cast<int>( m_rphase[B2_OSC] ) ] * m_parent->m_rvol[B2_OSC];
150
/*interpolate( m_B2wave[ static_cast<int>( m_rphase[B2_OSC] ) % WAVELEN ],
151
m_B2wave[ static_cast<int>( m_rphase[B2_OSC] + 1 ) % WAVELEN ],
152
fraction( m_rphase[B2_OSC] ) ) * m_parent->m_rvol[B2_OSC];*/
154
// if crosstalk active, add a1
155
const float xt = m_parent->m_xtalk.value();
158
B2_L += ( A1_L * xt ) / 100.0f;
159
B2_R += ( A1_R * xt ) / 100.0f;
162
// if phase mod, add to phases
163
if( m_bmod == MOD_PM )
165
B1_lphase = fmodf( B1_lphase + B2_L * PMOD_AMT, WAVELEN );
166
if( B1_lphase < 0 ) B1_lphase += WAVELEN;
167
B1_rphase = fmodf( B1_rphase + B2_R * PMOD_AMT, WAVELEN );
168
if( B1_rphase < 0 ) B1_rphase += WAVELEN;
171
sample_t B1_L = interpolate( m_B1wave[ static_cast<int>( B1_lphase ) % WAVELEN ],
172
m_B1wave[ static_cast<int>( B1_lphase + 1 ) % WAVELEN ],
173
fraction( B1_lphase ) ) * m_parent->m_lvol[B1_OSC];
174
sample_t B1_R = interpolate( m_B1wave[ static_cast<int>( B1_rphase ) % WAVELEN ],
175
m_B1wave[ static_cast<int>( B1_rphase + 1 ) % WAVELEN ],
176
fraction( B1_rphase ) ) * m_parent->m_rvol[B1_OSC];
179
// A-series modulation)
183
A1_L = ( A1_L + A2_L ) / 2.0;
184
A1_R = ( A1_R + A2_R ) / 2.0;
187
A1_L *= qMax( 0.0f, A2_L + 1.0f );
188
A1_R *= qMax( 0.0f, A2_R + 1.0f );
195
m_abuf[frame][0] = A1_L;
196
m_abuf[frame][1] = A1_R;
198
// B-series modulation (other than phase mod)
202
B1_L = ( B1_L + B2_L ) / 2.0;
203
B1_R = ( B1_R + B2_R ) / 2.0;
206
B1_L *= qMax( 0.0f, B2_L + 1.0f );
207
B1_R *= qMax( 0.0f, B2_R + 1.0f );
214
m_bbuf[frame][0] = B1_L;
215
m_bbuf[frame][1] = B1_R;
218
for( int i = 0; i < NUM_OSCS; i++ )
220
m_lphase[i] += ( static_cast<float>( WAVELEN ) / ( m_samplerate / ( m_nph->frequency() * m_parent->m_lfreq[i] ) ) );
221
m_lphase[i] = fmodf( m_lphase[i], WAVELEN );
222
m_rphase[i] += ( static_cast<float>( WAVELEN ) / ( m_samplerate / ( m_nph->frequency() * m_parent->m_rfreq[i] ) ) );
223
m_rphase[i] = fmodf( m_rphase[i], WAVELEN );
231
WatsynInstrument::WatsynInstrument( InstrumentTrack * _instrument_track ) :
232
Instrument( _instrument_track, &watsyn_plugin_descriptor ),
234
a1_vol( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Volume A1" ) ),
235
a2_vol( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Volume A2" ) ),
236
b1_vol( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Volume B1" ) ),
237
b2_vol( 100.0f, 0.0f, 200.0f, 0.1f, this, tr( "Volume B2" ) ),
239
a1_pan( 0.0f, -100.0f, 100.0f, 0.1f, this, tr( "Panning A1" ) ),
240
a2_pan( 0.0f, -100.0f, 100.0f, 0.1f, this, tr( "Panning A2" ) ),
241
b1_pan( 0.0f, -100.0f, 100.0f, 0.1f, this, tr( "Panning B1" ) ),
242
b2_pan( 0.0f, -100.0f, 100.0f, 0.1f, this, tr( "Panning B2" ) ),
244
a1_mult( 8.0f, 1.0, 24.0, 1.0, this, tr( "Freq. multiplier A1" ) ),
245
a2_mult( 8.0f, 1.0, 24.0, 1.0, this, tr( "Freq. multiplier A2" ) ),
246
b1_mult( 8.0f, 1.0, 24.0, 1.0, this, tr( "Freq. multiplier B1" ) ),
247
b2_mult( 8.0f, 1.0, 24.0, 1.0, this, tr( "Freq. multiplier B2" ) ),
249
a1_ltune( 0.0f, -600.0f, 600.0f, 1.0f, this, tr( "Left detune A1" ) ),
250
a2_ltune( 0.0f, -600.0f, 600.0f, 1.0f, this, tr( "Left detune A2" ) ),
251
b1_ltune( 0.0f, -600.0f, 600.0f, 1.0f, this, tr( "Left detune B1" ) ),
252
b2_ltune( 0.0f, -600.0f, 600.0f, 1.0f, this, tr( "Left detune B2" ) ),
254
a1_rtune( 0.0f, -600.0f, 600.0f, 1.0f, this, tr( "Right detune A1" ) ),
255
a2_rtune( 0.0f, -600.0f, 600.0f, 1.0f, this, tr( "Right detune A2" ) ),
256
b1_rtune( 0.0f, -600.0f, 600.0f, 1.0f, this, tr( "Right detune B1" ) ),
257
b2_rtune( 0.0f, -600.0f, 600.0f, 1.0f, this, tr( "Right detune B2" ) ),
259
a1_graph( -1.0f, 1.0f, GRAPHLEN, this ),
260
a2_graph( -1.0f, 1.0f, GRAPHLEN, this ),
261
b1_graph( -1.0f, 1.0f, GRAPHLEN, this ),
262
b2_graph( -1.0f, 1.0f, GRAPHLEN, this ),
264
m_abmix( 0.0f, -100.0f, 100.0f, 0.1f, this, tr( "A-B Mix" ) ),
265
m_envAmt( 0.0f, -200.0f, 200.0f, 1.0f, this, tr( "A-B Mix envelope amount" ) ),
267
m_envAtt( 0.0f, 0.0f, 2000.0f, 1.0f, 2000.0f, this, tr( "A-B Mix envelope attack" ) ),
268
m_envHold( 0.0f, 0.0f, 2000.0f, 1.0f, 2000.0f, this, tr( "A-B Mix envelope hold" ) ),
269
m_envDec( 0.0f, 0.0f, 2000.0f, 1.0f, 2000.0f, this, tr( "A-B Mix envelope decay" ) ),
271
m_xtalk( 0.0f, 0.0f, 100.0f, 0.1f, this, tr( "A1-B2 Crosstalk" ) ),
273
m_amod( 0, 0, 3, this, tr( "A2-A1 modulation" ) ),
274
m_bmod( 0, 0, 3, this, tr( "B2-B1 modulation" ) ),
276
m_selectedGraph( 0, 0, 3, this, tr( "Selected graph" ) )
278
connect( &a1_vol, SIGNAL( dataChanged() ), this, SLOT( updateVolumes() ) );
279
connect( &a2_vol, SIGNAL( dataChanged() ), this, SLOT( updateVolumes() ) );
280
connect( &b1_vol, SIGNAL( dataChanged() ), this, SLOT( updateVolumes() ) );
281
connect( &b2_vol, SIGNAL( dataChanged() ), this, SLOT( updateVolumes() ) );
283
connect( &a1_pan, SIGNAL( dataChanged() ), this, SLOT( updateVolumes() ) );
284
connect( &a2_pan, SIGNAL( dataChanged() ), this, SLOT( updateVolumes() ) );
285
connect( &b1_pan, SIGNAL( dataChanged() ), this, SLOT( updateVolumes() ) );
286
connect( &b2_pan, SIGNAL( dataChanged() ), this, SLOT( updateVolumes() ) );
288
connect( &a1_mult, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
289
connect( &a2_mult, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
290
connect( &b1_mult, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
291
connect( &b2_mult, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
293
connect( &a1_ltune, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
294
connect( &a2_ltune, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
295
connect( &b1_ltune, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
296
connect( &b2_ltune, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
298
connect( &a1_rtune, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
299
connect( &a2_rtune, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
300
connect( &b1_rtune, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
301
connect( &b2_rtune, SIGNAL( dataChanged() ), this, SLOT( updateFreq() ) );
303
connect( &a1_graph, SIGNAL( samplesChanged( int, int ) ), this, SLOT( updateWaves() ) );
304
connect( &a2_graph, SIGNAL( samplesChanged( int, int ) ), this, SLOT( updateWaves() ) );
305
connect( &b1_graph, SIGNAL( samplesChanged( int, int ) ), this, SLOT( updateWaves() ) );
306
connect( &b2_graph, SIGNAL( samplesChanged( int, int ) ), this, SLOT( updateWaves() ) );
308
a1_graph.setWaveToSine();
309
a2_graph.setWaveToSine();
310
b1_graph.setWaveToSine();
311
b2_graph.setWaveToSine();
319
WatsynInstrument::~WatsynInstrument()
324
void WatsynInstrument::playNote( NotePlayHandle * _n,
325
sampleFrame * _working_buffer )
327
if ( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL )
329
WatsynObject * w = new WatsynObject(
334
m_amod.value(), m_bmod.value(),
335
engine::mixer()->processingSampleRate(), _n,
336
engine::mixer()->framesPerPeriod(), this );
338
_n->m_pluginData = w;
341
const fpp_t frames = _n->framesLeftForCurrentPeriod();
343
WatsynObject * w = static_cast<WatsynObject *>( _n->m_pluginData );
345
sampleFrame * abuf = w->abuf();
346
sampleFrame * bbuf = w->bbuf();
348
w-> renderOutput( frames );
350
// envelope parameters
351
const float envAmt = m_envAmt.value();
352
const float envAtt = ( m_envAtt.value() * w->samplerate() ) / 1000.0f;
353
const float envHold = ( m_envHold.value() * w->samplerate() ) / 1000.0f;
354
const float envDec = ( m_envDec.value() * w->samplerate() ) / 1000.0f;
355
const float envLen = envAtt + envDec + envHold;
356
const float tfp_ = static_cast<float>( _n->totalFramesPlayed() );
358
// if sample-exact is enabled, use sample-exact calculations...
359
if( engine::mixer()->currentQualitySettings().sampleExactControllers )
361
for( fpp_t f=0; f < frames; f++ )
363
const float tfp = tfp_ + f;
364
// handle mixing envelope
365
float mixvalue = m_abmix.value( f );
366
if( envAmt != 0.0f && tfp < envLen )
370
mixvalue = qBound( -100.0f, mixvalue + ( tfp / envAtt * envAmt ), 100.0f );
372
else if ( tfp >= envAtt && tfp < envAtt + envHold )
374
mixvalue = qBound( -100.0f, mixvalue + envAmt, 100.0f );
378
mixvalue = qBound( -100.0f, mixvalue + envAmt - ( ( tfp - ( envAtt + envHold ) ) / envDec * envAmt ), 100.0f );
381
// get knob values in sample-exact way
382
const float bmix = ( ( mixvalue + 100.0 ) / 200.0 );
383
const float amix = 1.0 - bmix;
385
// mix a/b streams according to mixing knob
386
_working_buffer[f][0] = ( abuf[f][0] * amix ) +
387
( bbuf[f][0] * bmix );
388
_working_buffer[f][1] = ( abuf[f][1] * amix ) +
389
( bbuf[f][1] * bmix );
393
// if sample-exact is not enabled, use simpler calculations:
394
// if mix envelope is active, and we haven't gone past the envelope end, use envelope-aware calculation...
395
else if( envAmt != 0.0f && tfp_ < envLen )
397
const float mixvalue_ = m_abmix.value();
398
for( fpp_t f=0; f < frames; f++ )
400
float mixvalue = mixvalue_;
401
const float tfp = tfp_ + f;
402
// handle mixing envelope
405
mixvalue = qBound( -100.0f, mixvalue + ( tfp / envAtt * envAmt ), 100.0f );
407
else if ( tfp >= envAtt && tfp < envAtt + envHold )
409
mixvalue = qBound( -100.0f, mixvalue + envAmt, 100.0f );
413
mixvalue = qBound( -100.0f, mixvalue + envAmt - ( ( tfp - ( envAtt + envHold ) ) / envDec * envAmt ), 100.0f );
417
const float bmix = ( ( mixvalue + 100.0 ) / 200.0 );
418
const float amix = 1.0 - bmix;
420
// mix a/b streams according to mixing knob
421
_working_buffer[f][0] = ( abuf[f][0] * amix ) +
422
( bbuf[f][0] * bmix );
423
_working_buffer[f][1] = ( abuf[f][1] * amix ) +
424
( bbuf[f][1] * bmix );
428
// ... mix envelope is inactive or we've past the end of envelope, so use a faster calculation to save cpu
432
const float bmix = ( ( m_abmix.value() + 100.0 ) / 200.0 );
433
const float amix = 1.0 - bmix;
434
for( fpp_t f=0; f < frames; f++ )
436
// mix a/b streams according to mixing knob
437
_working_buffer[f][0] = ( abuf[f][0] * amix ) +
438
( bbuf[f][0] * bmix );
439
_working_buffer[f][1] = ( abuf[f][1] * amix ) +
440
( bbuf[f][1] * bmix );
444
applyRelease( _working_buffer, _n );
446
instrumentTrack()->processAudioBuffer( _working_buffer, frames, _n );
450
void WatsynInstrument::deleteNotePluginData( NotePlayHandle * _n )
452
delete static_cast<WatsynObject *>( _n->m_pluginData );
456
void WatsynInstrument::saveSettings( QDomDocument & _doc,
457
QDomElement & _this )
459
a1_vol.saveSettings( _doc, _this, "a1_vol" );
460
a2_vol.saveSettings( _doc, _this, "a2_vol" );
461
b1_vol.saveSettings( _doc, _this, "b1_vol" );
462
b2_vol.saveSettings( _doc, _this, "b2_vol" );
464
a1_pan.saveSettings( _doc, _this, "a1_pan" );
465
a2_pan.saveSettings( _doc, _this, "a2_pan" );
466
b1_pan.saveSettings( _doc, _this, "b1_pan" );
467
b2_pan.saveSettings( _doc, _this, "b2_pan" );
469
a1_mult.saveSettings( _doc, _this, "a1_mult" );
470
a2_mult.saveSettings( _doc, _this, "a2_mult" );
471
b1_mult.saveSettings( _doc, _this, "b1_mult" );
472
b2_mult.saveSettings( _doc, _this, "b2_mult" );
474
a1_ltune.saveSettings( _doc, _this, "a1_ltune" );
475
a2_ltune.saveSettings( _doc, _this, "a2_ltune" );
476
b1_ltune.saveSettings( _doc, _this, "b1_ltune" );
477
b2_ltune.saveSettings( _doc, _this, "b2_ltune" );
479
a1_rtune.saveSettings( _doc, _this, "a1_rtune" );
480
a2_rtune.saveSettings( _doc, _this, "a2_rtune" );
481
b1_rtune.saveSettings( _doc, _this, "b1_rtune" );
482
b2_rtune.saveSettings( _doc, _this, "b2_rtune" );
485
QString sampleString;
487
base64::encode( (const char *)a1_graph.samples(), a1_graph.length() * sizeof(float), sampleString );
488
_this.setAttribute( "a1_wave", sampleString );
489
base64::encode( (const char *)a2_graph.samples(), a2_graph.length() * sizeof(float), sampleString );
490
_this.setAttribute( "a2_wave", sampleString );
491
base64::encode( (const char *)b1_graph.samples(), b1_graph.length() * sizeof(float), sampleString );
492
_this.setAttribute( "b1_wave", sampleString );
493
base64::encode( (const char *)b2_graph.samples(), b2_graph.length() * sizeof(float), sampleString );
494
_this.setAttribute( "b2_wave", sampleString );
496
m_abmix.saveSettings( _doc, _this, "abmix" );
497
m_envAmt.saveSettings( _doc, _this, "envAmt" );
498
m_envAtt.saveSettings( _doc, _this, "envAtt" );
499
m_envHold.saveSettings( _doc, _this, "envHold" );
500
m_envDec.saveSettings( _doc, _this, "envDec" );
502
m_xtalk.saveSettings( _doc, _this, "xtalk" );
504
m_amod.saveSettings( _doc, _this, "amod" );
505
m_bmod.saveSettings( _doc, _this, "bmod" );
506
/* m_selectedGraph.saveSettings( _doc, _this, "selgraph" );*/
510
void WatsynInstrument::loadSettings( const QDomElement & _this )
512
a1_vol.loadSettings( _this, "a1_vol" );
513
a2_vol.loadSettings( _this, "a2_vol" );
514
b1_vol.loadSettings( _this, "b1_vol" );
515
b2_vol.loadSettings( _this, "b2_vol" );
517
a1_pan.loadSettings( _this, "a1_pan" );
518
a2_pan.loadSettings( _this, "a2_pan" );
519
b1_pan.loadSettings( _this, "b1_pan" );
520
b2_pan.loadSettings( _this, "b2_pan" );
522
a1_mult.loadSettings( _this, "a1_mult" );
523
a2_mult.loadSettings( _this, "a2_mult" );
524
b1_mult.loadSettings( _this, "b1_mult" );
525
b2_mult.loadSettings( _this, "b2_mult" );
527
a1_ltune.loadSettings( _this, "a1_ltune" );
528
a2_ltune.loadSettings( _this, "a2_ltune" );
529
b1_ltune.loadSettings( _this, "b1_ltune" );
530
b2_ltune.loadSettings( _this, "b2_ltune" );
532
a1_rtune.loadSettings( _this, "a1_rtune" );
533
a2_rtune.loadSettings( _this, "a2_rtune" );
534
b1_rtune.loadSettings( _this, "b1_rtune" );
535
b2_rtune.loadSettings( _this, "b2_rtune" );
541
base64::decode( _this.attribute( "a1_wave"), &dst, &size );
542
a1_graph.setSamples( (float*) dst );
543
base64::decode( _this.attribute( "a2_wave"), &dst, &size );
544
a2_graph.setSamples( (float*) dst );
545
base64::decode( _this.attribute( "b1_wave"), &dst, &size );
546
b1_graph.setSamples( (float*) dst );
547
base64::decode( _this.attribute( "b2_wave"), &dst, &size );
548
b2_graph.setSamples( (float*) dst );
552
m_abmix.loadSettings( _this, "abmix" );
554
m_envAmt.loadSettings( _this, "envAmt" );
555
m_envAtt.loadSettings( _this, "envAtt" );
556
m_envHold.loadSettings( _this, "envHold" );
557
m_envDec.loadSettings( _this, "envDec" );
559
m_xtalk.loadSettings( _this, "xtalk" );
561
m_amod.loadSettings( _this, "amod" );
562
m_bmod.loadSettings( _this, "bmod" );
563
/* m_selectedGraph.loadSettings( _this, "selgraph" );*/
567
QString WatsynInstrument::nodeName() const
569
return( watsyn_plugin_descriptor.name );
573
PluginView * WatsynInstrument::instantiateView( QWidget * _parent )
575
return( new WatsynView( this, _parent ) );
579
void WatsynInstrument::updateVolumes()
581
m_lvol[A1_OSC] = leftCh( a1_vol.value(), a1_pan.value() );
582
m_rvol[A1_OSC] = rightCh( a1_vol.value(), a1_pan.value() );
584
m_lvol[A2_OSC] = leftCh( a2_vol.value(), a2_pan.value() );
585
m_rvol[A2_OSC] = rightCh( a2_vol.value(), a2_pan.value() );
587
m_lvol[B1_OSC] = leftCh( b1_vol.value(), b1_pan.value() );
588
m_rvol[B1_OSC] = rightCh( b1_vol.value(), b1_pan.value() );
590
m_lvol[B2_OSC] = leftCh( b2_vol.value(), b2_pan.value() );
591
m_rvol[B2_OSC] = rightCh( b2_vol.value(), b2_pan.value() );
594
void WatsynInstrument::updateFreq()
596
// calculate frequencies
597
m_lfreq[A1_OSC] = ( a1_mult.value() / 8 ) * powf( 2, a1_ltune.value() / 1200 );
598
m_rfreq[A1_OSC] = ( a1_mult.value() / 8 ) * powf( 2, a1_rtune.value() / 1200 );
600
m_lfreq[A2_OSC] = ( a2_mult.value() / 8 ) * powf( 2, a2_ltune.value() / 1200 );
601
m_rfreq[A2_OSC] = ( a2_mult.value() / 8 ) * powf( 2, a2_rtune.value() / 1200 );
603
m_lfreq[B1_OSC] = ( b1_mult.value() / 8 ) * powf( 2, b1_ltune.value() / 1200 );
604
m_rfreq[B1_OSC] = ( b1_mult.value() / 8 ) * powf( 2, b1_rtune.value() / 1200 );
606
m_lfreq[B2_OSC] = ( b2_mult.value() / 8 ) * powf( 2, b2_ltune.value() / 1200 );
607
m_rfreq[B2_OSC] = ( b2_mult.value() / 8 ) * powf( 2, b2_rtune.value() / 1200 );
611
void WatsynInstrument::updateWaves()
613
// do cip+oversampling on the wavetables to improve quality
614
cipcpy( &A1_wave[0], const_cast<float*>( a1_graph.samples() ) );
615
cipcpy( &A2_wave[0], const_cast<float*>( a2_graph.samples() ) );
616
cipcpy( &B1_wave[0], const_cast<float*>( b1_graph.samples() ) );
617
cipcpy( &B2_wave[0], const_cast<float*>( b2_graph.samples() ) );
621
WatsynView::WatsynView( Instrument * _instrument,
622
QWidget * _parent ) :
623
InstrumentView( _instrument, _parent )
625
setAutoFillBackground( true );
628
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) );
631
// knobs... lots of em
633
makeknob( a1_volKnob, 130, A1ROW, "Volume", "%", "aKnob" )
634
makeknob( a2_volKnob, 130, A2ROW, "Volume", "%", "aKnob" )
635
makeknob( b1_volKnob, 130, B1ROW, "Volume", "%", "bKnob" )
636
makeknob( b2_volKnob, 130, B2ROW, "Volume", "%", "bKnob" )
638
makeknob( a1_panKnob, 154, A1ROW, "Panning", "", "aKnob" )
639
makeknob( a2_panKnob, 154, A2ROW, "Panning", "", "aKnob" )
640
makeknob( b1_panKnob, 154, B1ROW, "Panning", "", "bKnob" )
641
makeknob( b2_panKnob, 154, B2ROW, "Panning", "", "bKnob" )
643
makeknob( a1_multKnob, 178, A1ROW, "Freq. multiplier", "/8", "aKnob" )
644
makeknob( a2_multKnob, 178, A2ROW, "Freq. multiplier", "/8", "aKnob" )
645
makeknob( b1_multKnob, 178, B1ROW, "Freq. multiplier", "/8", "bKnob" )
646
makeknob( b2_multKnob, 178, B2ROW, "Freq. multiplier", "/8", "bKnob" )
648
makeknob( a1_ltuneKnob, 202, A1ROW, "Left detune", " cents", "aKnob" )
649
makeknob( a2_ltuneKnob, 202, A2ROW, "Left detune", " cents", "aKnob" )
650
makeknob( b1_ltuneKnob, 202, B1ROW, "Left detune", " cents", "bKnob" )
651
makeknob( b2_ltuneKnob, 202, B2ROW, "Left detune", " cents", "bKnob" )
653
makeknob( a1_rtuneKnob, 226, A1ROW, "Right detune", " cents", "aKnob" )
654
makeknob( a2_rtuneKnob, 226, A2ROW, "Right detune", " cents", "aKnob" )
655
makeknob( b1_rtuneKnob, 226, B1ROW, "Right detune", " cents", "bKnob" )
656
makeknob( b2_rtuneKnob, 226, B2ROW, "Right detune", " cents", "bKnob" )
658
makeknob( m_abmixKnob, 4, 3, "A-B Mix", "", "mixKnob" )
660
makeknob( m_envAmtKnob, 88, 3, "Mix envelope amount", "", "mixenvKnob" )
662
maketsknob( m_envAttKnob, 88, A1ROW, "Mix envelope attack", " ms", "mixenvKnob" )
663
maketsknob( m_envHoldKnob, 88, A2ROW, "Mix envelope hold", " ms", "mixenvKnob" )
664
maketsknob( m_envDecKnob, 88, B1ROW, "Mix envelope decay", " ms", "mixenvKnob" )
666
makeknob( m_xtalkKnob, 88, B2ROW, "Crosstalk", "", "xtalkKnob" )
668
// let's set volume knobs
669
a1_volKnob -> setVolumeKnob( true );
670
a2_volKnob -> setVolumeKnob( true );
671
b1_volKnob -> setVolumeKnob( true );
672
b2_volKnob -> setVolumeKnob( true );
674
m_abmixKnob -> setFixedSize( 31, 31 );
677
// button groups next.
678
// graph select buttons
679
pixmapButton * a1_selectButton = new pixmapButton( this, NULL );
680
a1_selectButton -> move( 4, 121 );
681
a1_selectButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "a1_active" ) );
682
a1_selectButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "a1_inactive" ) );
683
toolTip::add( a1_selectButton, tr( "Select oscillator A1") );
685
pixmapButton * a2_selectButton = new pixmapButton( this, NULL );
686
a2_selectButton -> move( 44, 121 );
687
a2_selectButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "a2_active" ) );
688
a2_selectButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "a2_inactive" ) );
689
toolTip::add( a2_selectButton, tr( "Select oscillator A2") );
691
pixmapButton * b1_selectButton = new pixmapButton( this, NULL );
692
b1_selectButton -> move( 84, 121 );
693
b1_selectButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "b1_active" ) );
694
b1_selectButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "b1_inactive" ) );
695
toolTip::add( b1_selectButton, tr( "Select oscillator B1") );
697
pixmapButton * b2_selectButton = new pixmapButton( this, NULL );
698
b2_selectButton -> move( 124, 121 );
699
b2_selectButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "b2_active" ) );
700
b2_selectButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "b2_inactive" ) );
701
toolTip::add( b2_selectButton, tr( "Select oscillator B2") );
703
m_selectedGraphGroup = new automatableButtonGroup( this );
704
m_selectedGraphGroup -> addButton( a1_selectButton );
705
m_selectedGraphGroup -> addButton( a2_selectButton );
706
m_selectedGraphGroup -> addButton( b1_selectButton );
707
m_selectedGraphGroup -> addButton( b2_selectButton );
709
// A-modulation button group
710
pixmapButton * amod_mixButton = new pixmapButton( this, NULL );
711
amod_mixButton -> move( 4, 50 );
712
amod_mixButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "amix_active" ) );
713
amod_mixButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "amix_inactive" ) );
714
toolTip::add( amod_mixButton, tr( "Mix output of A2 to A1" ) );
716
pixmapButton * amod_amButton = new pixmapButton( this, NULL );
717
amod_amButton -> move( 4, 66 );
718
amod_amButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "aam_active" ) );
719
amod_amButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "aam_inactive" ) );
720
toolTip::add( amod_amButton, tr( "Modulate amplitude of A1 with output of A2" ) );
722
pixmapButton * amod_rmButton = new pixmapButton( this, NULL );
723
amod_rmButton -> move( 4, 82 );
724
amod_rmButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "arm_active" ) );
725
amod_rmButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "arm_inactive" ) );
726
toolTip::add( amod_rmButton, tr( "Ring-modulate A1 and A2" ) );
728
pixmapButton * amod_pmButton = new pixmapButton( this, NULL );
729
amod_pmButton -> move( 4, 98 );
730
amod_pmButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "apm_active" ) );
731
amod_pmButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "apm_inactive" ) );
732
toolTip::add( amod_pmButton, tr( "Modulate phase of A1 with output of A2" ) );
734
m_aModGroup = new automatableButtonGroup( this );
735
m_aModGroup -> addButton( amod_mixButton );
736
m_aModGroup -> addButton( amod_amButton );
737
m_aModGroup -> addButton( amod_rmButton );
738
m_aModGroup -> addButton( amod_pmButton );
740
// B-modulation button group
741
pixmapButton * bmod_mixButton = new pixmapButton( this, NULL );
742
bmod_mixButton -> move( 44, 50 );
743
bmod_mixButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "bmix_active" ) );
744
bmod_mixButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "bmix_inactive" ) );
745
toolTip::add( bmod_mixButton, tr( "Mix output of B2 to B1" ) );
747
pixmapButton * bmod_amButton = new pixmapButton( this, NULL );
748
bmod_amButton -> move( 44, 66 );
749
bmod_amButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "bam_active" ) );
750
bmod_amButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "bam_inactive" ) );
751
toolTip::add( bmod_amButton, tr( "Modulate amplitude of B1 with output of B2" ) );
753
pixmapButton * bmod_rmButton = new pixmapButton( this, NULL );
754
bmod_rmButton -> move( 44, 82 );
755
bmod_rmButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "brm_active" ) );
756
bmod_rmButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "brm_inactive" ) );
757
toolTip::add( bmod_rmButton, tr( "Ring-modulate B1 and B2" ) );
759
pixmapButton * bmod_pmButton = new pixmapButton( this, NULL );
760
bmod_pmButton -> move( 44, 98 );
761
bmod_pmButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "bpm_active" ) );
762
bmod_pmButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "bpm_inactive" ) );
763
toolTip::add( bmod_pmButton, tr( "Modulate phase of B1 with output of B2" ) );
765
m_bModGroup = new automatableButtonGroup( this );
766
m_bModGroup -> addButton( bmod_mixButton );
767
m_bModGroup -> addButton( bmod_amButton );
768
m_bModGroup -> addButton( bmod_rmButton );
769
m_bModGroup -> addButton( bmod_pmButton );
774
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap("wavegraph") );
776
a1_graph = new graph( this, graph::LinearStyle, 224, 105 );
777
a1_graph->move( 4, 141 );
778
a1_graph->setAutoFillBackground( true );
779
a1_graph->setGraphColor( QColor( 0x43, 0xb2, 0xff ) );
780
toolTip::add( a1_graph, tr ( "Draw your own waveform here by dragging your mouse on this graph." ) );
781
a1_graph->setPalette( pal );
784
a2_graph = new graph( this, graph::LinearStyle, 224, 105 );
785
a2_graph->move( 4, 141 );
786
a2_graph->setAutoFillBackground( true );
787
a2_graph->setGraphColor( QColor( 0x43, 0xb2, 0xff ) );
788
toolTip::add( a2_graph, tr ( "Draw your own waveform here by dragging your mouse on this graph." ) );
789
a2_graph->setPalette( pal );
792
b1_graph = new graph( this, graph::LinearStyle, 224, 105 );
793
b1_graph->move( 4, 141 );
794
b1_graph->setAutoFillBackground( true );
795
b1_graph->setGraphColor( QColor( 0xfc, 0x54, 0x31 ) );
796
toolTip::add( b1_graph, tr ( "Draw your own waveform here by dragging your mouse on this graph." ) );
797
b1_graph->setPalette( pal );
800
b2_graph = new graph( this, graph::LinearStyle, 224, 105 );
801
b2_graph->move( 4, 141 );
802
b2_graph->setAutoFillBackground( true );
803
b2_graph->setGraphColor( QColor( 0xfc, 0x54, 0x31 ) );
804
toolTip::add( b2_graph, tr ( "Draw your own waveform here by dragging your mouse on this graph." ) );
805
b2_graph->setPalette( pal );
809
// waveform modifications
811
m_loadButton = new pixmapButton( this, tr( "Load waveform" ) );
812
m_loadButton -> move ( 173, 121 );
813
m_loadButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "load_active" ) );
814
m_loadButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "load_inactive" ) );
815
toolTip::add( m_loadButton, tr( "Click to load a waveform from a sample file" ) );
817
m_phaseLeftButton = new pixmapButton( this, tr( "Phase left" ) );
818
m_phaseLeftButton -> move ( 193, 121 );
819
m_phaseLeftButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "phl_active" ) );
820
m_phaseLeftButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "phl_inactive" ) );
821
toolTip::add( m_phaseLeftButton, tr( "Click to shift phase by -15 degrees" ) );
823
m_phaseRightButton = new pixmapButton( this, tr( "Phase right" ) );
824
m_phaseRightButton -> move ( 210, 121 );
825
m_phaseRightButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "phr_active" ) );
826
m_phaseRightButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "phr_inactive" ) );
827
toolTip::add( m_phaseRightButton, tr( "Click to shift phase by +15 degrees" ) );
829
m_normalizeButton = new pixmapButton( this, tr( "Normalize" ) );
830
m_normalizeButton -> move ( 230, 121 );
831
m_normalizeButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "norm_active" ) );
832
m_normalizeButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "norm_inactive" ) );
833
toolTip::add( m_normalizeButton, tr( "Click to normalize" ) );
836
m_invertButton = new pixmapButton( this, tr( "Invert" ) );
837
m_invertButton -> move ( 230, 138 );
838
m_invertButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "inv_active" ) );
839
m_invertButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "inv_inactive" ) );
840
toolTip::add( m_invertButton, tr( "Click to invert" ) );
842
m_smoothButton = new pixmapButton( this, tr( "Smooth" ) );
843
m_smoothButton -> move ( 230, 155 );
844
m_smoothButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "smooth_active" ) );
845
m_smoothButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "smooth_inactive" ) );
846
toolTip::add( m_smoothButton, tr( "Click to smooth" ) );
850
m_sinWaveButton = new pixmapButton( this, tr( "Sine wave" ) );
851
m_sinWaveButton -> move ( 230, 176 );
852
m_sinWaveButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sin_active" ) );
853
m_sinWaveButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sin_inactive" ) );
854
toolTip::add( m_sinWaveButton, tr( "Click for sine wave" ) );
856
m_triWaveButton = new pixmapButton( this, tr( "Triangle wave" ) );
857
m_triWaveButton -> move ( 230, 194 );
858
m_triWaveButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "tri_active" ) );
859
m_triWaveButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "tri_inactive" ) );
860
toolTip::add( m_triWaveButton, tr( "Click for triangle wave" ) );
862
m_sawWaveButton = new pixmapButton( this, tr( "Triangle wave" ) );
863
m_sawWaveButton -> move ( 230, 212 );
864
m_sawWaveButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "saw_active" ) );
865
m_sawWaveButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "saw_inactive" ) );
866
toolTip::add( m_sawWaveButton, tr( "Click for saw wave" ) );
868
m_sqrWaveButton = new pixmapButton( this, tr( "Square wave" ) );
869
m_sqrWaveButton -> move ( 230, 230 );
870
m_sqrWaveButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sqr_active" ) );
871
m_sqrWaveButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sqr_inactive" ) );
872
toolTip::add( m_sqrWaveButton, tr( "Click for square wave" ) );
876
connect( m_sinWaveButton, SIGNAL( clicked() ), this, SLOT( sinWaveClicked() ) );
877
connect( m_triWaveButton, SIGNAL( clicked() ), this, SLOT( triWaveClicked() ) );
878
connect( m_sawWaveButton, SIGNAL( clicked() ), this, SLOT( sawWaveClicked() ) );
879
connect( m_sqrWaveButton, SIGNAL( clicked() ), this, SLOT( sqrWaveClicked() ) );
880
connect( m_normalizeButton, SIGNAL( clicked() ), this, SLOT( normalizeClicked() ) );
881
connect( m_invertButton, SIGNAL( clicked() ), this, SLOT( invertClicked() ) );
882
connect( m_smoothButton, SIGNAL( clicked() ), this, SLOT( smoothClicked() ) );
883
connect( m_phaseLeftButton, SIGNAL( clicked() ), this, SLOT( phaseLeftClicked() ) );
884
connect( m_phaseRightButton, SIGNAL( clicked() ), this, SLOT( phaseRightClicked() ) );
885
connect( m_loadButton, SIGNAL( clicked() ), this, SLOT( loadClicked() ) );
887
connect( a1_selectButton, SIGNAL( clicked() ), this, SLOT( updateLayout() ) );
888
connect( a2_selectButton, SIGNAL( clicked() ), this, SLOT( updateLayout() ) );
889
connect( b1_selectButton, SIGNAL( clicked() ), this, SLOT( updateLayout() ) );
890
connect( b2_selectButton, SIGNAL( clicked() ), this, SLOT( updateLayout() ) );
896
WatsynView::~WatsynView()
902
void WatsynView::updateLayout()
904
switch( m_selectedGraphGroup->model()->value() )
935
void WatsynView::sinWaveClicked()
937
switch( m_selectedGraphGroup->model()->value() )
940
a1_graph->model()->setWaveToSine();
941
engine::getSong()->setModified();
944
a2_graph->model()->setWaveToSine();
945
engine::getSong()->setModified();
948
b1_graph->model()->setWaveToSine();
949
engine::getSong()->setModified();
952
b2_graph->model()->setWaveToSine();
953
engine::getSong()->setModified();
959
void WatsynView::triWaveClicked()
961
switch( m_selectedGraphGroup->model()->value() )
964
a1_graph->model()->setWaveToTriangle();
965
engine::getSong()->setModified();
968
a2_graph->model()->setWaveToTriangle();
969
engine::getSong()->setModified();
972
b1_graph->model()->setWaveToTriangle();
973
engine::getSong()->setModified();
976
b2_graph->model()->setWaveToTriangle();
977
engine::getSong()->setModified();
983
void WatsynView::sawWaveClicked()
985
switch( m_selectedGraphGroup->model()->value() )
988
a1_graph->model()->setWaveToSaw();
989
engine::getSong()->setModified();
992
a2_graph->model()->setWaveToSaw();
993
engine::getSong()->setModified();
996
b1_graph->model()->setWaveToSaw();
997
engine::getSong()->setModified();
1000
b2_graph->model()->setWaveToSaw();
1001
engine::getSong()->setModified();
1007
void WatsynView::sqrWaveClicked()
1009
switch( m_selectedGraphGroup->model()->value() )
1012
a1_graph->model()->setWaveToSquare();
1013
engine::getSong()->setModified();
1016
a2_graph->model()->setWaveToSquare();
1017
engine::getSong()->setModified();
1020
b1_graph->model()->setWaveToSquare();
1021
engine::getSong()->setModified();
1024
b2_graph->model()->setWaveToSquare();
1025
engine::getSong()->setModified();
1031
void WatsynView::normalizeClicked()
1033
switch( m_selectedGraphGroup->model()->value() )
1036
a1_graph->model()->normalize();
1037
engine::getSong()->setModified();
1040
a2_graph->model()->normalize();
1041
engine::getSong()->setModified();
1044
b1_graph->model()->normalize();
1045
engine::getSong()->setModified();
1048
b2_graph->model()->normalize();
1049
engine::getSong()->setModified();
1055
void WatsynView::invertClicked()
1057
switch( m_selectedGraphGroup->model()->value() )
1060
a1_graph->model()->invert();
1061
engine::getSong()->setModified();
1064
a2_graph->model()->invert();
1065
engine::getSong()->setModified();
1068
b1_graph->model()->invert();
1069
engine::getSong()->setModified();
1072
b2_graph->model()->invert();
1073
engine::getSong()->setModified();
1079
void WatsynView::smoothClicked()
1081
switch( m_selectedGraphGroup->model()->value() )
1084
a1_graph->model()->smooth();
1085
engine::getSong()->setModified();
1088
a2_graph->model()->smooth();
1089
engine::getSong()->setModified();
1092
b1_graph->model()->smooth();
1093
engine::getSong()->setModified();
1096
b2_graph->model()->smooth();
1097
engine::getSong()->setModified();
1103
void WatsynView::phaseLeftClicked()
1105
switch( m_selectedGraphGroup->model()->value() )
1108
a1_graph->model()->shiftPhase( -15 );
1109
engine::getSong()->setModified();
1112
a2_graph->model()->shiftPhase( -15 );
1113
engine::getSong()->setModified();
1116
b1_graph->model()->shiftPhase( -15 );
1117
engine::getSong()->setModified();
1120
b2_graph->model()->shiftPhase( -15 );
1121
engine::getSong()->setModified();
1127
void WatsynView::phaseRightClicked()
1129
switch( m_selectedGraphGroup->model()->value() )
1132
a1_graph->model()->shiftPhase( 15 );
1133
engine::getSong()->setModified();
1136
a2_graph->model()->shiftPhase( 15 );
1137
engine::getSong()->setModified();
1140
b1_graph->model()->shiftPhase( 15 );
1141
engine::getSong()->setModified();
1144
b2_graph->model()->shiftPhase( 15 );
1145
engine::getSong()->setModified();
1151
void WatsynView::loadClicked()
1154
switch( m_selectedGraphGroup->model()->value() )
1157
a1_graph->model()->setWaveToUser();
1158
engine::getSong()->setModified();
1161
a2_graph->model()->setWaveToUser();
1162
engine::getSong()->setModified();
1165
b1_graph->model()->setWaveToUser();
1166
engine::getSong()->setModified();
1169
b2_graph->model()->setWaveToUser();
1170
engine::getSong()->setModified();
1176
void WatsynView::modelChanged()
1178
WatsynInstrument * w = castModel<WatsynInstrument>();
1180
a1_volKnob -> setModel( &w -> a1_vol );
1181
a2_volKnob -> setModel( &w -> a2_vol );
1182
b1_volKnob -> setModel( &w -> b1_vol );
1183
b2_volKnob -> setModel( &w -> b2_vol );
1185
a1_panKnob -> setModel( &w -> a1_pan );
1186
a2_panKnob -> setModel( &w -> a2_pan );
1187
b1_panKnob -> setModel( &w -> b1_pan );
1188
b2_panKnob -> setModel( &w -> b2_pan );
1190
a1_multKnob -> setModel( &w -> a1_mult );
1191
a2_multKnob -> setModel( &w -> a2_mult );
1192
b1_multKnob -> setModel( &w -> b1_mult );
1193
b2_multKnob -> setModel( &w -> b2_mult );
1195
a1_ltuneKnob -> setModel( &w -> a1_ltune );
1196
a2_ltuneKnob -> setModel( &w -> a2_ltune );
1197
b1_ltuneKnob -> setModel( &w -> b1_ltune );
1198
b2_ltuneKnob -> setModel( &w -> b2_ltune );
1200
a1_rtuneKnob -> setModel( &w -> a1_rtune );
1201
a2_rtuneKnob -> setModel( &w -> a2_rtune );
1202
b1_rtuneKnob -> setModel( &w -> b1_rtune );
1203
b2_rtuneKnob -> setModel( &w -> b2_rtune );
1205
m_abmixKnob -> setModel( &w -> m_abmix );
1207
m_selectedGraphGroup -> setModel( &w -> m_selectedGraph );
1209
m_aModGroup -> setModel( &w -> m_amod );
1210
m_bModGroup -> setModel( &w -> m_bmod );
1212
a1_graph -> setModel( &w -> a1_graph );
1213
a2_graph -> setModel( &w -> a2_graph );
1214
b1_graph -> setModel( &w -> b1_graph );
1215
b2_graph -> setModel( &w -> b2_graph );
1217
m_envAmtKnob -> setModel( &w -> m_envAmt );
1218
m_envAttKnob -> setModel( &w -> m_envAtt );
1219
m_envHoldKnob -> setModel( &w -> m_envHold );
1220
m_envDecKnob -> setModel( &w -> m_envDec );
1222
m_xtalkKnob -> setModel( &w -> m_xtalk );
1232
// necessary for getting instance out of shared lib
1233
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data )
1235
return( new WatsynInstrument( static_cast<InstrumentTrack *>( _data ) ) );
1242
#include "moc_Watsyn.cxx"