Unified · Split
Binary file not shown.
Binary file not shown.
| @@ -107,6 +107,8 @@ extern "C" { · 106 unmodified lines | |||
| 107 | void tPoly_setPitchBend (tPoly* const, float pitchBend); | 107 | void tPoly_setPitchBend (tPoly* const, float pitchBend); |
| 108 | void tPoly_setPitchGlideActive (tPoly* const, oBool isActive); | 108 | void tPoly_setPitchGlideActive (tPoly* const, oBool isActive); |
| 109 | void tPoly_setPitchGlideTime (tPoly* const, float t); | 109 | void tPoly_setPitchGlideTime (tPoly* const, float t); |
| 110 | void tPoly_setBendGlideTime (tPoly* const polyh, float t); | ||
| 111 | void tPoly_setBendSamplesPerTick (tPoly* const polyh, float t); | ||
| 110 | void tPoly_tickPitch (tPoly* const); | 112 | void tPoly_tickPitch (tPoly* const); |
| 111 | void tPoly_tickPitchGlide (tPoly* const); | 113 | void tPoly_tickPitchGlide (tPoly* const); |
| 112 | void tPoly_tickPitchBend (tPoly* const); | 114 | void tPoly_tickPitchBend (tPoly* const); |
| @@ -254,15 +254,7 @@ float tTalkbox_tick(tTalkbox* const voc, float synth, float voice) · 253 unmodified lines | |||
| 254 | v->pos = p0; | 254 | v->pos = p0; |
| 255 | v->FX = fx; | 255 | v->FX = fx; |
| 256 | 256 | ||
| 257 | float den = 1.0e-10f; //(float)pow(10.0f, -10.0f * param[4]); | 257 | |
| 258 | if(fabs(v->d0) < den) v->d0 = 0.0f; //anti-denormal (doesn't seem necessary but P4?) | ||
| 259 | if(fabs(v->d1) < den) v->d1 = 0.0f; | ||
| 260 | if(fabs(v->d2) < den) v->d2 = 0.0f; | ||
| 261 | if(fabs(v->d3) < den) v->d3 = 0.0f; | ||
| 262 | if(fabs(v->u0) < den) v->u0 = 0.0f; | ||
| 263 | if(fabs(v->u1) < den) v->u1 = 0.0f; | ||
| 264 | if(fabs(v->u2) < den) v->u2 = 0.0f; | ||
| 265 | if(fabs(v->u3) < den) v->u3 = 0.0f; | ||
| 266 | return o; | 258 | return o; |
| 267 | } | 259 | } |
| 268 | 260 | ||
| @@ -399,7 +399,7 @@ void tADSR_setAttack(tADSR* const adsrenv, float attack) · 398 unmodified lines | |||
| 399 | adsr->attackInc = adsr->inc_buff[attackIndex]; | 399 | adsr->attackInc = adsr->inc_buff[attackIndex]; |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | void tADSR_detDecay(tADSR* const adsrenv, float decay) | 402 | void tADSR_setDecay(tADSR* const adsrenv, float decay) |
| 403 | { | 403 | { |
| 404 | _tADSR* adsr = *adsrenv; | 404 | _tADSR* adsr = *adsrenv; |
| 405 | 405 | ||
| @@ -657,14 +657,11 @@ float tRamp_tick(tRamp* const ramp) · 251 unmodified lines | |||
| 657 | 657 | ||
| 658 | r->curr += r->inc; | 658 | r->curr += r->inc; |
| 659 | 659 | ||
| 660 | if (((r->curr >= r->dest) && (r->inc > 0.0f)) || ((r->curr <= r->dest) && (r->inc < 0.0f))) | 660 | if (((r->curr >= r->dest) && (r->inc >= 0.0f)) || ((r->curr <= r->dest) && (r->inc < 0.0f))) |
| 661 | { | 661 | { |
| 662 | r->inc = 0.0f; | 662 | r->inc = 0.0f; |
| 663 | r->curr=r->dest; | 663 | r->curr=r->dest; |
| 664 | } | 664 | } |
| 665 | |||
| 666 | // Palle: There is a slight risk that you overshoot here and stay on dest+inc, which with a large inc value could be a real problem | ||
| 667 | // I suggest you add: r->curr=r->dest in the true if case | ||
| 668 | 665 | ||
| 669 | return r->curr; | 666 | return r->curr; |
| 670 | } | 667 | } |
| @@ -425,7 +425,6 @@ void tPoly_tickPitchBend(tPoly* polyh) · 424 unmodified lines | |||
| 425 | tRamp_tick(&poly->pitchBendRamp); | 425 | tRamp_tick(&poly->pitchBendRamp); |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | //instead of including in dacsend, should have a separate pitch bend ramp, that is added when the ramps are ticked and sent to DAC | ||
| 429 | void tPoly_setPitchBend(tPoly* const polyh, float pitchBend) | 428 | void tPoly_setPitchBend(tPoly* const polyh, float pitchBend) |
| 430 | { | 429 | { |
| 431 | _tPoly* poly = *polyh; | 430 | _tPoly* poly = *polyh; |
| @@ -480,7 +479,7 @@ int tPoly_noteOn(tPoly* const polyh, int note, uint8_t vel) · 48 unmodified lines | |||
| 480 | whichVoice = poly->notes[whichNote][1]; | 479 | whichVoice = poly->notes[whichNote][1]; |
| 481 | if (whichVoice >= 0) | 480 | if (whichVoice >= 0) |
| 482 | { | 481 | { |
| 483 | poly->lastVoiceToChange = j; | 482 | poly->lastVoiceToChange = whichVoice; |
| 484 | int oldNote = poly->voices[whichVoice][0]; | 483 | int oldNote = poly->voices[whichVoice][0]; |
| 485 | poly->voices[whichVoice][0] = note; | 484 | poly->voices[whichVoice][0] = note; |
| 486 | poly->voices[whichVoice][1] = vel; | 485 | poly->voices[whichVoice][1] = vel; |
| @@ -488,7 +487,14 @@ int tPoly_noteOn(tPoly* const polyh, int note, uint8_t vel) · 1 unmodified line | |||
| 488 | poly->notes[note][0] = vel; | 487 | poly->notes[note][0] = vel; |
| 489 | poly->notes[note][1] = whichVoice; | 488 | poly->notes[note][1] = whichVoice; |
| 490 | 489 | ||
| 491 | tRamp_setTime(&poly->ramps[whichVoice], poly->glideTime); | 490 | if (poly->pitchGlideIsActive) |
| 491 | { | ||
| 492 | tRamp_setTime(&poly->ramps[whichVoice], poly->glideTime); | ||
| 493 | } | ||
| 494 | else | ||
| 495 | { | ||
| 496 | tRamp_setVal(&poly->ramps[whichVoice], note); | ||
| 497 | } | ||
| 492 | tRamp_setDest(&poly->ramps[whichVoice], poly->voices[whichVoice][0]); | 498 | tRamp_setDest(&poly->ramps[whichVoice], poly->voices[whichVoice][0]); |
| 493 | 499 | ||
| 494 | alteredVoice = whichVoice; | 500 | alteredVoice = whichVoice; |
| @@ -546,6 +552,14 @@ int tPoly_noteOff(tPoly* const polyh, uint8_t note) · 51 unmodified lines | |||
| 546 | if (poly->notes[noteToTest][1] < 0) //if there is a stolen note waiting (marked inactive but on the stack) | 552 | if (poly->notes[noteToTest][1] < 0) //if there is a stolen note waiting (marked inactive but on the stack) |
| 547 | { | 553 | { |
| 548 | poly->voices[deactivatedVoice][0] = noteToTest; //set the newly free voice to use the old stolen note | 554 | poly->voices[deactivatedVoice][0] = noteToTest; //set the newly free voice to use the old stolen note |
| 555 | if (poly->pitchGlideIsActive) | ||
| 556 | { | ||
| 557 | tRamp_setTime(&poly->ramps[deactivatedVoice], poly->glideTime); | ||
| 558 | } | ||
| 559 | else | ||
| 560 | { | ||
| 561 | tRamp_setVal(&poly->ramps[deactivatedVoice], noteToTest); | ||
| 562 | } | ||
| 549 | tRamp_setDest(&poly->ramps[deactivatedVoice], poly->voices[deactivatedVoice][0]); | 563 | tRamp_setDest(&poly->ramps[deactivatedVoice], poly->voices[deactivatedVoice][0]); |
| 550 | poly->voices[deactivatedVoice][1] = poly->notes[noteToTest][0]; // set the velocity of the voice to be the velocity of that note | 564 | poly->voices[deactivatedVoice][1] = poly->notes[noteToTest][0]; // set the velocity of the voice to be the velocity of that note |
| 551 | poly->notes[noteToTest][1] = deactivatedVoice; //mark that it is no longer stolen and is now active | 565 | poly->notes[noteToTest][1] = deactivatedVoice; //mark that it is no longer stolen and is now active |
| @@ -618,6 +632,18 @@ void tPoly_setPitchGlideTime(tPoly* const polyh, float t) · 66 unmodified lines | |||
| 618 | } | 632 | } |
| 619 | } | 633 | } |
| 620 | 634 | ||
| 635 | void tPoly_setBendGlideTime(tPoly* const polyh, float t) | ||
| 636 | { | ||
| 637 | _tPoly* poly = *polyh; | ||
| 638 | tRamp_setTime(&poly->pitchBendRamp, t); | ||
| 639 | } | ||
| 640 | |||
| 641 | void tPoly_setBendSamplesPerTick(tPoly* const polyh, float t) | ||
| 642 | { | ||
| 643 | _tPoly* poly = *polyh; | ||
| 644 | poly->pitchBendRamp->samples_per_tick = t; | ||
| 645 | } | ||
| 646 | |||
| 621 | int tPoly_getNumVoices(tPoly* const polyh) | 647 | int tPoly_getNumVoices(tPoly* const polyh) |
| 622 | { | 648 | { |
| 623 | _tPoly* poly = *polyh; | 649 | _tPoly* poly = *polyh; |
| @@ -25,6 +25,7 @@ void tCycle_init(tCycle* const cy) · 24 unmodified lines | |||
| 25 | 25 | ||
| 26 | c->inc = 0.0f; | 26 | c->inc = 0.0f; |
| 27 | c->phase = 0.0f; | 27 | c->phase = 0.0f; |
| 28 | |||
| 28 | } | 29 | } |
| 29 | 30 | ||
| 30 | void tCycle_free(tCycle* const cy) | 31 | void tCycle_free(tCycle* const cy) |
| @@ -41,6 +42,7 @@ void tCycle_initToPool (tCycle* const cy, tMempool* const mp) · 10 unmodified lines | |||
| 41 | 42 | ||
| 42 | c->inc = 0.0f; | 43 | c->inc = 0.0f; |
| 43 | c->phase = 0.0f; | 44 | c->phase = 0.0f; |
| 45 | |||
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | void tCycle_freeFromPool (tCycle* const cy, tMempool* const mp) | 48 | void tCycle_freeFromPool (tCycle* const cy, tMempool* const mp) |
| @@ -55,30 +57,38 @@ int tCycle_setFreq(tCycle* const cy, float freq) · 8 unmodified lines | |||
| 55 | { | 57 | { |
| 56 | _tCycle* c = *cy; | 58 | _tCycle* c = *cy; |
| 57 | 59 | ||
| 58 | if (freq < 0.0f) freq = 0.0f; | ||
| 59 | |||
| 60 | c->freq = freq; | 60 | c->freq = freq; |
| 61 | c->inc = freq * leaf.invSampleRate; | 61 | c->inc = freq * leaf.invSampleRate; |
| 62 | 62 | ||
| 63 | return 0; | 63 | return 0; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | //need to check bounds and wrap table properly to allow through-zero FM | ||
| 66 | float tCycle_tick(tCycle* const cy) | 67 | float tCycle_tick(tCycle* const cy) |
| 67 | { | 68 | { |
| 68 | _tCycle* c = *cy; | 69 | _tCycle* c = *cy; |
| 70 | float temp;; | ||
| 71 | int intPart;; | ||
| 72 | float fracPart; | ||
| 73 | float samp0; | ||
| 74 | float samp1; | ||
| 69 | 75 | ||
| 70 | // Phasor increment | 76 | // Phasor increment |
| 71 | c->phase += c->inc; | 77 | c->phase += c->inc; |
| 72 | while (c->phase >= 1.0f) c->phase -= 1.0f; | 78 | while (c->phase >= 1.0f) c->phase -= 1.0f; |
| 73 | 79 | while (c->phase <= 0.0f) c->phase += 1.0f; | |
| 80 | |||
| 74 | // Wavetable synthesis | 81 | // Wavetable synthesis |
| 75 | float temp = SINE_TABLE_SIZE * c->phase; | 82 | |
| 76 | int intPart = (int)temp; | 83 | temp = SINE_TABLE_SIZE * c->phase; |
| 77 | float fracPart = temp - (float)intPart; | 84 | intPart = (int)temp; |
| 78 | float samp0 = sinewave[intPart]; | 85 | fracPart = temp - (float)intPart; |
| 79 | if (++intPart >= SINE_TABLE_SIZE) intPart = 0; | 86 | samp0 = sinewave[intPart]; |
| 80 | float samp1 = sinewave[intPart]; | 87 | if (++intPart >= SINE_TABLE_SIZE) intPart = 0; |
| 88 | samp1 = sinewave[intPart]; | ||
| 89 | |||
| 81 | return (samp0 + (samp1 - samp0) * fracPart); | 90 | return (samp0 + (samp1 - samp0) * fracPart); |
| 91 | |||
| 82 | } | 92 | } |
| 83 | 93 | ||
| 84 | void tCycleSampleRateChanged (tCycle* const cy) | 94 | void tCycleSampleRateChanged (tCycle* const cy) |