From 80b488292202479f31f7914c48ffb96be02da8a0 Mon Sep 17 00:00:00 2001 From: Stepan Moskovchenko Date: Mon, 2 Oct 2006 04:13:33 +0000 Subject: I have an iRiver again, yay! Make notes ramp down in a better way. Fix note-off pop/click due to waveform index out of bounds access. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11105 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/midi/synth.c | 55 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 16 deletions(-) (limited to 'apps/plugins/midi/synth.c') diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c index 2ec263da60..1b7145a372 100644 --- a/apps/plugins/midi/synth.c +++ b/apps/plugins/midi/synth.c @@ -252,7 +252,7 @@ inline void stopVoice(struct SynthObject * so) if(so->state == STATE_RAMPDOWN) return; so->state = STATE_RAMPDOWN; - so->decay = 255; + so->decay = 0; } @@ -267,16 +267,41 @@ signed short int synthVoice(struct SynthObject * so) wf = so->wf; - if(so->state != STATE_RAMPDOWN) + /* Is voice being ramped? */ + if(so->state == STATE_RAMPDOWN) + { + if(so->decay != 0) /* Ramp has been started */ + { + so->decay = so->decay / 2; + + if(so->decay < 10 && so->decay > -10) + so->isUsed = 0; + + if(so->state == STATE_RAMPDOWN) + { + so->decay-=5; + if(so->decay < 5) + so->isUsed=0; + s = (s * so->decay) >> 8; + } + + + return so->decay*so->volscale>>14; + } + } else /* OK to advance voice */ { so->cp += so->delta; } + cpShifted = so->cp >> FRACTSIZE; //Was 10 - if( (cpShifted > (wf->numSamples) && (so->state != STATE_RAMPDOWN))) + /* Have we overrun? */ + if( (cpShifted >= (wf->numSamples-1))) { - stopVoice(so); + so->cp -= so->delta; + cpShifted = so->cp >> FRACTSIZE; + stopVoice(so); } s2 = getSample((cpShifted)+1, wf); @@ -314,8 +339,8 @@ signed short int synthVoice(struct SynthObject * so) } /* Better, working, linear interpolation */ - s1=getSample((cpShifted), wf); //\|/ Was 1023)) >> 10 -// s = s1 + ((signed)((s2 - s1) * (so->cp & (1023)))>>10); //Was 10 + s1=getSample((cpShifted), wf); + s = s1 + ((signed)((s2 - s1) * (so->cp & ((1<>FRACTSIZE); //Was 10 /* ADSR COMMENT WOULD GO FROM HERE.........*/ @@ -324,7 +349,7 @@ signed short int synthVoice(struct SynthObject * so) stopVoice(so); - if(so->ch != 9) /* Stupid ADSR code... and don't do ADSR for drums */ + if(so->ch != 9 && so->state != STATE_RAMPDOWN) /* Stupid ADSR code... and don't do ADSR for drums */ { if(so->curOffset < so->targetOffset) { @@ -352,22 +377,20 @@ signed short int synthVoice(struct SynthObject * so) } if(so->curOffset < 0) - so->isUsed=0; /* This is OK because offset faded it out already */ - + stopVoice(so); s = (s * (so->curOffset >> 22) >> 8); -/* ............. TO HERE */ - - if(so->state == STATE_RAMPDOWN) + /* need to set ramp beginning */ + if(so->state == STATE_RAMPDOWN && so->decay == 0) { - so->decay-=5; - if(so->decay < 5) - so->isUsed=0; - s = (s * so->decay) >> 8; + so->decay = s; } + +/* ............. TO HERE */ + /* Scaling by channel volume and note volume is done in sequencer.c */ /* That saves us some multiplication and pointer operations */ return s*so->volscale>>14; -- cgit v1.2.3