summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
authorStepan Moskovchenko <stevenm@rockbox.org>2006-10-02 04:13:33 +0000
committerStepan Moskovchenko <stevenm@rockbox.org>2006-10-02 04:13:33 +0000
commit80b488292202479f31f7914c48ffb96be02da8a0 (patch)
treeecbfbaba1e7288f445d48cadfde80d58a18a1767 /apps/plugins
parentd72506cf985e86610ad3b2dd88bbde8be6dc2428 (diff)
downloadrockbox-80b488292202479f31f7914c48ffb96be02da8a0.zip
rockbox-80b488292202479f31f7914c48ffb96be02da8a0.tar.gz
rockbox-80b488292202479f31f7914c48ffb96be02da8a0.tar.bz2
rockbox-80b488292202479f31f7914c48ffb96be02da8a0.tar.xz
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
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/midi/synth.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/apps/plugins/midi/synth.c b/apps/plugins/midi/synth.c
index 2ec263d..1b7145a 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)-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;