libspandsp 0.0.4
|
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.10 2008/04/17 14:26:56 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 static __inline__ int16_t gsm_add(int16_t a, int16_t b) 00039 { 00040 #if defined(__GNUC__) && defined(__i386__) 00041 __asm__ __volatile__( 00042 " addw %2,%0;\n" 00043 " jno 0f;\n" 00044 " movw $0x7fff,%0;\n" 00045 " adcw $0,%0;\n" 00046 "0:" 00047 : "=r" (a) 00048 : "0" (a), "ir" (b) 00049 : "cc" 00050 ); 00051 return a; 00052 #else 00053 int32_t sum; 00054 00055 sum = (int32_t) a + (int32_t) b; 00056 return saturate(sum); 00057 #endif 00058 } 00059 /*- End of function --------------------------------------------------------*/ 00060 00061 static __inline__ int32_t gsm_l_add(int32_t a, int32_t b) 00062 { 00063 #if defined(__i386__) 00064 __asm__ __volatile__( 00065 " addl %2,%0;\n" 00066 " jno 0f;\n" 00067 " movl $0x7fffffff,%0;\n" 00068 " adcl $0,%0;\n" 00069 "0:" 00070 : "=r" (a) 00071 : "0" (a), "ir" (b) 00072 : "cc" 00073 ); 00074 return a; 00075 #else 00076 uint32_t A; 00077 00078 if (a < 0) 00079 { 00080 if (b >= 0) 00081 return a + b; 00082 /*endif*/ 00083 A = (uint32_t) -(a + 1) + (uint32_t) -(b + 1); 00084 return (A >= INT32_MAX) ? INT32_MIN : -(int32_t) A - 2; 00085 } 00086 /*endif*/ 00087 if (b <= 0) 00088 return a + b; 00089 /*endif*/ 00090 A = (uint32_t) a + (uint32_t) b; 00091 return (A > INT32_MAX) ? INT32_MAX : A; 00092 #endif 00093 } 00094 /*- End of function --------------------------------------------------------*/ 00095 00096 static __inline__ int16_t gsm_sub(int16_t a, int16_t b) 00097 { 00098 int32_t diff; 00099 00100 diff = (int32_t) a - (int32_t) b; 00101 return saturate(diff); 00102 } 00103 /*- End of function --------------------------------------------------------*/ 00104 00105 static __inline__ int16_t gsm_mult(int16_t a, int16_t b) 00106 { 00107 if (a == INT16_MIN && b == INT16_MIN) 00108 return INT16_MAX; 00109 /*endif*/ 00110 return (int16_t) (((int32_t) a * (int32_t) b) >> 15); 00111 } 00112 /*- End of function --------------------------------------------------------*/ 00113 00114 static __inline__ int32_t gsm_l_mult(int16_t a, int16_t b) 00115 { 00116 assert (a != INT16_MIN || b != INT16_MIN); 00117 return ((int32_t) a * (int32_t) b) << 1; 00118 } 00119 /*- End of function --------------------------------------------------------*/ 00120 00121 static __inline__ int16_t gsm_mult_r(int16_t a, int16_t b) 00122 { 00123 int32_t prod; 00124 00125 if (b == INT16_MIN && a == INT16_MIN) 00126 return INT16_MAX; 00127 /*endif*/ 00128 prod = (int32_t) a * (int32_t) b + 16384; 00129 prod >>= 15; 00130 return (int16_t) (prod & 0xFFFF); 00131 } 00132 /*- End of function --------------------------------------------------------*/ 00133 00134 static __inline__ int16_t gsm_abs(int16_t a) 00135 { 00136 return (a == INT16_MIN) ? INT16_MAX : (int16_t) abs(a); 00137 } 00138 /*- End of function --------------------------------------------------------*/ 00139 00140 static __inline__ int16_t gsm_asr(int16_t a, int n) 00141 { 00142 if (n >= 16) 00143 return (int16_t) (-(a < 0)); 00144 /*endif*/ 00145 if (n <= -16) 00146 return 0; 00147 /*endif*/ 00148 if (n < 0) 00149 return (int16_t) (a << -n); 00150 /*endif*/ 00151 return (int16_t) (a >> n); 00152 } 00153 /*- End of function --------------------------------------------------------*/ 00154 00155 static __inline__ int16_t gsm_asl(int16_t a, int n) 00156 { 00157 if (n >= 16) 00158 return 0; 00159 /*endif*/ 00160 if (n <= -16) 00161 return (int16_t) (-(a < 0)); 00162 /*endif*/ 00163 if (n < 0) 00164 return gsm_asr(a, -n); 00165 /*endif*/ 00166 return (int16_t) (a << n); 00167 } 00168 /*- End of function --------------------------------------------------------*/ 00169 00170 extern void gsm0610_long_term_predictor(gsm0610_state_t *s, 00171 int16_t d[40], 00172 int16_t *dp, /* [-120..-1] d' IN */ 00173 int16_t e[40], 00174 int16_t dpp[40], 00175 int16_t *Nc, 00176 int16_t *bc); 00177 00178 extern void gsm0610_lpc_analysis(gsm0610_state_t *s, 00179 int16_t amp[160], 00180 int16_t LARc[8]); 00181 00182 extern void gsm0610_preprocess(gsm0610_state_t *s, 00183 const int16_t amp[], 00184 int16_t so[]); 00185 00186 extern void gsm0610_short_term_analysis_filter(gsm0610_state_t *s, 00187 int16_t LARc[8], 00188 int16_t amp[160]); 00189 00190 extern void gsm0610_long_term_synthesis_filtering(gsm0610_state_t *s, 00191 int16_t Ncr, 00192 int16_t bcr, 00193 int16_t erp[40], 00194 int16_t *drp); /* [-120..-1] IN, [0..40] OUT */ 00195 00196 extern void gsm0610_rpe_decoding(gsm0610_state_t *s, 00197 int16_t xmaxcr, 00198 int16_t Mcr, 00199 int16_t *xMcr, /* [0..12], 3 bits IN */ 00200 int16_t erp[40]); 00201 00202 extern void gsm0610_rpe_encoding(gsm0610_state_t *s, 00203 int16_t *e, /* [-5..-1][0..39][40..44] IN/OUT */ 00204 int16_t *xmaxc, 00205 int16_t *Mc, 00206 int16_t xMc[13]); 00207 00208 extern void gsm0610_short_term_synthesis_filter(gsm0610_state_t *s, 00209 int16_t LARcr[8], 00210 int16_t drp[40], 00211 int16_t amp[160]); 00212 00213 extern int16_t gsm0610_norm(int32_t a); 00214 00215 #if defined(__GNUC__) && defined(__i386__) 00216 00217 void gsm0610_vec_vsraw(const int16_t *p, int n, int bits); 00218 00219 int32_t gsm0610_vec_iprod(const int16_t *p, const int16_t *q, int n); 00220 00221 int32_t gsm0610_vec_maxmin(const int16_t *p, int n, int16_t *out); 00222 00223 int32_t gsm0610_max_cross_corr(const int16_t *wt, const int16_t *dp, int16_t *Nc_out); 00224 00225 #endif 00226 00227 #endif 00228 00229 /*- End of include ---------------------------------------------------------*/