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 }