SPC codec on Coldfire: Urgh. There was a whole gain stage I overlooked. :P Kill another several boost points.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12561 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/codecs/spc/Spc_Dsp.h b/apps/codecs/spc/Spc_Dsp.h
index d09b753..291d6ec 100644
--- a/apps/codecs/spc/Spc_Dsp.h
+++ b/apps/codecs/spc/Spc_Dsp.h
@@ -6,6 +6,8 @@
  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
  *                     \/            \/     \/    \/            \/
  *
+ * $Id$
+ *
  * Copyright (C) 2006-2007 Adam Gashlin (hcs)
  * Copyright (C) 2004-2007 Shay Green (blargg)
  * Copyright (C) 2002 Brad Martin
@@ -880,7 +882,7 @@
         #if !SPC_NOINTERP
             /* Interleved gauss table (to improve cache coherency). */
             /* gauss [i * 2 + j] = normal_gauss [(1 - j) * 256 + i] */
-            static short const gauss [512] =
+            static short const gauss [512] ICONST_ATTR =
             {
 370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303,
 339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299,
@@ -915,7 +917,6 @@
   0, 434,   0, 430,   0, 426,   0, 422,   0, 418,   0, 414,   0, 410,   0, 405,
   0, 401,   0, 397,   0, 393,   0, 389,   0, 385,   0, 381,   0, 378,   0, 374,
             };
-            
             /* Gaussian interpolation using most recent 4 samples */
             long position = voice->position;
             voice->position += rate;
@@ -969,7 +970,8 @@
         #else
         /* two-point linear interpolation */
         #ifdef CPU_COLDFIRE
-            int32_t  output = (int16_t)this->noise;
+            int amp_0 = (int16_t)this->noise;
+            int amp_1;
 
             if ( (this->r.g.noise_enables & vbit) == 0 )
             {
@@ -1001,12 +1003,45 @@
                 /* output = y0 + (result >> 12)          */
                 "asr.l      %[sh], %[y1]              \r\n"
                 "add.l      %[y0], %[y1]              \r\n"
-                : [f]"+&d"(f), [y0]"=&a"(y0), [y1]"=&d"(output)
+                : [f]"+&d"(f), [y0]"=&a"(y0), [y1]"=&d"(amp_0)
                 : [s]"a"(voice->samples), [sh]"d"(12)
                     );
             }
 
+            /* apply voice envelope to output */
+            asm volatile (
+            "mac.w %[output]l, %[envx]l, %%acc0 \r\n"
+            :
+            : [output]"r"(amp_0), [envx]"r"(voice->envx)
+            );
+
+            /* advance voice position */
             voice->position += rate;
+
+            /* fetch output, scale and apply left and right
+               voice volume */
+            asm volatile (
+            "movclr.l %%acc0,    %[output]         \r\n"
+            "asr.l    %[sh],     %[output]         \r\n"
+            "mac.l    %[vvol_0], %[output], %%acc0 \r\n"
+            "mac.l    %[vvol_1], %[output], %%acc1 \r\n"
+            : [output]"=&r"(amp_0)
+            : [vvol_0]"r"((int)voice->volume[0]),
+              [vvol_1]"r"((int)voice->volume[1]),
+              [sh]"d"(11)
+            );
+
+            /* save this output into previous, scale and save in
+               output register */
+            prev_outx = amp_0;
+            raw_voice->outx = amp_0 >> 8;
+
+            /* fetch final voice output */
+            asm volatile (
+            "movclr.l %%acc0, %[amp_0] \r\n"
+            "movclr.l %%acc1, %[amp_1] \r\n"
+            : [amp_0]"=r"(amp_0), [amp_1]"=r"(amp_1)
+            );
         #else
 
             /* Try this one out on ARM and see - similar to above but the asm
@@ -1043,8 +1078,6 @@
             if ( this->r.g.noise_enables & vbit )
                 output = *(int16_t*) &this->noise;
 #endif
-        #endif /* CPU_COLDFIRE */
-
             output = (output * voice->envx) >> 11;
 
             /* duplicated here to give compiler more to run in parallel */
@@ -1053,6 +1086,7 @@
 
             prev_outx = output;
             raw_voice->outx = (int8_t) (output >> 8);
+        #endif /* CPU_COLDFIRE */
         #endif
         
         #if SPC_BRRCACHE