spandsp 0.0.6
|
00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * gsm0610_local.h - GSM 06.10 full rate speech codec. 00005 * 00006 * Written by Steve Underwood <steveu@coppice.org> 00007 * 00008 * Copyright (C) 2006 Steve Underwood 00009 * 00010 * All rights reserved. 00011 * 00012 * This program is free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU Lesser General Public License version 2.1, 00014 * as published by the Free Software Foundation. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00024 * 00025 * This code is based on the widely used GSM 06.10 code available from 00026 * http://kbs.cs.tu-berlin.de/~jutta/toast.html 00027 * 00028 * $Id: gsm0610_local.h,v 1.15 2009/03/13 15:57:29 steveu Exp $ 00029 */ 00030 00031 #if !defined(_GSM0610_LOCAL_H_) 00032 #define _GSM0610_LOCAL_H_ 00033 00034 #define GSM0610_FRAME_LEN 160 00035 00036 #define GSM0610_MAGIC 0xD 00037 00038 #include "spandsp/private/gsm0610.h" 00039 00040 static __inline__ int16_t gsm_add(int16_t a, int16_t b) 00041 { 00042 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) 00043 __asm__ __volatile__( 00044 " addw %2,%0;\n" 00045 " jno 0f;\n" 00046 " movw $0x7fff,%0;\n" 00047 " adcw $0,%0;\n" 00048 "0:" 00049 : "=&r" (a) 00050 : "0" (a), "ir" (b) 00051 : "cc" 00052 ); 00053 return a; 00054 #else 00055 int32_t sum; 00056 00057 sum = (int32_t) a + (int32_t) b; 00058 return saturate(sum); 00059 #endif 00060 } 00061 /*- End of function --------------------------------------------------------*/ 00062 00063 static __inline__ int32_t gsm_l_add(int32_t a, int32_t b) 00064 { 00065 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) 00066 __asm__ __volatile__( 00067 " addl %2,%0;\n" 00068 " jno 0f;\n" 00069 " movl $0x7fffffff,%0;\n" 00070 " adcl $0,%0;\n" 00071 "0:" 00072 : "=&r" (a) 00073 : "0" (a), "ir" (b) 00074 : "cc" 00075 ); 00076 return a; 00077 #else 00078 uint32_t A; 00079 00080 if (a < 0) 00081 { 00082 if (b >= 0) 00083 return a + b; 00084 /*endif*/ 00085 A = (uint32_t) -(a + 1) + (uint32_t) -(b + 1); 00086 return (A >= INT32_MAX) ? INT32_MIN : -(int32_t) A - 2; 00087 } 00088 /*endif*/ 00089 if (b <= 0) 00090 return a + b; 00091 /*endif*/ 00092 A = (uint32_t) a + (uint32_t) b; 00093 return (A > INT32_MAX) ? INT32_MAX : A; 00094 #endif 00095 } 00096 /*- End of function --------------------------------------------------------*/ 00097 00098 static __inline__ int16_t gsm_sub(int16_t a, int16_t b) 00099 { 00100 int32_t diff; 00101 00102 diff = (int32_t) a - (int32_t) b; 00103 return saturate(diff); 00104 } 00105 /*- End of function --------------------------------------------------------*/ 00106 00107 static __inline__ int16_t gsm_mult(int16_t a, int16_t b) 00108 { 00109 if (a == INT16_MIN && b == INT16_MIN) 00110 return INT16_MAX; 00111 /*endif*/ 00112 return (int16_t) (((int32_t) a * (int32_t) b) >> 15); 00113 } 00114 /*- End of function --------------------------------------------------------*/ 00115 00116 static __inline__ int32_t gsm_l_mult(int16_t a, int16_t b) 00117 { 00118 assert (a != INT16_MIN || b != INT16_MIN); 00119 return ((int32_t) a * (int32_t) b) << 1; 00120 } 00121 /*- End of function --------------------------------------------------------*/ 00122 00123 static __inline__ int16_t gsm_mult_r(int16_t a, int16_t b) 00124 { 00125 int32_t prod; 00126 00127 if (b == INT16_MIN && a == INT16_MIN) 00128 return INT16_MAX; 00129 /*endif*/ 00130 prod = (int32_t) a * (int32_t) b + 16384; 00131 prod >>= 15; 00132 return (int16_t) (prod & 0xFFFF); 00133 } 00134 /*- End of function --------------------------------------------------------*/ 00135 00136 static __inline__ int16_t gsm_abs(int16_t a) 00137 { 00138 return (a == INT16_MIN) ? INT16_MAX : (int16_t) abs(a); 00139 } 00140 /*- End of function --------------------------------------------------------*/ 00141 00142 static __inline__ int16_t gsm_asr(int16_t a, int n) 00143 { 00144 if (n >= 16) 00145 return (int16_t) (-(a < 0)); 00146 /*endif*/ 00147 if (n <= -16) 00148 return 0; 00149 /*endif*/ 00150 if (n < 0) 00151 return (int16_t) (a << -n); 00152 /*endif*/ 00153 return (int16_t) (a >> n); 00154 } 00155 /*- End of function --------------------------------------------------------*/ 00156 00157 static __inline__ int16_t gsm_asl(int16_t a, int n) 00158 { 00159 if (n >= 16) 00160 return 0; 00161 /*endif*/ 00162 if (n <= -16) 00163 return (int16_t) (-(a < 0)); 00164 /*endif*/ 00165 if (n < 0) 00166 return gsm_asr(a, -n); 00167 /*endif*/ 00168 return (int16_t) (a << n); 00169 } 00170 /*- End of function --------------------------------------------------------*/ 00171 00172 extern void gsm0610_long_term_predictor(gsm0610_state_t *s, 00173 int16_t d[40], 00174 int16_t *dp, /* [-120..-1] d' IN */ 00175 int16_t e[40], 00176 int16_t dpp[40], 00177 int16_t *Nc, 00178 int16_t *bc); 00179 00180 extern void gsm0610_lpc_analysis(gsm0610_state_t *s, 00181 int16_t amp[160], 00182 int16_t LARc[8]); 00183 00184 extern void gsm0610_preprocess(gsm0610_state_t *s, 00185 const int16_t amp[], 00186 int16_t so[]); 00187 00188 extern void gsm0610_short_term_analysis_filter(gsm0610_state_t *s, 00189 int16_t LARc[8], 00190 int16_t amp[160]); 00191 00192 extern void gsm0610_long_term_synthesis_filtering(gsm0610_state_t *s, 00193 int16_t Ncr, 00194 int16_t bcr, 00195 int16_t erp[40], 00196 int16_t *drp); /* [-120..-1] IN, [0..40] OUT */ 00197 00198 extern void gsm0610_rpe_decoding(gsm0610_state_t *s, 00199 int16_t xmaxcr, 00200 int16_t Mcr, 00201 int16_t *xMcr, /* [0..12], 3 bits IN */ 00202 int16_t erp[40]); 00203 00204 extern void gsm0610_rpe_encoding(gsm0610_state_t *s, 00205 int16_t *e, /* [-5..-1][0..39][40..44] IN/OUT */ 00206 int16_t *xmaxc, 00207 int16_t *Mc, 00208 int16_t xMc[13]); 00209 00210 extern void gsm0610_short_term_synthesis_filter(gsm0610_state_t *s, 00211 int16_t LARcr[8], 00212 int16_t drp[40], 00213 int16_t amp[160]); 00214 00215 extern int16_t gsm0610_norm(int32_t a); 00216 00217 #endif 00218 00219 /*- End of include ---------------------------------------------------------*/