1 module soundtab.audio.instruments;
2 
3 import dlangui.core.logger;
4 import soundtab.ui.noteutil;
5 import soundtab.audio.audiosource;
6 import soundtab.audio.filters;
7 import soundtab.audio.generators;
8 import std.math : log2, exp2, sin, cos, pow, PI;
9 
10 /// Standard controller IDs
11 enum ControllerId {
12     PitchCorrection,
13     VibratoAmount,
14     VibratoFreq,
15     Chorus,
16     Reverb,
17     Distortion,
18     InstrumentVolume,
19     AccompanimentVolume,
20     None,
21     YAxisController,
22     Noise
23 }
24 
25 
26 void interpolate(float[] arr, float startValue, float endValue) {
27     int len = cast(int)arr.length;
28     float diff = endValue - startValue;
29     for(int i = 0; i < len; i++)
30         arr.ptr[i] = startValue + diff * i / len;
31 }
32 
33 void interpolate(int[] arr, int startValue, int endValue) {
34     int len = cast(int)arr.length;
35     int diff = endValue - startValue;
36     for(int i = 0; i < len; i++)
37         arr.ptr[i] = startValue + diff * i / len;
38 }
39 
40 
41 struct Controller {
42     ControllerId id;
43     dstring name;
44     int minValue;
45     int maxValue;
46     int value;
47 }
48 
49 
50 class Instrument : AudioSource {
51 
52     protected string _id;
53     protected dstring _name;
54     protected ControllerId _yAxisControllerId = ControllerId.None;
55 
56     @property dstring name() { return _name; }
57     @property string id() { return _id; }
58 
59     protected float _targetPitch = 1000; // Hz
60     protected float _targetGain = 0; // 0..1
61     //protected float _targetController1 = 0;
62 
63     protected int _attack = 20;
64     protected int _release = 40;
65 
66     /// returns list of supported controllers
67     immutable(Controller)[] getControllers() {
68         return [];
69     }
70 
71     /// returns true if controller value is set, false for unknown controller
72     bool updateController(ControllerId id, int value) {
73         return false;
74     }
75 
76     void setYAxisController(ControllerId controllerId) {
77         _yAxisControllerId = controllerId;
78     }
79 
80     void setSynthParams(float pitch, float gain, float controller1) {
81 
82         if (pitch < 16)
83             pitch = 16;
84         if (pitch > 12000)
85             pitch = 12000;
86         if (gain < 0)
87             gain = 0;
88         if (gain > 1)
89             gain = 1;
90         if (controller1 < 0)
91             controller1 = 0;
92         if (controller1 > 1)
93             controller1 = 1;
94         // lower part of tablet should be sine
95         //if (controller1 < 0.9)
96         //    controller1 /= 0.9;
97         //else
98         //    controller1 = 1;
99         if (_yAxisControllerId != ControllerId.None) {
100             updateController(_yAxisControllerId, cast(int)((1 - controller1) * 1000));
101         }
102         //===========================================
103         lock();
104         scope(exit)unlock();
105         //if (gain > 0.001) {
106             _targetPitch = pitch;
107             //_targetController1 = controller1;
108         //}
109         _targetGain = gain;
110     }
111 
112     protected int freqToStepMul256(float freq) {
113         return cast(int)(WAVETABLE_SIZE * freq / samplesPerSecond * 256);
114     }
115 }
116 
117 /// i is [0..len-1], interpolate from startValue to endValue
118 int interpolate(int i, int len, int startValue, int endValue) {
119     return startValue + (endValue - startValue) * i / len;
120 }
121 
122 /// i is [0..len-1], interpolate from startValue to endValue
123 float interpolate(int i, int len, float startValue, float endValue) {
124     return startValue + (endValue - startValue) * i / len;
125 }
126 
127 void interpolateTable(ref float[] table, int len, float startValue, float endValue) {
128     if (table.length < len)
129         table.length = len;
130     float v = startValue;
131     float step = (endValue - startValue) / len;
132     for (int i = 0; i < len; i++) {
133         table.ptr[i] = v;
134         v += step;
135     }
136 }
137 
138 void interpolateTable(ref int[] table, int len, int startValue, int endValue) {
139     if (table.length < len)
140         table.length = len;
141     int v = startValue;
142     int step = (endValue - startValue) / len;
143     int dstep = (endValue - startValue) % len;
144     for (int i = 0; i < len; i++) {
145         table.ptr[i] = v;
146         v += step;
147         if (dstep > 0) {
148             v++;
149             dstep--;
150         } else if (dstep < 0) {
151             v--;
152             dstep++;
153         }
154     }
155 }
156 
157 /// float calculations instrument base class
158 class InstrumentBaseF : Instrument {
159 
160     Interpolator  _pitch;
161     InterpolatorF _gain;
162     InterpolatorF _controller1;
163     InterpolatorF _vibratoAmount;
164     Interpolator  _vibratoFreq;
165     InterpolatorF _chorus;
166     InterpolatorF _distortion;
167     InterpolatorF _noise;
168 
169     float _targetVibratoAmount = 0;
170     float _targetVibratoFreq = 10;
171     float _targetChorus = 0;
172     float _targetDistortion = 0;
173     float _targetNoise = 0;
174 
175     protected override void calcParams() {
176         // copy dynamic values
177         _pitch.target = freqToStepMul256(_targetPitch);
178         _gain.target = _targetGain;
179         _chorus.target = _targetChorus;
180         //_controller1.target = _targetController1;
181         _vibratoAmount.target = _targetVibratoAmount;
182         _vibratoFreq.target = freqToStepMul256(_targetVibratoFreq);
183         _distortion.target = _targetDistortion;
184         _noise.target = _targetNoise;
185     }
186 
187     protected void interpolateParams(int frameCount) {
188         int frameMillis = frameCount < 10 ? 10 : 1000 * frameCount / samplesPerSecond;
189 
190         _gain.limitTargetChange(frameMillis, _attack, _release);
191         _gain.init(frameCount);
192         if (_gain.value < 0.001f) {
193             _pitch.reset();
194             _chorus.reset();
195             _controller1.reset();
196             _vibratoAmount.reset();
197             _vibratoFreq.reset();
198             _distortion.reset();
199             _noise.reset();
200         }
201         _pitch.init(frameCount);
202         _chorus.init(frameCount);
203         _controller1.init(frameCount);
204         _vibratoAmount.init(frameCount);
205         _vibratoFreq.init(frameCount);
206         _distortion.init(frameCount);
207         _noise.init(frameCount);
208     }
209 
210     override protected void onFormatChanged() {
211     }
212 
213     /// returns true if controller value is set, false for unknown controller
214     override bool updateController(ControllerId id, int value) {
215         switch(id) {
216             case ControllerId.VibratoAmount:
217                 // 0 .. 1/8 tone
218                 double lsAmount = ((value / 1000.0) / 4 / 12); // quarter_tone
219                 double n = exp2(lsAmount) - 1;
220                 _targetVibratoAmount = n; //exp2(log2(QUARTER_TONE) / 3 * value / 1000.0f);
221                 break;
222             case ControllerId.VibratoFreq:
223                 // 1 .. 20 hz
224                 _targetVibratoFreq = 1 + value * 15 / 1000.0f;
225                 break;
226             case ControllerId.Chorus:
227                 // 1 .. 20 hz
228                 _targetChorus = value / 1000.0f;
229                 break;
230             case ControllerId.Noise:
231                 // 1 .. 20 hz
232                 _targetNoise = value / 1000.0f;
233                 break;
234             case ControllerId.Distortion:
235                 _targetDistortion = value / 1000.0f;
236                 break;
237             default:
238                 break;
239         }
240         return false;
241     }
242 
243 }
244 
245 
246 void limitDistortion(ref float v) {
247     if (v < -0.9f) {
248         float delta = -v - 0.9f;
249         // map delta 0..5 -> 0..0.1
250         delta = log2(delta + 1) / 40;
251         v = -0.9f - delta;
252     } else if (v > 0.9f) {
253         float delta = v - 0.9f;
254         delta = log2(delta + 1) / 40;
255         v = 0.9f + delta;
256     }
257         
258 }
259 
260 class SineHarmonicWaveTable : InstrumentBaseF {
261     OscillerF _tone1;
262     OscillerF _chorusTone1;
263     OscillerF _chorusTone2;
264     OscillerF _chorusTone3;
265     OscillerF _chorusTone4;
266     OscillerF _chorusTone5;
267     OscillerF _chorusTone6;
268     OscillerF _chorusTone7;
269     OscillerF _chorusTone8;
270     OscillerF _vibrato1;
271     OscillerF _chorusVibrato1;
272     OscillerF _chorusVibrato2;
273     OscillerF _chorusVibrato3;
274     OscillerF _chorusVibrato4;
275     OscillerF _chorusVibrato5;
276     OscillerF _chorusVibrato6;
277     OscillerF _chorusVibrato7;
278     OscillerF _chorusVibrato8;
279     float[] _wavetable;
280     this(string id, dstring name, immutable(float[])formants = null) {
281         _id = id;
282         _name = name;
283         _wavetable = SIN_TABLE_F;
284         //immutable(float[]) formants = null;
285         //_tone1 = new OscillerF(_wavetable, 1, 0, [0.7, 0.5, 0.3, 0.1, 0.05, 0.05]);
286         _tone1 = new OscillerF(_wavetable, 1, 0, formants);
287         _chorusTone1 = new OscillerF(_wavetable, 1, 0, formants);
288         _chorusTone2 = new OscillerF(_wavetable, 1, 0, formants);
289         _chorusTone3 = new OscillerF(_wavetable, 1, 0, formants);
290         _chorusTone4 = new OscillerF(_wavetable, 1, 0, formants);
291         _chorusTone5 = new OscillerF(_wavetable, 1, 0, formants);
292         _chorusTone6 = new OscillerF(_wavetable, 1, 0, formants);
293         _chorusTone7 = new OscillerF(_wavetable, 1, 0, formants);
294         _chorusTone8 = new OscillerF(_wavetable, 1, 0, formants);
295         _vibrato1 = new OscillerF(SIN_TABLE_F);
296         _chorusVibrato1 = new OscillerF(SIN_TABLE_F, 0.00312, 1.000, [0.4, -0.3, 0.2, 0.1, 0.05, 0.02, 0.01, -0.01]);
297         _chorusVibrato2 = new OscillerF(SIN_TABLE_F, 0.00323, 1.002, [0.2,-0.2, 0.2,-0.1, 0.3, 0.02, 0.01, -0.01]);
298         _chorusVibrato3 = new OscillerF(SIN_TABLE_F, 0.00334, 0.999, [0.3,-0.3, 0.2,-0.2, 0.15, 0.02, 0.01, -0.01]);
299         _chorusVibrato4 = new OscillerF(SIN_TABLE_F, 0.00315, 0.998, [0.45, 0.1, 0.2, 0.1, 0.02, 0.1, 0.01, -0.01]);
300         _chorusVibrato5 = new OscillerF(SIN_TABLE_F, 0.00323, 1.000, [0.31, -0.2, 0.2, 0.3, 0.03, 0.1, 0.01, -0.01]);
301         _chorusVibrato6 = new OscillerF(SIN_TABLE_F, 0.00331, 1.002, [0.42, 0.1, -0.2, 0.1, 0.01, 0.02, 0.01, -0.01]);
302         _chorusVibrato7 = new OscillerF(SIN_TABLE_F, 0.00317, 0.999, [0.13, -0.3, 0.3, 0.1, 0.08, 0.02, 0.01, -0.01]);
303         _chorusVibrato8 = new OscillerF(SIN_TABLE_F, 0.00323, 0.998, [0.21, 0.2, 0.2, 0.05, 0.02, 0.02, 0.01, -0.01]);
304     }
305 
306 
307     void resetPhase() {
308         _tone1.resetPhase();
309         _chorusTone1.resetPhase();
310         _chorusTone2.resetPhase();
311         _chorusTone3.resetPhase();
312         _chorusTone4.resetPhase();
313         _chorusTone5.resetPhase();
314         _chorusTone6.resetPhase();
315         _chorusTone7.resetPhase();
316         _chorusTone8.resetPhase();
317     }
318 
319     override protected void onFormatChanged() {
320         resetPhase();
321     }
322 
323 
324     override bool loadData(int frameCount, ubyte * buf, ref uint flags) {
325         {
326             lock();
327             scope(exit)unlock();
328             calcParams();
329         }
330 
331         interpolateParams(frameCount);
332 
333 
334 
335         if (_gain.isZero /* || _zeroVolume */) {
336             // silent
337             //flags = AUDIO_SOURCE_SILENCE_FLAG;
338             generateSilence(frameCount, buf);
339             resetPhase();
340             return true;
341         }
342 
343         bool hasVibrato = !_vibratoAmount.isZero;
344         bool hasChorus = !_chorus.isZero;
345         float chorusSample1 = 0;
346         float chorusSample2 = 0;
347         int chorusVibratoStep1 = freqToStepMul256( 1.2354124f);
348         int chorusVibratoStep2 = freqToStepMul256( 3.53452334f);
349         int chorusVibratoStep3 = freqToStepMul256( 2.1234523f);
350         int chorusVibratoStep4 = freqToStepMul256( 0.7234543234f);
351         int chorusVibratoStep5 = freqToStepMul256( 0.43453f);
352         int chorusVibratoStep6 = freqToStepMul256( 2.334245746f);
353         int chorusVibratoStep7 = freqToStepMul256( 1.984545f);
354         int chorusVibratoStep8 = freqToStepMul256( 1.6332675f);
355         for (int i = 0; i < frameCount; i++) {
356             /// one step
357             float gain = _gain.next;
358             if (!_unityVolume)
359                 gain *= _volume;
360             float controller1 = _controller1.next;
361 
362             int step = _pitch.next; //_vibrato0.stepMultiply(_step_mul_256, vibratoAmount1);
363             // apply vibrato
364             if (hasVibrato) {
365                 int vibratoStep = _vibratoFreq.next;
366                 float vibratoAmount = _vibratoAmount.next;
367                 float vibrato = _vibrato1.step(vibratoStep) * vibratoAmount + 1;
368                 step = cast(int)(step * vibrato);
369             }
370 
371             if (hasChorus) {
372                 float chorus = _chorus.next;
373                 float chorusGain = gain * chorus * 7 / 10;
374                 gain -= chorusGain;
375                 float chorus1 = _chorusVibrato1.step(chorusVibratoStep1);
376                 float chorus2 = _chorusVibrato2.step(chorusVibratoStep2);
377                 float chorus3 = _chorusVibrato3.step(chorusVibratoStep3);
378                 float chorus4 = _chorusVibrato4.step(chorusVibratoStep4);
379                 float chorus5 = _chorusVibrato5.step(chorusVibratoStep5);
380                 float chorus6 = _chorusVibrato6.step(chorusVibratoStep6);
381                 float chorus7 = _chorusVibrato7.step(chorusVibratoStep7);
382                 float chorus8 = _chorusVibrato8.step(chorusVibratoStep8);
383                 int step1 = cast(int)(chorus1 * step);
384                 int step2 = cast(int)(chorus2 * step);
385                 int step3 = cast(int)(chorus3 * step);
386                 int step4 = cast(int)(chorus4 * step);
387                 int step5 = cast(int)(chorus5 * step);
388                 int step6 = cast(int)(chorus6 * step);
389                 int step7 = cast(int)(chorus7 * step);
390                 int step8 = cast(int)(chorus8 * step);
391                 chorus1 = _chorusTone1.step(step1);
392                 chorus2 = _chorusTone2.step(step2);
393                 chorus3 = _chorusTone3.step(step3);
394                 chorus4 = _chorusTone4.step(step4);
395                 chorus5 = _chorusTone5.step(step5);
396                 chorus6 = _chorusTone6.step(step6);
397                 chorus7 = _chorusTone7.step(step7);
398                 chorus8 = _chorusTone8.step(step8);
399                 chorusSample1 = (
400                       -chorus1
401                     + chorus2
402                     + chorus5/3
403                     + chorus6/4
404                     - chorus7/4
405                     - chorus8/3
406                     + chorus3
407                     + chorus4) / 6;
408                 chorusSample2 = (
409                     chorus5
410                     + chorus6
411                     - chorus1/3
412                     + chorus2/4
413                     - chorus3/4
414                     - chorus4/3
415                     + chorus7
416                     + chorus8) / 6;
417             }
418 
419             float sample = _tone1.step(step);
420             float sample1 = (sample + chorusSample1);
421             float sample2 = (sample + chorusSample2);
422             if (!_distortion.isZero) {
423                 float distort = 1 + _distortion.next * 5;
424                 sample1 *= distort;
425                 sample1 *= distort;
426                 limitDistortion(sample1);
427                 limitDistortion(sample2);
428             }
429             sample1 *= gain;
430             sample2 *= gain;
431             limitDistortion(sample1);
432             limitDistortion(sample2);
433 
434             putSamples(buf, sample1, sample2);
435 
436             buf += blockAlign;
437         }
438 
439         // TODO
440         //durationCounter--;
441         flags = 0; //durationCounter <= 0 ? AUDCLNT_BUFFERFLAGS.AUDCLNT_BUFFERFLAGS_SILENT : 0;
442         //Log.d("Instrument loadData - exit");
443         return true;
444     }
445 
446     /// returns list of supported controllers
447     override immutable(Controller)[] getControllers() {
448         Controller[] res;
449         //res ~= Controller("chorus", "Chorus", 0, 1000, 300);
450         //res ~= Controller("reverb", "Reverb", 0, 1000, 300);
451         res ~= Controller(ControllerId.VibratoAmount, "Vibrato Amount", 0, 1000, 300);
452         res ~= Controller(ControllerId.VibratoFreq, "Vibrato Freq", 0, 1000, 500);
453         res ~= Controller(ControllerId.Chorus, "Chorus", 0, 1000, 0);
454         res ~= Controller(ControllerId.Distortion, "Distortion", 0, 1000, 0);
455         return cast(immutable(Controller)[])res;
456     }
457 
458     /// returns true if controller value is set, false for unknown controller
459     override bool updateController(ControllerId id, int value) {
460         return super.updateController(id, value);
461     }
462 
463 }
464 
465 float[] mulSequence(float firstValue, float mult, int len) {
466     float[] res = new float[len];
467     float value = firstValue;
468     for (int i = 0; i < len; i++) {
469         res[i] = value;
470         value *= mult;
471     }
472     return res;
473 }
474 
475 class PhonemeOscillerF : OscillerF {
476     PhonemeFormantsFilter _formantFilter;
477     OneZero _onezero;
478     OnePole _onepole;
479     Noise _noise;
480     this(PhonemeType phoneme, float formantFreqMult = 1) {
481         super(SIN_TABLE_F, 1, 0, mulSequence(1, -0.85, 40).dup);//VOICE_IMPULSE_F SAW_TABLE_F VOICE_EXPERIMENTAL_F
482         //super(VOICE_EXPERIMENTAL_F);//VOICE_IMPULSE_F SAW_TABLE_F VOICE_EXPERIMENTAL_F VOICE_EX_1_F
483         _formantFilter = new PhonemeFormantsFilter(phoneme, formantFreqMult);
484         _onezero = new OneZero();
485         _onepole = new OnePole();
486         _onezero.setZero( -0.9 );
487         _onepole.setPole( 0.9 );
488     }
489     void setPhoneme(PhonemeType phoneme, float formantFreqMult = 1) {
490         _formantFilter.setPhoneme(phoneme, formantFreqMult);
491     }
492     void setSampleRate(int samplesPerSecond) {
493         _formantFilter.setSampleRate(samplesPerSecond);
494     }
495     float step(int step_mul_256, float noiseGain) {
496         int oldPhase = _phase;
497         float value = super.step(step_mul_256);
498         //if (oldPhase > _phase)
499         //    value = 1;
500         //else
501         //    value = 0;
502         //if ((oldPhase >> 8) < WAVETABLE_SIZE / 12) {
503         //    if (noiseGain > 0)
504         //        value += _noise.tick() * noiseGain;
505         //}
506 
507         value = _onepole.tick( _onezero.tick( value ) );
508 
509         value = _formantFilter.tick(value);
510         return value;
511     }
512 }
513 
514 class PhonemeSynth : InstrumentBaseF {
515     PhonemeOscillerF _tone1;
516     PhonemeOscillerF _chorusTone1;
517     PhonemeOscillerF _chorusTone2;
518     PhonemeOscillerF _chorusTone3;
519     PhonemeOscillerF _chorusTone4;
520     PhonemeOscillerF _chorusTone5;
521     PhonemeOscillerF _chorusTone6;
522     PhonemeOscillerF _chorusTone7;
523     PhonemeOscillerF _chorusTone8;
524     OscillerF _vibrato1;
525     OscillerF _chorusVibrato1;
526     OscillerF _chorusVibrato2;
527     OscillerF _chorusVibrato3;
528     OscillerF _chorusVibrato4;
529     OscillerF _chorusVibrato5;
530     OscillerF _chorusVibrato6;
531     OscillerF _chorusVibrato7;
532     OscillerF _chorusVibrato8;
533     this(string id, dstring name, PhonemeType phoneme) {
534         _id = id;
535         _name = name;
536         _tone1 = new PhonemeOscillerF(phoneme);
537         _chorusTone1 = new PhonemeOscillerF(phoneme, 1.01f);
538         _chorusTone2 = new PhonemeOscillerF(phoneme, 1.02f);
539         _chorusTone3 = new PhonemeOscillerF(phoneme, 1.1f);
540         _chorusTone4 = new PhonemeOscillerF(phoneme, 1.04f);
541         _chorusTone5 = new PhonemeOscillerF(phoneme, 1.01f);
542         _chorusTone6 = new PhonemeOscillerF(phoneme, 1.025f);
543         _chorusTone7 = new PhonemeOscillerF(phoneme, 1.035f);
544         _chorusTone8 = new PhonemeOscillerF(phoneme, 1.05f);
545         _vibrato1 = new OscillerF(SIN_TABLE_F);
546         _chorusVibrato1 = new OscillerF(SIN_TABLE_F, 0.00312, 1.000, [0.4, -0.3, 0.2, 0.1, 0.05, 0.02, 0.01, -0.01]);
547         _chorusVibrato2 = new OscillerF(SIN_TABLE_F, 0.00323, 1.002, [0.2,-0.2, 0.2,-0.1, 0.3, 0.02, 0.01, -0.01]);
548         _chorusVibrato3 = new OscillerF(SIN_TABLE_F, 0.00334, 0.999, [0.3,-0.3, 0.2,-0.2, 0.15, 0.02, 0.01, -0.01]);
549         _chorusVibrato4 = new OscillerF(SIN_TABLE_F, 0.00315, 0.998, [0.45, 0.1, 0.2, 0.1, 0.02, 0.1, 0.01, -0.01]);
550         _chorusVibrato5 = new OscillerF(SIN_TABLE_F, 0.00323, 1.000, [0.31, -0.2, 0.2, 0.3, 0.03, 0.1, 0.01, -0.01]);
551         _chorusVibrato6 = new OscillerF(SIN_TABLE_F, 0.00331, 1.002, [0.42, 0.1, -0.2, 0.1, 0.01, 0.02, 0.01, -0.01]);
552         _chorusVibrato7 = new OscillerF(SIN_TABLE_F, 0.00317, 0.999, [0.13, -0.3, 0.3, 0.1, 0.08, 0.02, 0.01, -0.01]);
553         _chorusVibrato8 = new OscillerF(SIN_TABLE_F, 0.00323, 0.998, [0.21, 0.2, 0.2, 0.05, 0.02, 0.02, 0.01, -0.01]);
554     }
555 
556     void setPhoneme(PhonemeType phoneme) {
557         _tone1.setPhoneme(phoneme);
558         _chorusTone1.setPhoneme(phoneme, 1.1f);
559         _chorusTone2.setPhoneme(phoneme, 1.2f);
560         _chorusTone3.setPhoneme(phoneme, 1.3f);
561         _chorusTone4.setPhoneme(phoneme, 1.4f);
562         _chorusTone5.setPhoneme(phoneme, 1.1f);
563         _chorusTone6.setPhoneme(phoneme, 1.25f);
564         _chorusTone7.setPhoneme(phoneme, 1.35f);
565         _chorusTone8.setPhoneme(phoneme, 1.05f);
566     }
567 
568     void resetPhase() {
569         _tone1.resetPhase();
570         _chorusTone1.resetPhase();
571         _chorusTone2.resetPhase();
572         _chorusTone3.resetPhase();
573         _chorusTone4.resetPhase();
574         _chorusTone5.resetPhase();
575         _chorusTone6.resetPhase();
576         _chorusTone7.resetPhase();
577         _chorusTone8.resetPhase();
578     }
579 
580     override protected void onFormatChanged() {
581         resetPhase();
582         _tone1.setSampleRate(samplesPerSecond);
583         _chorusTone1.setSampleRate(samplesPerSecond);
584         _chorusTone2.setSampleRate(samplesPerSecond);
585         _chorusTone3.setSampleRate(samplesPerSecond);
586         _chorusTone4.setSampleRate(samplesPerSecond);
587         _chorusTone5.setSampleRate(samplesPerSecond);
588         _chorusTone6.setSampleRate(samplesPerSecond);
589         _chorusTone7.setSampleRate(samplesPerSecond);
590         _chorusTone8.setSampleRate(samplesPerSecond);
591     }
592 
593     override bool loadData(int frameCount, ubyte * buf, ref uint flags) {
594         {
595             lock();
596             scope(exit)unlock();
597             calcParams();
598         }
599 
600         interpolateParams(frameCount);
601 
602         if (_gain.isZero /* || _zeroVolume */) {
603             // silent
604             //flags = AUDIO_SOURCE_SILENCE_FLAG;
605             generateSilence(frameCount, buf);
606             resetPhase();
607             return true;
608         }
609 
610         bool hasVibrato = !_vibratoAmount.isZero;
611         bool hasChorus = !_chorus.isZero;
612         float chorusSample1 = 0;
613         float chorusSample2 = 0;
614         int chorusVibratoStep1 = freqToStepMul256( 1.2354124f);
615         int chorusVibratoStep2 = freqToStepMul256( 3.53452334f);
616         int chorusVibratoStep3 = freqToStepMul256( 2.1234523f);
617         int chorusVibratoStep4 = freqToStepMul256( 0.7234543234f);
618         int chorusVibratoStep5 = freqToStepMul256( 0.43453f);
619         int chorusVibratoStep6 = freqToStepMul256( 2.334245746f);
620         int chorusVibratoStep7 = freqToStepMul256( 1.984545f);
621         int chorusVibratoStep8 = freqToStepMul256( 1.6332675f);
622         for (int i = 0; i < frameCount; i++) {
623             /// one step
624             float gain = _gain.next;
625             if (!_unityVolume)
626                 gain *= _volume;
627             float controller1 = _controller1.next;
628 
629             int step = _pitch.next; //_vibrato0.stepMultiply(_step_mul_256, vibratoAmount1);
630             // apply vibrato
631             if (hasVibrato) {
632                 int vibratoStep = _vibratoFreq.next;
633                 float vibratoAmount = _vibratoAmount.next;
634                 float vibrato = _vibrato1.step(vibratoStep) * vibratoAmount + 1;
635                 step = cast(int)(step * vibrato);
636             }
637 
638             float noiseGain = _noise.next;
639 
640             if (hasChorus) {
641                 float chorus = _chorus.next;
642                 float chorusGain = gain * chorus * 7 / 10;
643                 gain -= chorusGain;
644                 float chorus1 = _chorusVibrato1.step(chorusVibratoStep1);
645                 float chorus2 = _chorusVibrato2.step(chorusVibratoStep2);
646                 float chorus3 = _chorusVibrato3.step(chorusVibratoStep3);
647                 float chorus4 = _chorusVibrato4.step(chorusVibratoStep4);
648                 float chorus5 = _chorusVibrato5.step(chorusVibratoStep5);
649                 float chorus6 = _chorusVibrato6.step(chorusVibratoStep6);
650                 float chorus7 = _chorusVibrato7.step(chorusVibratoStep7);
651                 float chorus8 = _chorusVibrato8.step(chorusVibratoStep8);
652                 int step1 = cast(int)(chorus1 * step);
653                 int step2 = cast(int)(chorus2 * step);
654                 int step3 = cast(int)(chorus3 * step);
655                 int step4 = cast(int)(chorus4 * step);
656                 int step5 = cast(int)(chorus5 * step);
657                 int step6 = cast(int)(chorus6 * step);
658                 int step7 = cast(int)(chorus7 * step);
659                 int step8 = cast(int)(chorus8 * step);
660                 chorus1 = _chorusTone1.step(step1, noiseGain);
661                 chorus2 = _chorusTone2.step(step2, noiseGain);
662                 chorus3 = _chorusTone3.step(step3, noiseGain);
663                 chorus4 = _chorusTone4.step(step4, noiseGain);
664                 chorus5 = _chorusTone5.step(step5, noiseGain);
665                 chorus6 = _chorusTone6.step(step6, noiseGain);
666                 chorus7 = _chorusTone7.step(step7, noiseGain);
667                 chorus8 = _chorusTone8.step(step8, noiseGain);
668                 chorusSample1 = (
669                                  -chorus1
670                                  + chorus2
671                                  + chorus5/2
672                                  + chorus6/3
673                                  - chorus7/3
674                                  - chorus8/2
675                                  + chorus3
676                                  + chorus4);
677                 chorusSample2 = (
678                                  chorus5
679                                  + chorus6
680                                  - chorus1/2
681                                  + chorus2/3
682                                  - chorus3/3
683                                  - chorus4/2
684                                  + chorus7
685                                  + chorus8);
686             }
687 
688             float sample = _tone1.step(step, noiseGain);
689             float sample1 = (sample + chorusSample1);
690             float sample2 = (sample + chorusSample2);
691             if (!_distortion.isZero) {
692                 float distort = 1 + _distortion.next * 5;
693                 sample1 *= distort;
694                 sample1 *= distort;
695                 limitDistortion(sample1);
696                 limitDistortion(sample2);
697             }
698             sample1 *= gain;
699             sample2 *= gain;
700             limitDistortion(sample1);
701             limitDistortion(sample2);
702 
703             putSamples(buf, sample1, sample2);
704 
705             buf += blockAlign;
706         }
707 
708         // TODO
709         //durationCounter--;
710         flags = 0; //durationCounter <= 0 ? AUDCLNT_BUFFERFLAGS.AUDCLNT_BUFFERFLAGS_SILENT : 0;
711         //Log.d("Instrument loadData - exit");
712         return true;
713     }
714 
715     /// returns list of supported controllers
716     override immutable(Controller)[] getControllers() {
717         Controller[] res;
718         res ~= Controller(ControllerId.VibratoAmount, "Vibrato Amount", 0, 1000, 300);
719         res ~= Controller(ControllerId.VibratoFreq, "Vibrato Freq", 0, 1000, 500);
720         res ~= Controller(ControllerId.Chorus, "Chorus", 0, 1000, 1000);
721         //res ~= Controller(ControllerId.Noise, "Noise", 0, 1000, 0);
722         res ~= Controller(ControllerId.Distortion, "Distortion", 0, 1000, 0);
723         return cast(immutable(Controller)[])res;
724     }
725 
726     /// returns true if controller value is set, false for unknown controller
727     override bool updateController(ControllerId id, int value) {
728         return super.updateController(id, value);
729     }
730 
731 }
732 
733 
734 private __gshared Instrument[] _instrumentList;
735 /// get list of supported instruments
736 Instrument[] getInstrumentList() {
737     if (!_instrumentList.length) {
738         _instrumentList ~= new SineHarmonicWaveTable("sinewave", "Sine Wave", null);
739         _instrumentList ~= new SineHarmonicWaveTable("strings", "Strings", [0.7, -0.6, 0.5, -0.4, 0.3, -0.2]);
740         _instrumentList ~= new SineHarmonicWaveTable("strings2", "Strings 2", [0.5, -0.4, 0.3, -0.3, 0.25, -0.3, 0.15, -0.15, 0.1, -0.05, 0.04, -0.03, 0.02, -0.01]);
741         _instrumentList ~= new SineHarmonicWaveTable("brass", "Brass", [0.1, -0.3, 0.4, -0.4, 0.6, -0.6, 0.8, -0.8, 0.4, -0.35, 0.2, -0.1, 0.05, -0.02]);
742         _instrumentList ~= new PhonemeSynth("voiceAaa", "Voice Aaa", PhonemeType.aaa);
743         _instrumentList ~= new PhonemeSynth("voiceIhh", "Voice Ihh", PhonemeType.ihh);
744         _instrumentList ~= new PhonemeSynth("voiceEhh", "Voice Ehh", PhonemeType.ehh);
745         _instrumentList ~= new PhonemeSynth("voiceEee", "Voice Eee", PhonemeType.eee);
746         _instrumentList ~= new PhonemeSynth("voiceAhh", "Voice Ahh", PhonemeType.ahh);
747         _instrumentList ~= new PhonemeSynth("voiceAww", "Voice Aww", PhonemeType.aww);
748         _instrumentList ~= new PhonemeSynth("voiceOhh", "Voice Ohh", PhonemeType.ohh);
749         _instrumentList ~= new PhonemeSynth("voiceUhh", "Voice Uhh", PhonemeType.uhh);
750         _instrumentList ~= new PhonemeSynth("voiceUuu", "Voice Uuu", PhonemeType.uuu);
751         _instrumentList ~= new PhonemeSynth("voiceOoo", "Voice Ooo", PhonemeType.ooo);
752         _instrumentList ~= new PhonemeSynth("voiceRrr", "Voice Rrr", PhonemeType.rrr);
753         _instrumentList ~= new PhonemeSynth("voiceLll", "Voice Lll", PhonemeType.lll);
754     }
755     return _instrumentList;
756 }