codec_gsm.c

00001 /*
00002  * iaxclient: a cross-platform IAX softphone library
00003  *
00004  * Copyrights:
00005  * Copyright (C) 2003-2006, Horizon Wimba, Inc.
00006  * Copyright (C) 2007, Wimba, Inc.
00007  *
00008  * Contributors:
00009  * Steve Kann <stevek@stevek.com>
00010  *
00011  * This program is free software, distributed under the terms of
00012  * the GNU Lesser (Library) General Public License.
00013  */
00014 
00015 #include "codec_gsm.h"
00016 #include "iaxclient_lib.h"
00017 #include "gsm.h"
00018 
00019 struct state {
00020     gsm gsmstate;
00021     plc_state_t plc;
00022 };
00023 
00024 
00025 static void destroy ( struct iaxc_audio_codec *c) {
00026 
00027     struct state * encstate = (struct state *) c->encstate;
00028     struct state * decstate = (struct state *) c->decstate;
00029 
00030     gsm_destroy(encstate->gsmstate);
00031     gsm_destroy(decstate->gsmstate);
00032     free(c->encstate);
00033     free(c->decstate);
00034     free(c);
00035 }
00036 
00037 
00038 static int decode ( struct iaxc_audio_codec *c,
00039     int *inlen, unsigned char *in, int *outlen, short *out ) {
00040     struct state * decstate = (struct state *) c->decstate;
00041 
00042     /* use generic interpolation */
00043     if(*inlen == 0) {
00044         int interp_len = 160;
00045         if(*outlen < interp_len) interp_len = *outlen;
00046         plc_fillin(&decstate->plc,out,interp_len);
00047         *outlen -= interp_len;
00048         return 0;
00049     }
00050 
00051     /* need to decode minimum of 33 bytes to 160 byte output */
00052     while( (*inlen >= 33) && (*outlen >= 160) ) {
00053         if(gsm_decode(decstate->gsmstate, in, out))
00054         {
00055             fprintf(stderr, "codec_gsm: gsm_decode returned error\n");
00056             return -1;
00057         }
00058 
00059         /* push decoded data to interpolation buffer */
00060         plc_rx(&decstate->plc,out,160);
00061 
00062         /* we used 33 bytes of input, and 160 bytes of output */
00063         *inlen -= 33;
00064         in += 33;
00065         *outlen -= 160;
00066         out += 160;
00067     }
00068 
00069     return 0;
00070 }
00071 
00072 static int encode ( struct iaxc_audio_codec *c,
00073     int *inlen, short *in, int *outlen, unsigned char *out ) {
00074 
00075     struct state * encstate = (struct state *) c->encstate;
00076 
00077 
00078     /* need to encode minimum of 160 bytes to 33 byte output */
00079     while( (*inlen >= 160) && (*outlen >= 33) ) {
00080         gsm_encode(encstate->gsmstate, in, out);
00081 
00082         /* we used 160 bytes of input, and 33 bytes of output */
00083         *inlen -= 160;
00084         in += 160;
00085         *outlen -= 33;
00086         out += 33;
00087     }
00088 
00089     return 0;
00090 }
00091 
00092 struct iaxc_audio_codec *codec_audio_gsm_new() {
00093 
00094   struct state * encstate;
00095   struct state * decstate;
00096   struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
00097 
00098 
00099   if(!c) return c;
00100 
00101   strcpy(c->name,"gsm 06.10");
00102   c->format = IAXC_FORMAT_GSM;
00103   c->encode = encode;
00104   c->decode = decode;
00105   c->destroy = destroy;
00106 
00107   c->minimum_frame_size = 160;
00108 
00109   c->encstate = calloc(sizeof(struct state),1);
00110   c->decstate = calloc(sizeof(struct state),1);
00111 
00112   /* leaks a bit on no-memory */
00113   if(!(c->encstate && c->decstate))
00114       return NULL;
00115 
00116   encstate = (struct state *) c->encstate;
00117   decstate = (struct state *) c->decstate;
00118 
00119   encstate->gsmstate = gsm_create();
00120   decstate->gsmstate = gsm_create();
00121 
00122   if(!(encstate->gsmstate && decstate->gsmstate))
00123       return NULL;
00124 
00125   return c;
00126 }
00127 

Generated on Mon Sep 24 15:43:29 2007 for IAXClient by  doxygen 1.5.3