00001 /**********************************************************/ 00002 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00003 /* 00004 Copyright: 1994 - Grupo de Voz (DAET) ETSII/IT-Bilbao 00005 00006 Nombre fuente................ lpc10_c1.c 00007 Nombre paquete............... LPC10E 00008 Lenguaje fuente.............. C 00009 Estado....................... Completado 00010 Dependencia Hard/OS.......... - 00011 Codigo condicional........... - 00012 00013 Codificacion................. Borja Etxebarria 00014 00015 Version dd/mm/aa Autor Proposito de la edicion 00016 ------- -------- -------- ----------------------- 00017 0.0.0 10/03/97 Borja codificacion inicial 00018 00019 ======================== Contenido ======================== 00020 codificador LPC10E a 2400bps. Basado en unos fuentes de 00021 dominio publico. Esta es la documentacion para los 00022 objetos definidos en lpc10_c1.c, lpc10_d1.c, lpc10_c2.c 00023 y lpc10_d2.c. Los prototipos y definiciones necesarias 00024 para utilizar todo esto estan en lpc10.h. 00025 00026 NOTA IMPORTANTE: por ahora SOLO se soporta un unico objeto de 00027 cada tipo (un solo CLPC10_2400, etc). 00028 00029 2 modos de funcionamiento: como bitstream o como datagrama. 00030 El bitstream simula un flujo de bits, orientado a simular 00031 el funcionamiento del sistema. Cada trama es un array 00032 de 54 enteros, cada entero representa un bit. Se utiliza 00033 el tipo LPC10_2400_idata para representar una trama. 00034 00035 El datagrama esta mas empaquetadito, orientado a un uso 00036 practico del codec. Cada trama utiliza 7 bytes en los 00037 que se empaquetan todos los bits codificados. Se utiliza 00038 el tipo LPC10_dgram_data para representar una trama. 00039 Ademas se ha eliminado parte de la codificacion de canal 00040 (codigos de proteccion hamming, etc), en vistas a la 00041 utilizacion como datagrama: o todo o nada. 00042 00043 Los tipos de objetos son: 00044 00045 CLPC10_2400 : codificador bitstream 00046 DLPC10_2400 : decodificador bitstream 00047 CLPC10_DGRAM : codificador datagrama 00048 DLPC10_DGRAM : decodificador datagrama 00049 PTHL10 : implementa un metodo de calculo de pitch en base a 00050 este codec. 00051 00052 Cada tipo tiene su constructor y destructor (ej. para CLPC10_2400, 00053 clpc10_2400_construct() y clpc10_2400_destruct()). 00054 00055 Ademas tienen un metodo ???_reset() para reinicializar el sistema 00056 (estado "home", memorias reinicializadas a cero). 00057 00058 Para codificar con el codec bitstream se utiliza clpc10_2400_icode() 00059 o tambien clpc10_2400_icode_i16(). La primera recibe las muestras 00060 de audio como floats entre -1 y 1. La segunda utiliza muestras PCM 00061 de 16 bits. Ambas {devuelven} un puntero a una trama LP10_2400_idata 00062 (internamente almacenada). 00063 00064 Para decodificar un bitstream se utiliza dlpc10_2400_idecode() o 00065 tambien dlpc10_2400_idecode_i16(), la primera decodifica las muestras 00066 en formato float entre -1 y 1, y la segunda como muestras de 16 bits. 00067 Ambas reciben una trama LPC10_2400_idata y {devuelven} el numero N 00068 de muestras que se generan. IMPORTANTE: aunque LPC10_LFRAME muestras 00069 de entrada se codifican en una trama LPC10_2400_idata, no sucede 00070 lo contrario: una trama codificada no se decodifica/expande en 00071 LPC10_LFRAME (a veces mas, a veces menos, aunque la media 00072 si que es LPC10_LFRAME), por eso estas funciones {devuelven} el 00073 numero N de muestras que se han obtenido. Para obtener el vector 00074 de audio decodificado, inmediatamente despues de llamar a 00075 dlpc10_2400_idecode() (o dlpc10_2400_idecode_i16()) llamaremos 00076 a dlpc10_2400_outvec() (o dlpc10_2400_outvec_i16()), que 00077 {devuelven} un puntero a un buffer interno que contiene las N 00078 muestras generadas en la ultima llamada a idecode. El numero 00079 N de muestras devueltas esta entre 0 y LPC10_DOUTMAX. 00080 00081 Con el codificador de datagramas, similar al de bitstream pero 00082 con tramas codificadas de tipo LPC10_dgram_data. Para codificar 00083 se utiliza clpc10_dgram_code() o clpc10_dgram_code_i16() y 00084 para decodificar dlpc10_dgram_decode() o dlpc10_dgram_decode_i16(), 00085 con dlpc10_dgram_outvec() o dlpc10_dgram_outvec_i16() para obtener 00086 el correspondiente vector. 00087 00088 El codificador de bitstream genera tramas LPC10_2400_idata, 00089 compuestas por 54 enteros, cada uno representando un bit 00090 de informacion transmitida. Tambien se puede compactar 00091 para almacenar dicha informacion (aunque para eso es mejor 00092 utilizar el modelo orientado a datagrama) utilizando 00093 la funcion clpc10_2400_pack(), que recibe una trama 00094 codificada LPC10_2400_idata y rellena una trama codificada 00095 compactada LPC10_2400_data. La funcion dlpc10_2400_unpack() se utiliza 00096 para hacer el proceso contrario (expansion de la trama codificada 00097 compactada a trama codificada LPC10_2400_idata). 00098 00099 En cuanto al tipo PTHL10, tambien tiene un constructor, 00100 destructor y reset que funcionan como en los anteriores. 00101 Ademas tiene la funcion pthl10_get_i16() que para cada 00102 trama de LPC10_LFRAME muestras de tipo PCM16, {devuelve} 00103 el valor de pitch calculado utilizando los algoritmos del 00104 codec LPC10e. Hay que tener en cuenta el retardo: el valor 00105 devuelto no corresponde a la trama recien enviada, sino a 00106 una trama anterior, con un retardo de ??? tramas. 00107 00108 CODEC DE BAJO NIVEL: 00109 Se proporcionan estas funciones para utilizar el codec como 00110 un algoritmo de analisis de senyal, y obtener todos los 00111 parametros: pitch, energia, voice/unvoice, rcs. Es una 00112 generalizacion de PTHL10. Estas son las funciones: 00113 parametros del codec 00114 00115 - c_lpc10_ini() para inicializar el codificador. 00116 - d_lpc10_ini() para inicializar el decodificador. 00117 - c_lpc10_code() para codificar trama de audio (FLOAT*) 00118 - c_lpc10_code_i16() para codificar trama de audio (PCM16*) 00119 - c_lpc10_peek() para obtener los parametros de la codificacion, 00120 que son voice[2], pitch, rms, rc[10]. Atencion que hay un 00121 retardo de tres tramas (es decir, se obtienen los parametros de 00122 la trama de audio que se envio hace tres tramas). 00123 - d_lpc10_decode() para recuperar audio a partir de los parametros 00124 que c_lpc10_peek() genera. No se genera una trama completa (180 00125 muestras) sino cualquier valor entre 0 y LPC10_DOUTMAX. La funcion 00126 {devuelve} el numero N de muestras generado. Atencion que hay 00127 un retraso de una trama (LPC10_LFRAME muestras = 180 muestras). 00128 =========================================================== 00129 */ 00130 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00131 /**********************************************************/ 00132 00133 #include <stdio.h> 00134 #include <stdlib.h> 00135 00136 #include "lpc10.h" 00137 #include "c_lpc10.h" 00138 #include "sr_lpc10.h" 00139 00140 /**********************************************************/ 00141 00142 BOOL g_used_c_2400 = FALSE; 00143 INDEX g_ibits[54]; 00144 00145 /**********************************************************/ 00146 00147 CLPC10_2400 *clpc10_2400_construct( VOID ) 00148 { 00149 if (g_used_c_2400) { 00150 fprintf(stderr,"\nPor ahora no soporto mas de una estructura CLPC10_2400!\7\n"); 00151 exit(1); 00152 } 00153 00154 g_used_c_2400 = TRUE; 00155 00156 clpc10_2400_reset((CLPC10_2400*)1); 00157 return (CLPC10_2400*)1; 00158 } 00159 00160 /**********************************************************/ 00161 00162 VOID clpc10_2400_destruct( CLPC10_2400 *c ) 00163 { 00164 (void)c; /* avoid "unused parameter" warning */ 00165 g_used_c_2400 = FALSE; 00166 } 00167 00168 /**********************************************************/ 00169 00170 VOID clpc10_2400_reset( CLPC10_2400 *c ) 00171 { 00172 (void)c; /* avoid "unused parameter" warning */ 00173 coder_ini(); 00174 send_2400_ini(); 00175 } 00176 00177 /**********************************************************/ 00178 00179 LPC10_2400_idata *clpc10_2400_icode( CLPC10_2400 *c, FLOAT speech[LPC10_LFRAME] ) 00180 { 00181 (void)c; /* avoid "unused parameter" warning */ 00182 /* shift sample and other buffers */ 00183 shift(); 00184 /* prepare and copy input buffer */ 00185 framein(speech); 00186 /* analyze frame */ 00187 analys(); 00188 /* channel encode and write */ 00189 send_2400_i(CODED_VOICE, CODED_PITCH, CODED_RMS, CODED_RC, g_ibits); 00190 00191 return (LPC10_2400_idata*)g_ibits; 00192 } 00193 00194 /**********************************************************/ 00195 00196 LPC10_2400_idata *clpc10_2400_icode_i16( CLPC10_2400 *c, INT16 speech[LPC10_LFRAME] ) 00197 { 00198 (void)c; /* avoid "unused parameter" warning */ 00199 /* shift sample and other buffers */ 00200 shift(); 00201 /* prepare and copy input buffer */ 00202 framein_i16(speech); 00203 /* analyze frame */ 00204 analys(); 00205 /* channel encode and write */ 00206 send_2400_i(CODED_VOICE, CODED_PITCH, CODED_RMS, CODED_RC, g_ibits); 00207 00208 return (LPC10_2400_idata*)g_ibits; 00209 } 00210 00211 /**********************************************************/ 00212 00213 VOID clpc10_2400_pack( LPC10_2400_idata *in, LPC10_2400_data *o) 00214 { 00215 INDEX i,j,n; 00216 BYTE b; 00217 00218 for (i=0; i<7; i++) { 00219 b=0; 00220 for (j=0; j<8; j++) { 00221 n=i*8+j; 00222 if (n>=(INDEX)sizeof(LPC10_2400_idata)) break; 00223 b = ((*in)[n]?1:0) | (b<<1); 00224 } 00225 (*o)[i]=b; 00226 } 00227 } 00228 00229 /**********************************************************/