use dsputil for float to signed 16-bit sample conversion
authorJustin Ruggles <justin.ruggles@gmail.com>
Sat, 4 Aug 2007 20:59:22 +0000 (20:59 +0000)
committerJustin Ruggles <justin.ruggles@gmail.com>
Sat, 4 Aug 2007 20:59:22 +0000 (20:59 +0000)
Originally committed as revision 9914 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/ac3dec.c

index a85c135afc1118a1f3f93790648a3ee2b4f997a2..2c615d97b5285a37f7cb4d5b49a30ba44e2643d9 100644 (file)
@@ -150,8 +150,11 @@ typedef struct {
     MDCTContext imdct_512;  //for 512 sample imdct transform
     MDCTContext imdct_256;  //for 256 sample imdct transform
     DSPContext  dsp;        //for optimization
+    float       add_bias;   ///< offset for float_to_int16 conversion
+    float       mul_bias;   ///< scaling for float_to_int16 conversion
 
     DECLARE_ALIGNED_16(float, output[AC3_MAX_CHANNELS-1][256]); //output after imdct transform and windowing
+    DECLARE_ALIGNED_16(short, int_output[AC3_MAX_CHANNELS-1][256]); ///< final 16-bit integer output
     DECLARE_ALIGNED_16(float, delay[AC3_MAX_CHANNELS-1][256]);  //delay - added to the next block
     DECLARE_ALIGNED_16(float, tmp_imdct[256]);                  //temporary storage for imdct transform
     DECLARE_ALIGNED_16(float, tmp_output[512]);                 //temporary storage for output before windowing
@@ -262,6 +265,14 @@ static int ac3_decode_init(AVCodecContext *avctx)
     dsputil_init(&ctx->dsp, avctx);
     av_init_random(0, &ctx->dith_state);
 
+    if(ctx->dsp.float_to_int16 == ff_float_to_int16_c) {
+        ctx->add_bias = 385.0f;
+        ctx->mul_bias = 1.0f;
+    } else {
+        ctx->add_bias = 0.0f;
+        ctx->mul_bias = 32767.0f;
+    }
+
     return 0;
 }
 /*********** END INIT FUNCTIONS ***********/
@@ -651,7 +662,7 @@ static inline void do_imdct(AC3DecodeContext *ctx)
                                           ctx->tmp_imdct);
         }
         ctx->dsp.vector_fmul_add_add(ctx->output[ch-1], ctx->tmp_output,
-                                     ctx->window, ctx->delay[ch-1], 384, 256, 1);
+                                     ctx->window, ctx->delay[ch-1], ctx->add_bias, 256, 1);
         ctx->dsp.vector_fmul_reverse(ctx->delay[ch-1], ctx->tmp_output+256,
                                      ctx->window, 256);
     }
@@ -921,7 +932,7 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk)
 
     /* apply scaling to coefficients (headroom, dynrng) */
     for(ch=1; ch<=ctx->nchans; ch++) {
-        float gain = 2.0f;
+        float gain = 2.0f * ctx->mul_bias;
         if(ctx->acmod == AC3_ACMOD_DUALMONO && ch == 2) {
             gain *= ctx->dynrng2;
         } else {
@@ -934,17 +945,12 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk)
 
     do_imdct(ctx);
 
-    return 0;
-}
+    /* convert float to 16-bit integer */
+    for(ch=0; ch<ctx->out_channels; ch++) {
+        ctx->dsp.float_to_int16(ctx->int_output[ch], ctx->output[ch], 256);
+    }
 
-static inline int16_t convert(int32_t i)
-{
-    if (i > 0x43c07fff)
-        return 32767;
-    else if (i <= 0x43bf8000)
-        return -32768;
-    else
-        return (i - 0x43c00000);
+    return 0;
 }
 
 /* Decode ac3 frame.
@@ -960,10 +966,6 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
     AC3DecodeContext *ctx = (AC3DecodeContext *)avctx->priv_data;
     int16_t *out_samples = (int16_t *)data;
     int i, blk, ch;
-    int32_t *int_ptr[6];
-
-    for (ch = 0; ch < 6; ch++)
-        int_ptr[ch] = (int32_t *)(&ctx->output[ch]);
 
     //Initialize the GetBitContext with the start of valid AC3 Frame.
     init_get_bits(&ctx->gb, buf, buf_size * 8);
@@ -999,7 +1001,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
         }
         for (i = 0; i < 256; i++)
             for (ch = 0; ch < ctx->out_channels; ch++)
-                *(out_samples++) = convert(int_ptr[ch][i]);
+                *(out_samples++) = ctx->int_output[ch][i];
     }
     *data_size = NB_BLOCKS * 256 * avctx->channels * sizeof (int16_t);
     return ctx->frame_size;