aboutsummaryrefslogtreecommitdiffstats
path: root/codecs/mp3/src/dec8.c
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>1999-12-07 05:45:48 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>1999-12-07 05:45:48 +0000
commit878dd470f235a2c945f2410927175a45f052b234 (patch)
tree4fc09f73bccf2e5017fd2dab7019e076351cab9b /codecs/mp3/src/dec8.c
parent070e10a75492938462eeac565c78c8c16a02fc74 (diff)
Version 0.1.1 from FTP
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@95 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'codecs/mp3/src/dec8.c')
-rwxr-xr-xcodecs/mp3/src/dec8.c338
1 files changed, 338 insertions, 0 deletions
diff --git a/codecs/mp3/src/dec8.c b/codecs/mp3/src/dec8.c
new file mode 100755
index 000000000..478bbf1df
--- /dev/null
+++ b/codecs/mp3/src/dec8.c
@@ -0,0 +1,338 @@
+/*____________________________________________________________________________
+
+ FreeAmp - The Free MP3 Player
+
+ MP3 Decoder originally Copyright (C) 1995-1997 Xing Technology
+ Corp. http://www.xingtech.com
+
+ Portions Copyright (C) 1998-1999 EMusic.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
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+____________________________________________________________________________*/
+
+/**** dec8.c ***************************************************
+
+
+ANSI C
+MPEG audio decoder Layer II only mpeg1 and mpeg2
+output sample type and sample rate conversion
+ decode mpeg to 8000Ks mono
+ output 16 bit linear, 8 bit linear, or u-law
+
+
+mod 6/29/95 bugfix in u-law table
+
+mod 11/15/95 for Layer I
+
+mod 1/7/97 minor mods for warnings
+
+******************************************************************/
+/*****************************************************************
+
+ MPEG audio software decoder portable ANSI c.
+ Decodes all Layer II to 8000Ks mono pcm.
+ Output selectable: 16 bit linear, 8 bit linear, u-law.
+
+-------------------------------------
+int audio_decode8_init(MPEG_HEAD *h, int framebytes_arg,
+ int reduction_code, int transform_code, int convert_code,
+ int freq_limit)
+
+initilize decoder:
+ return 0 = fail, not 0 = success
+
+MPEG_HEAD *h input, mpeg header info (returned by call to head_info)
+framebytes input, mpeg frame size (returned by call to head_info)
+reduction_code input, ignored
+transform_code input, ignored
+convert_code input, set convert_code = 4*bit_code + chan_code
+ bit_code: 1 = 16 bit linear pcm
+ 2 = 8 bit (unsigned) linear pcm
+ 3 = u-law (8 bits unsigned)
+ chan_code: 0 = convert two chan to mono
+ 1 = convert two chan to mono
+ 2 = convert two chan to left chan
+ 3 = convert two chan to right chan
+freq_limit input, ignored
+
+
+---------------------------------
+void audio_decode8_info( DEC_INFO *info)
+
+information return:
+ Call after audio_decode8_init. See mhead.h for
+ information returned in DEC_INFO structure.
+
+
+---------------------------------
+IN_OUT audio_decode8(unsigned char *bs, void *pcmbuf)
+
+decode one mpeg audio frame:
+bs input, mpeg bitstream, must start with
+ sync word. Caution: may read up to 3 bytes
+ beyond end of frame.
+pcmbuf output, pcm samples.
+
+IN_OUT structure returns:
+ Number bytes conceptually removed from mpeg bitstream.
+ Returns 0 if sync loss.
+ Number bytes of pcm output. This may vary from frame
+ to frame.
+
+*****************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <float.h>
+#include <math.h>
+#include "L3.h"
+#include "mhead.h" /* mpeg header structure */
+
+
+
+
+
+/*------------------------------------------*/
+static int output_code;
+static int convert(void *mv, unsigned char *pcm);
+static int convert_8bit(void *mv, unsigned char *pcm);
+static int convert_u(void *mv, unsigned char *pcm);
+static CVT_FUNCTION_8 cvt_table[3] =
+{
+ convert,
+ convert_8bit,
+ convert_u,
+};
+
+void mpeg8_init(MPEG8 *m)
+{
+ memset(&m->dec, 0, sizeof(m->dec));
+ m->dec.ncnt = 8 * 288;
+ m->dec.ncnt1 = 8 * 287;
+ m->dec.nlast = 287;
+ m->dec.ndeci = 11;
+ m->dec.kdeci = 8 * 288;
+ m->dec.first_pass = 1;
+}
+
+/*====================================================================*/
+IN_OUT audio_decode8(MPEG8 *m, unsigned char *bs, signed short *pcmbuf)
+{
+ IN_OUT x;
+
+ x = audio_decode(&m->cupper, bs, m->dec.pcm);
+ if (x.in_bytes <= 0)
+ return x;
+ x.out_bytes = m->dec.convert_routine(m, (void *) pcmbuf);
+
+ return x;
+}
+/*--------------8Ks 16 bit pcm --------------------------------*/
+static int convert(void *mv, unsigned char y0[])
+{
+ MPEG8 *m = mv;
+ int i, k;
+ long alpha;
+ short *y;
+
+ y = (short *) y0;
+ k = 0;
+ if (m->dec.kdeci < m->dec.ncnt)
+ {
+ alpha = m->dec.kdeci & 7;
+ y[k++] = (short) (m->dec.xsave + ((alpha * (m->dec.pcm[0] - m->dec.xsave)) >> 3));
+ m->dec.kdeci += m->dec.ndeci;
+ }
+ m->dec.kdeci -= m->dec.ncnt;
+ for (; m->dec.kdeci < m->dec.ncnt1; m->dec.kdeci += m->dec.ndeci)
+ {
+ i = m->dec.kdeci >> 3;
+ alpha = m->dec.kdeci & 7;
+ y[k++] = (short) (m->dec.pcm[i] + ((alpha * (m->dec.pcm[i + 1] - m->dec.pcm[i])) >> 3));
+ }
+ m->dec.xsave = m->dec.pcm[m->dec.nlast];
+
+/* printf("\n k out = %4d", k); */
+
+ return sizeof(short) * k;
+}
+/*----------------8Ks 8 bit unsigned pcm ---------------------------*/
+static int convert_8bit(void *mv, unsigned char y[])
+{
+ MPEG8 *m = mv;
+ int i, k;
+ long alpha;
+
+ k = 0;
+ if (m->dec.kdeci < m->dec.ncnt)
+ {
+ alpha = m->dec.kdeci & 7;
+ y[k++] = (unsigned char) (((m->dec.xsave + ((alpha * (m->dec.pcm[0] - m->dec.xsave)) >> 3)) >> 8) + 128);
+ m->dec.kdeci += m->dec.ndeci;
+ }
+ m->dec.kdeci -= m->dec.ncnt;
+ for (; m->dec.kdeci < m->dec.ncnt1; m->dec.kdeci += m->dec.ndeci)
+ {
+ i = m->dec.kdeci >> 3;
+ alpha = m->dec.kdeci & 7;
+ y[k++] = (unsigned char) (((m->dec.pcm[i] + ((alpha * (m->dec.pcm[i + 1] - m->dec.pcm[i])) >> 3)) >> 8) + 128);
+ }
+ m->dec.xsave = m->dec.pcm[m->dec.nlast];
+
+/* printf("\n k out = %4d", k); */
+
+ return k;
+}
+/*--------------8Ks u-law --------------------------------*/
+static int convert_u(void *mv, unsigned char y[])
+{
+ MPEG8 *m = mv;
+ int i, k;
+ long alpha;
+ unsigned char *look;
+
+ look = m->dec.look_u + 4096;
+
+ k = 0;
+ if (m->dec.kdeci < m->dec.ncnt)
+ {
+ alpha = m->dec.kdeci & 7;
+ y[k++] = look[(m->dec.xsave + ((alpha * (m->dec.pcm[0] - m->dec.xsave)) >> 3)) >> 3];
+ m->dec.kdeci += m->dec.ndeci;
+ }
+ m->dec.kdeci -= m->dec.ncnt;
+ for (; m->dec.kdeci < m->dec.ncnt1; m->dec.kdeci += m->dec.ndeci)
+ {
+ i = m->dec.kdeci >> 3;
+ alpha = m->dec.kdeci & 7;
+ y[k++] = look[(m->dec.pcm[i] + ((alpha * (m->dec.pcm[i + 1] - m->dec.pcm[i])) >> 3)) >> 3];
+ }
+ m->dec.xsave = m->dec.pcm[m->dec.nlast];
+
+/* printf("\n k out = %4d", k); */
+
+ return k;
+}
+/*--------------------------------------------------------------------*/
+static int ucomp3(int x) /* re analog devices CCITT G.711 */
+{
+ int s, p, y, t, u, u0, sign;
+
+ sign = 0;
+ if (x < 0)
+ {
+ x = -x;
+ sign = 0x0080;
+ }
+ if (x > 8031)
+ x = 8031;
+ x += 33;
+ t = x;
+ for (s = 0; s < 15; s++)
+ {
+ if (t & 0x4000)
+ break;
+ t <<= 1;
+ }
+ y = x << s;
+ p = (y >> 10) & 0x0f; /* position */
+ s = 9 - s; /* segment */
+ u0 = (((s << 4) | p) & 0x7f) | sign;
+ u = u0 ^ 0xff;
+
+ return u;
+}
+/*------------------------------------------------------------------*/
+static void table_init(MPEG8 *m)
+{
+ int i;
+
+ for (i = -4096; i < 4096; i++)
+ m->dec.look_u[4096 + i] = (unsigned char) (ucomp3(2 * i));
+
+}
+/*-------------------------------------------------------------------*/
+int audio_decode8_init(MPEG8 *m, MPEG_HEAD * h, int framebytes_arg,
+ int reduction_code, int transform_code, int convert_code,
+ int freq_limit)
+{
+ int istat;
+ int outvals;
+ static int sr_table[2][4] =
+ {{22, 24, 16, 0}, {44, 48, 32, 0}};
+
+ if (m->dec.first_pass)
+ {
+ table_init(m);
+ m->dec.first_pass = 0;
+ }
+
+ if ((h->sync & 1) == 0)
+ return 0; // fail mpeg 2.5
+
+ output_code = convert_code >> 2;
+ if (output_code < 1)
+ output_code = 1; /* 1= 16bit 2 = 8bit 3 = u */
+ if (output_code > 3)
+ output_code = 3; /* 1= 16bit 2 = 8bit 3 = u */
+
+ convert_code = convert_code & 3;
+ if (convert_code <= 0)
+ convert_code = 1; /* always cvt to mono */
+
+ reduction_code = 1;
+ if (h->id)
+ reduction_code = 2;
+
+/* select convert routine */
+ m->dec.convert_routine = cvt_table[output_code - 1];
+
+/* init decimation/convert routine */
+/*-- MPEG-2 layer III --*/
+ if ((h->option == 1) && h->id == 0)
+ outvals = 576 >> reduction_code;
+ else if (h->option == 3)
+ outvals = 384 >> reduction_code;
+/*-- layer I --*/
+ else
+ outvals = 1152 >> reduction_code;
+ m->dec.ncnt = 8 * outvals;
+ m->dec.ncnt1 = 8 * (outvals - 1);
+ m->dec.nlast = outvals - 1;
+ m->dec.ndeci = sr_table[h->id][h->sr_index] >> reduction_code;
+ m->dec.kdeci = 8 * outvals;
+/* printf("\n outvals %d", outvals); */
+
+ freq_limit = 3200;
+ istat = audio_decode_init(&m->cupper, h, framebytes_arg,
+ reduction_code, transform_code, convert_code,
+ freq_limit);
+
+
+ return istat;
+}
+/*-----------------------------------------------------------------*/
+void audio_decode8_info(MPEG8 *m, DEC_INFO * info)
+{
+
+ audio_decode_info(&m->cupper, info);
+ info->samprate = 8000;
+ if (output_code != 1)
+ info->bits = 8;
+ if (output_code == 3)
+ info->type = 10;
+}