summaryrefslogtreecommitdiff
path: root/src/libfaad/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libfaad/output.c')
-rw-r--r--src/libfaad/output.c206
1 files changed, 142 insertions, 64 deletions
diff --git a/src/libfaad/output.c b/src/libfaad/output.c
index 5b370c4bd..8a005c87e 100644
--- a/src/libfaad/output.c
+++ b/src/libfaad/output.c
@@ -1,19 +1,19 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: output.c,v 1.6 2004/12/03 01:15:30 tmattern Exp $
+** $Id: output.c,v 1.7 2005/10/29 23:57:07 tmmm Exp $
**/
#include "common.h"
@@ -84,7 +84,7 @@ if (sample >= 0.0f) \
#define CONV(a,b) ((a<<1)|(b&0x1))
-static void to_PCM_16bit(faacDecHandle hDecoder, real_t **input,
+static void to_PCM_16bit(NeAACDecHandle hDecoder, real_t **input,
uint8_t channels, uint16_t frame_len,
int16_t **sample_buffer)
{
@@ -105,18 +105,32 @@ static void to_PCM_16bit(faacDecHandle hDecoder, real_t **input,
}
break;
case CONV(2,0):
- ch = hDecoder->internal_channel[0];
- ch1 = hDecoder->internal_channel[1];
- for(i = 0; i < frame_len; i++)
+ if (hDecoder->upMatrix)
{
- real_t inp0 = input[ch ][i];
- real_t inp1 = input[ch1][i];
+ ch = hDecoder->internal_channel[0];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch][i];
- CLIP(inp0, 32767.0f, -32768.0f);
- CLIP(inp1, 32767.0f, -32768.0f);
+ CLIP(inp0, 32767.0f, -32768.0f);
- (*sample_buffer)[(i*2)+0] = (int16_t)lrintf(inp0);
- (*sample_buffer)[(i*2)+1] = (int16_t)lrintf(inp1);
+ (*sample_buffer)[(i*2)+0] = (int16_t)lrintf(inp0);
+ (*sample_buffer)[(i*2)+1] = (int16_t)lrintf(inp0);
+ }
+ } else {
+ ch = hDecoder->internal_channel[0];
+ ch1 = hDecoder->internal_channel[1];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch ][i];
+ real_t inp1 = input[ch1][i];
+
+ CLIP(inp0, 32767.0f, -32768.0f);
+ CLIP(inp1, 32767.0f, -32768.0f);
+
+ (*sample_buffer)[(i*2)+0] = (int16_t)lrintf(inp0);
+ (*sample_buffer)[(i*2)+1] = (int16_t)lrintf(inp1);
+ }
}
break;
default:
@@ -135,7 +149,7 @@ static void to_PCM_16bit(faacDecHandle hDecoder, real_t **input,
}
}
-static void to_PCM_24bit(faacDecHandle hDecoder, real_t **input,
+static void to_PCM_24bit(NeAACDecHandle hDecoder, real_t **input,
uint8_t channels, uint16_t frame_len,
int32_t **sample_buffer)
{
@@ -157,20 +171,35 @@ static void to_PCM_24bit(faacDecHandle hDecoder, real_t **input,
}
break;
case CONV(2,0):
- ch = hDecoder->internal_channel[0];
- ch1 = hDecoder->internal_channel[1];
- for(i = 0; i < frame_len; i++)
+ if (hDecoder->upMatrix)
{
- real_t inp0 = input[ch ][i];
- real_t inp1 = input[ch1][i];
+ ch = hDecoder->internal_channel[0];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch][i];
+
+ inp0 *= 256.0f;
+ CLIP(inp0, 8388607.0f, -8388608.0f);
+
+ (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0);
+ (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp0);
+ }
+ } else {
+ ch = hDecoder->internal_channel[0];
+ ch1 = hDecoder->internal_channel[1];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch ][i];
+ real_t inp1 = input[ch1][i];
- inp0 *= 256.0f;
- inp1 *= 256.0f;
- CLIP(inp0, 8388607.0f, -8388608.0f);
- CLIP(inp1, 8388607.0f, -8388608.0f);
+ inp0 *= 256.0f;
+ inp1 *= 256.0f;
+ CLIP(inp0, 8388607.0f, -8388608.0f);
+ CLIP(inp1, 8388607.0f, -8388608.0f);
- (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0);
- (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp1);
+ (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0);
+ (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp1);
+ }
}
break;
default:
@@ -190,7 +219,7 @@ static void to_PCM_24bit(faacDecHandle hDecoder, real_t **input,
}
}
-static void to_PCM_32bit(faacDecHandle hDecoder, real_t **input,
+static void to_PCM_32bit(NeAACDecHandle hDecoder, real_t **input,
uint8_t channels, uint16_t frame_len,
int32_t **sample_buffer)
{
@@ -212,20 +241,35 @@ static void to_PCM_32bit(faacDecHandle hDecoder, real_t **input,
}
break;
case CONV(2,0):
- ch = hDecoder->internal_channel[0];
- ch1 = hDecoder->internal_channel[1];
- for(i = 0; i < frame_len; i++)
+ if (hDecoder->upMatrix)
{
- real_t inp0 = input[ch ][i];
- real_t inp1 = input[ch1][i];
+ ch = hDecoder->internal_channel[0];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch][i];
- inp0 *= 65536.0f;
- inp1 *= 65536.0f;
- CLIP(inp0, 2147483647.0f, -2147483648.0f);
- CLIP(inp1, 2147483647.0f, -2147483648.0f);
+ inp0 *= 65536.0f;
+ CLIP(inp0, 2147483647.0f, -2147483648.0f);
- (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0);
- (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp1);
+ (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0);
+ (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp0);
+ }
+ } else {
+ ch = hDecoder->internal_channel[0];
+ ch1 = hDecoder->internal_channel[1];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch ][i];
+ real_t inp1 = input[ch1][i];
+
+ inp0 *= 65536.0f;
+ inp1 *= 65536.0f;
+ CLIP(inp0, 2147483647.0f, -2147483648.0f);
+ CLIP(inp1, 2147483647.0f, -2147483648.0f);
+
+ (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0);
+ (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp1);
+ }
}
break;
default:
@@ -245,7 +289,7 @@ static void to_PCM_32bit(faacDecHandle hDecoder, real_t **input,
}
}
-static void to_PCM_float(faacDecHandle hDecoder, real_t **input,
+static void to_PCM_float(NeAACDecHandle hDecoder, real_t **input,
uint8_t channels, uint16_t frame_len,
float32_t **sample_buffer)
{
@@ -263,14 +307,25 @@ static void to_PCM_float(faacDecHandle hDecoder, real_t **input,
}
break;
case CONV(2,0):
- ch = hDecoder->internal_channel[0];
- ch1 = hDecoder->internal_channel[1];
- for(i = 0; i < frame_len; i++)
+ if (hDecoder->upMatrix)
{
- real_t inp0 = input[ch ][i];
- real_t inp1 = input[ch1][i];
- (*sample_buffer)[(i*2)+0] = inp0*FLOAT_SCALE;
- (*sample_buffer)[(i*2)+1] = inp1*FLOAT_SCALE;
+ ch = hDecoder->internal_channel[0];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch][i];
+ (*sample_buffer)[(i*2)+0] = inp0*FLOAT_SCALE;
+ (*sample_buffer)[(i*2)+1] = inp0*FLOAT_SCALE;
+ }
+ } else {
+ ch = hDecoder->internal_channel[0];
+ ch1 = hDecoder->internal_channel[1];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch ][i];
+ real_t inp1 = input[ch1][i];
+ (*sample_buffer)[(i*2)+0] = inp0*FLOAT_SCALE;
+ (*sample_buffer)[(i*2)+1] = inp1*FLOAT_SCALE;
+ }
}
break;
default:
@@ -286,7 +341,7 @@ static void to_PCM_float(faacDecHandle hDecoder, real_t **input,
}
}
-static void to_PCM_double(faacDecHandle hDecoder, real_t **input,
+static void to_PCM_double(NeAACDecHandle hDecoder, real_t **input,
uint8_t channels, uint16_t frame_len,
double **sample_buffer)
{
@@ -304,14 +359,25 @@ static void to_PCM_double(faacDecHandle hDecoder, real_t **input,
}
break;
case CONV(2,0):
- ch = hDecoder->internal_channel[0];
- ch1 = hDecoder->internal_channel[1];
- for(i = 0; i < frame_len; i++)
+ if (hDecoder->upMatrix)
{
- real_t inp0 = input[ch ][i];
- real_t inp1 = input[ch1][i];
- (*sample_buffer)[(i*2)+0] = (double)inp0*FLOAT_SCALE;
- (*sample_buffer)[(i*2)+1] = (double)inp1*FLOAT_SCALE;
+ ch = hDecoder->internal_channel[0];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch][i];
+ (*sample_buffer)[(i*2)+0] = (double)inp0*FLOAT_SCALE;
+ (*sample_buffer)[(i*2)+1] = (double)inp0*FLOAT_SCALE;
+ }
+ } else {
+ ch = hDecoder->internal_channel[0];
+ ch1 = hDecoder->internal_channel[1];
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t inp0 = input[ch ][i];
+ real_t inp1 = input[ch1][i];
+ (*sample_buffer)[(i*2)+0] = (double)inp0*FLOAT_SCALE;
+ (*sample_buffer)[(i*2)+1] = (double)inp1*FLOAT_SCALE;
+ }
}
break;
default:
@@ -327,7 +393,7 @@ static void to_PCM_double(faacDecHandle hDecoder, real_t **input,
}
}
-void *output_to_PCM(faacDecHandle hDecoder,
+void *output_to_PCM(NeAACDecHandle hDecoder,
real_t **input, void *sample_buffer, uint8_t channels,
uint16_t frame_len, uint8_t format)
{
@@ -374,8 +440,12 @@ void *output_to_PCM(faacDecHandle hDecoder,
#define RSQRT2 FRAC_CONST(0.7071067811865475244) // 1/sqrt(2)
static INLINE real_t get_sample(real_t **input, uint8_t channel, uint16_t sample,
- uint8_t down_matrix, uint8_t *internal_channel)
+ uint8_t down_matrix, uint8_t up_matrix,
+ uint8_t *internal_channel)
{
+ if (up_matrix == 1)
+ return input[internal_channel[0]][sample];
+
if (!down_matrix)
return input[internal_channel[channel]][sample];
@@ -393,7 +463,7 @@ static INLINE real_t get_sample(real_t **input, uint8_t channel, uint16_t sample
}
}
-void* output_to_PCM(faacDecHandle hDecoder,
+void* output_to_PCM(NeAACDecHandle hDecoder,
real_t **input, void *sample_buffer, uint8_t channels,
uint16_t frame_len, uint8_t format)
{
@@ -410,8 +480,8 @@ void* output_to_PCM(faacDecHandle hDecoder,
case FAAD_FMT_16BIT:
for(i = 0; i < frame_len; i++)
{
- //int32_t tmp = input[ch][i];
- int32_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel);
+ int32_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->upMatrix,
+ hDecoder->internal_channel);
if (tmp >= 0)
{
tmp += (1 << (REAL_BITS-1));
@@ -433,8 +503,8 @@ void* output_to_PCM(faacDecHandle hDecoder,
case FAAD_FMT_24BIT:
for(i = 0; i < frame_len; i++)
{
- //int32_t tmp = input[ch][i];
- int32_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel);
+ int32_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->upMatrix,
+ hDecoder->internal_channel);
if (tmp >= 0)
{
tmp += (1 << (REAL_BITS-9));
@@ -457,8 +527,8 @@ void* output_to_PCM(faacDecHandle hDecoder,
case FAAD_FMT_32BIT:
for(i = 0; i < frame_len; i++)
{
- //int32_t tmp = input[ch][i];
- int32_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel);
+ int32_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->upMatrix,
+ hDecoder->internal_channel);
if (tmp >= 0)
{
tmp += (1 << (16-REAL_BITS-1));
@@ -470,6 +540,14 @@ void* output_to_PCM(faacDecHandle hDecoder,
int_sample_buffer[(i*channels)+ch] = (int32_t)tmp;
}
break;
+ case FAAD_FMT_FIXED:
+ for(i = 0; i < frame_len; i++)
+ {
+ real_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->upMatrix,
+ hDecoder->internal_channel);
+ int_sample_buffer[(i*channels)+ch] = (int32_t)tmp;
+ }
+ break;
}
}