diff spandsp-0.0.3/spandsp-0.0.3/src/gsm0610_preprocess.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spandsp-0.0.3/spandsp-0.0.3/src/gsm0610_preprocess.c	Fri Jun 25 16:00:21 2010 +0200
@@ -0,0 +1,148 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * gsm0610_preprocess.c - GSM 06.10 full rate speech codec.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2006 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * This code is based on the widely used GSM 06.10 code available from
+ * http://kbs.cs.tu-berlin.de/~jutta/toast.html
+ *
+ * $Id: gsm0610_preprocess.c,v 1.7 2006/11/19 14:07:24 steveu Exp $
+ */
+
+/*! \file */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <stdlib.h>
+
+#include "spandsp/telephony.h"
+#include "spandsp/dc_restore.h"
+#include "spandsp/gsm0610.h"
+
+#include "gsm0610_local.h"
+
+/*
+    4.2.0 .. 4.2.3  PREPROCESSING SECTION
+    
+    After A-law to linear conversion (or directly from the
+    A to D converter) the following scaling is assumed for
+    input to the RPE-LTP algorithm:
+  
+    in:  0.1.....................12
+         S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
+  
+    Where S is the sign bit, v a valid bit, and * a "don't care" bit.
+    The original signal is called sop[..]
+  
+    out:   0.1................... 12 
+         S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
+*/
+
+void gsm0610_preprocess(gsm0610_state_t *s, const int16_t amp[GSM0610_FRAME_LEN], int16_t so[GSM0610_FRAME_LEN])
+{
+    int16_t z1;
+    int16_t mp;
+    int16_t s1;
+    int16_t msp;
+    int16_t SO;
+    int32_t L_z2;
+    int32_t L_s2;
+    int32_t L_temp;
+#if !defined(__GNUC__)
+    int16_t lsp;
+#endif
+    int k;
+
+    z1 = s->z1;
+    L_z2 = s->L_z2;
+    mp = s->mp;
+    for (k = 0;  k < GSM0610_FRAME_LEN;  k++)
+    {
+        /* 4.2.1   Downscaling of the input signal */
+        SO = (amp[k] >> 1) & ~3;
+
+        assert(SO >= -0x4000); // downscaled by
+        assert(SO <=  0x3FFC); // previous routine.
+
+        /* 4.2.2   Offset compensation */
+
+        /*  This part implements a high-pass filter and requires extended
+            arithmetic precision for the recursive part of this filter.
+            The input of this procedure is the array so[0...159] and the
+            output the array sof[ 0...159 ].
+        */
+        /* Compute the non-recursive part */
+        s1 = SO - z1;
+        z1 = SO;
+
+        assert(s1 != INT16_MIN);
+
+        /* Compute the recursive part */
+        L_s2 = s1;
+        L_s2 <<= 15;
+
+        /* Perform a 31 by 16 bits multiplication */
+#if defined(__GNUC__)
+        L_z2 = ((int64_t) L_z2*32735 + 0x4000) >> 15;
+        /* Alternate (ANSI) version of below line does slightly different rounding:
+         * L_temp = L_z2 >> 9;
+         * L_temp += L_temp >> 5;
+         * L_temp = (++L_temp) >> 1;
+         * L_z2 = L_z2 - L_temp;
+         */
+        L_z2 = gsm_l_add(L_z2, L_s2);
+#else
+        /* This does L_z2  = L_z2 * 0x7FD5/0x8000 + L_s2 */
+        msp = (int16_t) (L_z2 >> 15);
+        lsp = (int16_t) (L_z2 - ((int32_t) msp << 15));
+
+        L_s2 += gsm_mult_r(lsp, 32735);
+        L_temp = (int32_t) msp*32735;
+        L_z2 = gsm_l_add(L_temp, L_s2);
+#endif
+
+        /* Compute sof[k] with rounding */
+        L_temp = gsm_l_add(L_z2, 16384);
+
+        /* 4.2.3  Preemphasis */
+        msp = gsm_mult_r(mp, -28180);
+        mp = (int16_t) (L_temp >> 15);
+        so[k] = gsm_add(mp, msp);
+    }
+    /*endfor*/
+
+    s->z1 = z1;
+    s->L_z2 = L_z2;
+    s->mp = mp;
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.