first commit
This commit is contained in:
Vendored
+127
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#include "codec_gsm.h"
|
||||
#include "iaxclient_lib.h"
|
||||
#include "gsm.h"
|
||||
|
||||
struct state {
|
||||
gsm gsmstate;
|
||||
plc_state_t plc;
|
||||
};
|
||||
|
||||
|
||||
static void destroy ( struct iaxc_audio_codec *c) {
|
||||
|
||||
struct state * encstate = (struct state *) c->encstate;
|
||||
struct state * decstate = (struct state *) c->decstate;
|
||||
|
||||
gsm_destroy(encstate->gsmstate);
|
||||
gsm_destroy(decstate->gsmstate);
|
||||
free(c->encstate);
|
||||
free(c->decstate);
|
||||
free(c);
|
||||
}
|
||||
|
||||
|
||||
static int decode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, unsigned char *in, int *outlen, short *out ) {
|
||||
struct state * decstate = (struct state *) c->decstate;
|
||||
|
||||
/* use generic interpolation */
|
||||
if(*inlen == 0) {
|
||||
int interp_len = 160;
|
||||
if(*outlen < interp_len) interp_len = *outlen;
|
||||
plc_fillin(&decstate->plc,out,interp_len);
|
||||
*outlen -= interp_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* need to decode minimum of 33 bytes to 160 byte output */
|
||||
while( (*inlen >= 33) && (*outlen >= 160) ) {
|
||||
if(gsm_decode(decstate->gsmstate, in, out))
|
||||
{
|
||||
fprintf(stderr, "codec_gsm: gsm_decode returned error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* push decoded data to interpolation buffer */
|
||||
plc_rx(&decstate->plc,out,160);
|
||||
|
||||
/* we used 33 bytes of input, and 160 bytes of output */
|
||||
*inlen -= 33;
|
||||
in += 33;
|
||||
*outlen -= 160;
|
||||
out += 160;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, short *in, int *outlen, unsigned char *out ) {
|
||||
|
||||
struct state * encstate = (struct state *) c->encstate;
|
||||
|
||||
|
||||
/* need to encode minimum of 160 bytes to 33 byte output */
|
||||
while( (*inlen >= 160) && (*outlen >= 33) ) {
|
||||
gsm_encode(encstate->gsmstate, in, out);
|
||||
|
||||
/* we used 160 bytes of input, and 33 bytes of output */
|
||||
*inlen -= 160;
|
||||
in += 160;
|
||||
*outlen -= 33;
|
||||
out += 33;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_gsm_new() {
|
||||
|
||||
struct state * encstate;
|
||||
struct state * decstate;
|
||||
struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
|
||||
|
||||
|
||||
if(!c) return c;
|
||||
|
||||
strcpy(c->name,"gsm 06.10");
|
||||
c->format = IAXC_FORMAT_GSM;
|
||||
c->encode = encode;
|
||||
c->decode = decode;
|
||||
c->destroy = destroy;
|
||||
|
||||
c->minimum_frame_size = 160;
|
||||
|
||||
c->encstate = calloc(sizeof(struct state),1);
|
||||
c->decstate = calloc(sizeof(struct state),1);
|
||||
|
||||
/* leaks a bit on no-memory */
|
||||
if(!(c->encstate && c->decstate))
|
||||
return NULL;
|
||||
|
||||
encstate = (struct state *) c->encstate;
|
||||
decstate = (struct state *) c->decstate;
|
||||
|
||||
encstate->gsmstate = gsm_create();
|
||||
decstate->gsmstate = gsm_create();
|
||||
|
||||
if(!(encstate->gsmstate && decstate->gsmstate))
|
||||
return NULL;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user