00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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
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
00060 plc_rx(&decstate->plc,out,160);
00061
00062
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
00079 while( (*inlen >= 160) && (*outlen >= 33) ) {
00080 gsm_encode(encstate->gsmstate, in, out);
00081
00082
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
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