Add rate to frames and a bunch of evil resample code

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@240 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2005-12-30 00:00:21 +00:00
parent 0fbf3f5af0
commit e98104d109
17 changed files with 265 additions and 111 deletions

View File

@ -106,15 +106,19 @@ SWITCH_DECLARE(switch_status) switch_core_codec_encode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *decoded_data, void *decoded_data,
size_t decoded_data_len, size_t decoded_data_len,
int decoded_rate,
void *encoded_data, void *encoded_data,
size_t *encoded_data_len, size_t *encoded_data_len,
int *encoded_rate,
unsigned int *flag); unsigned int *flag);
SWITCH_DECLARE(switch_status) switch_core_codec_decode(switch_codec *codec, SWITCH_DECLARE(switch_status) switch_core_codec_decode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *encoded_data, void *encoded_data,
size_t encoded_data_len, size_t encoded_data_len,
int encoded_rate,
void *decoded_data, void *decoded_data,
size_t *decoded_data_len, size_t *decoded_data_len,
int *decoded_rate,
unsigned int *flag); unsigned int *flag);
SWITCH_DECLARE(switch_status) switch_core_codec_destroy(switch_codec *codec); SWITCH_DECLARE(switch_status) switch_core_codec_destroy(switch_codec *codec);
SWITCH_DECLARE(switch_status) switch_core_session_set_read_codec(switch_core_session *session, switch_codec *codec); SWITCH_DECLARE(switch_status) switch_core_session_set_read_codec(switch_core_session *session, switch_codec *codec);

View File

@ -44,6 +44,7 @@ struct switch_frame {
size_t datalen; size_t datalen;
size_t buflen; size_t buflen;
int samples; int samples;
int rate;
}; };
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -228,15 +228,19 @@ struct switch_codec_implementation {
switch_codec *other_codec, switch_codec *other_codec,
void *decoded_data, void *decoded_data,
size_t decoded_data_len, size_t decoded_data_len,
int decoded_rate,
void *encoded_data, void *encoded_data,
size_t *encoded_data_len, size_t *encoded_data_len,
int *encoded_rate,
unsigned int *flag); unsigned int *flag);
switch_status (*decode)(switch_codec *codec, switch_status (*decode)(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *encoded_data, void *encoded_data,
size_t encoded_data_len, size_t encoded_data_len,
int encoded_rate,
void *decoded_data, void *decoded_data,
size_t *decoded_data_len, size_t *decoded_data_len,
int *decoded_rate,
unsigned int *flag); unsigned int *flag);
switch_status (*destroy)(switch_codec *); switch_status (*destroy)(switch_codec *);
const struct switch_codec_implementation *next; const struct switch_codec_implementation *next;

View File

@ -55,6 +55,7 @@ typedef enum {
SWITCH_STATUS_NOTIMPL, SWITCH_STATUS_NOTIMPL,
SWITCH_STATUS_MEMERR, SWITCH_STATUS_MEMERR,
SWITCH_STATUS_NOOP, SWITCH_STATUS_NOOP,
SWITCH_STATUS_RESAMPLE,
SWITCH_STATUS_GENERR, SWITCH_STATUS_GENERR,
SWITCH_STATUS_INUSE SWITCH_STATUS_INUSE
} switch_status; } switch_status;

View File

@ -70,10 +70,10 @@ SWITCH_DECLARE(switch_status) switch_socket_create_pollfd(switch_pollfd_t *poll,
SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms); SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms);
SWITCH_DECLARE(void) switch_swap_linear(int16_t *buf, int len); SWITCH_DECLARE(void) switch_swap_linear(int16_t *buf, int len);
SWITCH_DECLARE(char *) switch_cut_path(char *in); SWITCH_DECLARE(char *) switch_cut_path(char *in);
SWITCH_DECLARE(int) float_to_short(float *f, short *s, int len); SWITCH_DECLARE(int) switch_float_to_short(float *f, short *s, int len);
SWITCH_DECLARE(int) char_to_float(char *c, float *f, int len); SWITCH_DECLARE(int) switch_char_to_float(char *c, float *f, int len);
SWITCH_DECLARE(int) float_to_char(float *f, char *c, int len); SWITCH_DECLARE(int) switch_float_to_char(float *f, char *c, int len);
SWITCH_DECLARE(int) short_to_float(short *s, float *f, int len); SWITCH_DECLARE(int) switch_short_to_float(short *s, float *f, int len);
#if !defined(switch_strdupa) && defined(__GNUC__) #if !defined(switch_strdupa) && defined(__GNUC__)
# define switch_strdupa(s) \ # define switch_strdupa(s) \

View File

@ -79,8 +79,10 @@ static switch_status switch_gsm_encode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *decoded_data, void *decoded_data,
size_t decoded_data_len, size_t decoded_data_len,
int decoded_rate,
void *encoded_data, void *encoded_data,
size_t *encoded_data_len, size_t *encoded_data_len,
int *encoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
struct gsm_context *context = codec->private; struct gsm_context *context = codec->private;
@ -117,8 +119,10 @@ static switch_status switch_gsm_decode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *encoded_data, void *encoded_data,
size_t encoded_data_len, size_t encoded_data_len,
int encoded_rate,
void *decoded_data, void *decoded_data,
size_t *decoded_data_len, size_t *decoded_data_len,
int *decoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
struct gsm_context *context = codec->private; struct gsm_context *context = codec->private;

View File

@ -74,8 +74,10 @@ static switch_status switch_g729_encode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *decoded_data, void *decoded_data,
size_t decoded_data_len, size_t decoded_data_len,
int decoded_rate,
void *encoded_data, void *encoded_data,
size_t *encoded_data_len, size_t *encoded_data_len,
int *encoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
struct g729_context *context = codec->private; struct g729_context *context = codec->private;
@ -112,8 +114,10 @@ static switch_status switch_g729_decode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *encoded_data, void *encoded_data,
size_t encoded_data_len, size_t encoded_data_len,
int encoded_rate,
void *decoded_data, void *decoded_data,
size_t *decoded_data_len, size_t *decoded_data_len,
int *decoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
struct g729_context *context = codec->private; struct g729_context *context = codec->private;

View File

@ -911,6 +911,7 @@ static switch_status exosip_create_call(eXosip_event_t *event)
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} else { } else {
int ms; int ms;
tech_pvt->read_frame.rate = rate;
switch_set_flag(tech_pvt, TFLAG_USING_CODEC); switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000; ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000;
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Inbound Codec %s/%d %d ms\n", dname, rate, ms); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Inbound Codec %s/%d %d ms\n", dname, rate, ms);
@ -1075,6 +1076,7 @@ static void handle_answer(eXosip_event_t *event)
return; return;
} else { } else {
int ms; int ms;
tech_pvt->read_frame.rate = rate;
switch_set_flag(tech_pvt, TFLAG_USING_CODEC); switch_set_flag(tech_pvt, TFLAG_USING_CODEC);
ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000; ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000;
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Outbound Codec %s/%d %d ms\n", dname, rate, ms); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Outbound Codec %s/%d %d ms\n", dname, rate, ms);

View File

@ -55,8 +55,10 @@ static switch_status switch_g711u_encode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *decoded_data, void *decoded_data,
size_t decoded_data_len, size_t decoded_data_len,
int decoded_rate,
void *encoded_data, void *encoded_data,
size_t *encoded_data_len, size_t *encoded_data_len,
int *encoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
short *dbuf; short *dbuf;
@ -79,8 +81,10 @@ static switch_status switch_g711u_decode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *encoded_data, void *encoded_data,
size_t encoded_data_len, size_t encoded_data_len,
int encoded_rate,
void *decoded_data, void *decoded_data,
size_t *decoded_data_len, size_t *decoded_data_len,
int *decoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
short *dbuf; short *dbuf;
@ -129,8 +133,10 @@ static switch_status switch_g711a_encode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *decoded_data, void *decoded_data,
size_t decoded_data_len, size_t decoded_data_len,
int decoded_rate,
void *encoded_data, void *encoded_data,
size_t *encoded_data_len, size_t *encoded_data_len,
int *encoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
short *dbuf; short *dbuf;
@ -153,8 +159,10 @@ static switch_status switch_g711a_decode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *encoded_data, void *encoded_data,
size_t encoded_data_len, size_t encoded_data_len,
int encoded_rate,
void *decoded_data, void *decoded_data,
size_t *decoded_data_len, size_t *decoded_data_len,
int *decoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
short *dbuf; short *dbuf;

View File

@ -298,6 +298,7 @@ static switch_status iax_set_codec(struct private_object *tech_pvt, struct iax_s
int rate; int rate;
ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000; ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000;
rate = tech_pvt->write_codec.implementation->samples_per_second; rate = tech_pvt->write_codec.implementation->samples_per_second;
tech_pvt->read_frame.rate = rate;
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Codec %s/%d %d ms\n", dname, rate, ms); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Codec %s/%d %d ms\n", dname, rate, ms);
tech_pvt->read_frame.codec = &tech_pvt->read_codec; tech_pvt->read_frame.codec = &tech_pvt->read_codec;
switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec); switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);

View File

@ -103,7 +103,7 @@ void playback_function(switch_core_session *session, char *data)
switch_channel_hangup(channel); switch_channel_hangup(channel);
return; return;
} }
write_frame.rate = fh.samplerate;
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "setup timer success %d bytes per %d ms!\n", len, interval); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "setup timer success %d bytes per %d ms!\n", len, interval);
/* start a thread to absorb incoming audio */ /* start a thread to absorb incoming audio */
@ -136,7 +136,7 @@ void playback_function(switch_core_session *session, char *data)
} }
write_frame.datalen = ilen * 2; write_frame.datalen = ilen * 2;
write_frame.samples = ilen; write_frame.samples = (int)ilen;
#ifdef SWAP_LINEAR #ifdef SWAP_LINEAR
switch_swap_linear(write_frame.data, (int)write_frame.datalen / 2); switch_swap_linear(write_frame.data, (int)write_frame.datalen / 2);
#endif #endif

View File

@ -75,6 +75,7 @@ static struct {
int call_id; int call_id;
switch_hash *call_hash; switch_hash *call_hash;
switch_mutex_t *device_lock; switch_mutex_t *device_lock;
int sample_rate;
} globals; } globals;
struct private_object { struct private_object {
@ -559,6 +560,8 @@ static switch_status load_config(void)
if (!strcasecmp(cfg.category, "settings")) { if (!strcasecmp(cfg.category, "settings")) {
if (!strcmp(var, "debug")) { if (!strcmp(var, "debug")) {
globals.debug = atoi(val); globals.debug = atoi(val);
} else if (!strcmp(var, "sample_rate")) {
globals.sample_rate = atoi(val);
} else if (!strcmp(var, "dialplan")) { } else if (!strcmp(var, "dialplan")) {
set_global_dialplan(val); set_global_dialplan(val);
} else if (!strcmp(var, "cid_name")) { } else if (!strcmp(var, "cid_name")) {
@ -585,6 +588,10 @@ static switch_status load_config(void)
set_global_dialplan("default"); set_global_dialplan("default");
} }
if (!globals.sample_rate) {
globals.sample_rate = 8000;
}
switch_config_close_file(&cfg); switch_config_close_file(&cfg);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
@ -692,7 +699,7 @@ error:
static switch_status engage_device(struct private_object *tech_pvt) static switch_status engage_device(struct private_object *tech_pvt)
{ {
int sample_rate = 8000; int sample_rate = globals.sample_rate;
int codec_ms = 20; int codec_ms = 20;
switch_channel *channel; switch_channel *channel;
@ -723,7 +730,7 @@ static switch_status engage_device(struct private_object *tech_pvt)
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
} }
tech_pvt->read_frame.rate = sample_rate;
tech_pvt->read_frame.codec = &tech_pvt->read_codec; tech_pvt->read_frame.codec = &tech_pvt->read_codec;
switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec); switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec); switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);

View File

@ -42,21 +42,24 @@ static const char modname[] = "mod_rawaudio";
#define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif #endif
#define QUALITY 1
struct raw_resampler {
void *resampler;
int from;
int to;
double factor;
float *buf;
int buf_len;
int buf_size;
float *new_buf;
int new_buf_len;
int new_buf_size;
};
struct raw_context { struct raw_context {
void *enc_resampler; struct raw_resampler *enc;
int enc_from; struct raw_resampler *dec;
int enc_to;
double enc_factor;
float *enc_buf;
int enc_buf_len;
int enc_buf_size;
void *dec_resampler;
int dec_from;
int dec_to;
double dec_factor;
float *dec_buf;
int dec_buf_len;
int dec_buf_size;
}; };
@ -67,14 +70,17 @@ static int resample(void *handle, double factor, float *src, int srclen, float *
for(;;) { for(;;) {
int srcBlock = MIN(srclen-srcpos, srclen); int srcBlock = MIN(srclen-srcpos, srclen);
int lastFlag = (last && (srcBlock == srclen-srcpos)); int lastFlag = (last && (srcBlock == srclen-srcpos));
printf("resampling %d/%d (%d)\n", srcpos, srclen, MIN(dstlen-out, dstlen));
o = resample_process(handle, factor, &src[srcpos], srcBlock, lastFlag, &srcused, &dst[out], dstlen-out); o = resample_process(handle, factor, &src[srcpos], srcBlock, lastFlag, &srcused, &dst[out], dstlen-out);
//printf("resampling %d/%d (%d) %d %f\n", srcpos, srclen, MIN(dstlen-out, dstlen), srcused, factor);
srcpos += srcused; srcpos += srcused;
if (o >= 0) if (o >= 0) {
out += o; out += o;
if (o < 0 || (o == 0 && srcpos == srclen)) }
if (o < 0 || (o == 0 && srcpos == srclen)) {
break; break;
} }
}
return out; return out;
} }
@ -102,8 +108,10 @@ static switch_status switch_raw_encode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *decoded_data, void *decoded_data,
size_t decoded_data_len, size_t decoded_data_len,
int decoded_rate,
void *encoded_data, void *encoded_data,
size_t *encoded_data_len, size_t *encoded_data_len,
int *encoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
struct raw_context *context = codec->private; struct raw_context *context = codec->private;
@ -111,25 +119,51 @@ static switch_status switch_raw_encode(switch_codec *codec,
/* NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary. /* NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary.
TBD Support varying number of channels TBD Support varying number of channels
*/ */
//printf("encode %d->%d (%d)\n", other_codec->implementation->samples_per_second, codec->implementation->samples_per_second, decoded_rate);
if (other_codec && codec->implementation->samples_per_second != other_codec->implementation->samples_per_second) { if (other_codec &&
if (!context->enc_from) { codec->implementation->samples_per_second != other_codec->implementation->samples_per_second &&
printf("Activate Resample %d->%d\n", codec->implementation->samples_per_second, other_codec->implementation->samples_per_second); decoded_rate != other_codec->implementation->samples_per_second) {
context->enc_from = codec->implementation->samples_per_second; const short *ddp = decoded_data;
context->enc_to = other_codec->implementation->samples_per_second; short *edp = encoded_data;
context->enc_factor = ((double) context->enc_from / (double)context->enc_to); size_t ddplen = decoded_data_len / 2;
context->enc_resampler = resample_open(1, context->enc_factor, context->enc_factor);
context->enc_buf_size = codec->implementation->bytes_per_frame; if (!context->enc) {
context->enc_buf = (float *) switch_core_alloc(codec->memory_pool, context->enc_buf_size);
if (!(context->enc = switch_core_alloc(codec->memory_pool, sizeof(struct raw_resampler)))) {
return SWITCH_STATUS_MEMERR;
} }
if (context->enc_from) { context->enc->from = codec->implementation->samples_per_second;
context->enc->to = other_codec->implementation->samples_per_second;
context->enc->factor = ((double)context->enc->from / (double)context->enc->to);
context->enc->resampler = resample_open(QUALITY, context->enc->factor, context->enc->factor);
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Encode Resample %d->%d %f\n", other_codec->implementation->samples_per_second, codec->implementation->samples_per_second, context->enc->factor);
context->enc->buf_size = codec->implementation->bytes_per_frame * 10;
context->enc->buf = (float *) switch_core_alloc(codec->memory_pool, context->enc->buf_size);
context->enc->new_buf_size = codec->implementation->bytes_per_frame * 10;
context->enc->new_buf = (float *) switch_core_alloc(codec->memory_pool, context->enc->new_buf_size);
} }
if (context->enc) {
context->enc->buf_len = switch_short_to_float(decoded_data, context->enc->buf, (int)ddplen);
context->enc->new_buf_len = resample(context->enc->resampler,
context->enc->factor,
context->enc->buf,
context->enc->buf_len,
context->enc->new_buf,
context->enc->new_buf_size,
0);
switch_float_to_short(context->enc->new_buf, edp, decoded_data_len * 2);
*encoded_data_len = context->enc->new_buf_len * 2;
*encoded_rate = context->enc->to;
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
return SWITCH_STATUS_GENERR;
}
return SWITCH_STATUS_NOOP; return SWITCH_STATUS_NOOP;
} }
@ -137,13 +171,61 @@ static switch_status switch_raw_decode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *encoded_data, void *encoded_data,
size_t encoded_data_len, size_t encoded_data_len,
int encoded_rate,
void *decoded_data, void *decoded_data,
size_t *decoded_data_len, size_t *decoded_data_len,
int *decoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
struct raw_context *context = codec->private; struct raw_context *context = codec->private;
printf("decode %d %d->%d\n", encoded_data_len, other_codec->implementation->bytes_per_frame, codec->implementation->bytes_per_frame); //printf("decode %d->%d (%d)\n", other_codec->implementation->samples_per_second, codec->implementation->samples_per_second, encoded_rate);
if (other_codec &&
codec->implementation->samples_per_second != other_codec->implementation->samples_per_second &&
encoded_rate != other_codec->implementation->samples_per_second) {
short *ddp = decoded_data;
const short *edp = encoded_data;
size_t edplen = encoded_data_len / 2;
if (!context->dec) {
if (!(context->dec = switch_core_alloc(codec->memory_pool, sizeof(struct raw_resampler)))) {
return SWITCH_STATUS_MEMERR;
}
context->dec->from = codec->implementation->samples_per_second;
context->dec->to = other_codec->implementation->samples_per_second;
context->dec->factor = ((double)context->dec->from / (double)context->dec->to);
context->dec->resampler = resample_open(QUALITY, context->dec->factor, context->dec->factor);
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Activate Decode Resample %d->%d %f\n", other_codec->implementation->samples_per_second, codec->implementation->samples_per_second, context->dec->factor);
context->dec->buf_size = codec->implementation->bytes_per_frame * 10;
context->dec->buf = (float *) switch_core_alloc(codec->memory_pool, context->dec->buf_size);
context->dec->new_buf_size = codec->implementation->bytes_per_frame * 10;
context->dec->new_buf = (float *) switch_core_alloc(codec->memory_pool, context->dec->new_buf_size);
}
if (context->dec) {
context->dec->buf_len = switch_short_to_float(encoded_data, context->dec->buf, (int)edplen);
context->dec->new_buf_len = resample(context->dec->resampler,
context->dec->factor,
context->dec->buf,
context->dec->buf_len,
context->dec->new_buf,
context->dec->new_buf_size,
0);
switch_float_to_short(context->dec->new_buf, ddp, (int)edplen);
*decoded_data_len = context->dec->new_buf_len * 2;
*decoded_rate = context->dec->to;
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_GENERR;
}
return SWITCH_STATUS_NOOP; return SWITCH_STATUS_NOOP;
} }
@ -151,6 +233,16 @@ static switch_status switch_raw_decode(switch_codec *codec,
static switch_status switch_raw_destroy(switch_codec *codec) static switch_status switch_raw_destroy(switch_codec *codec)
{ {
struct raw_context *context = codec->private;
if (context->enc && context->enc->resampler){
resample_close(context->enc->resampler);
}
if (context->dec && context->dec->resampler){
resample_close(context->dec->resampler);
}
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }

View File

@ -157,8 +157,10 @@ static switch_status switch_speex_encode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *decoded_data, void *decoded_data,
size_t decoded_data_len, size_t decoded_data_len,
int decoded_rate,
void *encoded_data, void *encoded_data,
size_t *encoded_data_len, size_t *encoded_data_len,
int *encoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
struct speex_context *context = codec->private; struct speex_context *context = codec->private;
@ -211,8 +213,10 @@ static switch_status switch_speex_decode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *encoded_data, void *encoded_data,
size_t encoded_data_len, size_t encoded_data_len,
int encoded_rate,
void *decoded_data, void *decoded_data,
size_t *decoded_data_len, size_t *decoded_data_len,
int *decoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
struct speex_context *context = codec->private; struct speex_context *context = codec->private;

View File

@ -198,6 +198,7 @@ static switch_status woomerachan_on_init(switch_core_session *session)
{ {
switch_channel *channel; switch_channel *channel;
struct private_object *tech_pvt = NULL; struct private_object *tech_pvt = NULL;
int rate = 8000;
tech_pvt = switch_core_session_get_private(session); tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL); assert(tech_pvt != NULL);
@ -207,18 +208,18 @@ static switch_status woomerachan_on_init(switch_core_session *session)
tech_pvt->frame.data = tech_pvt->databuf; tech_pvt->frame.data = tech_pvt->databuf;
if (switch_core_codec_init(&tech_pvt->read_codec, "L16", 8000, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { if (switch_core_codec_init(&tech_pvt->read_codec, "L16", rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Cannot set read codec\n", switch_channel_get_name(channel));
switch_channel_hangup(channel); switch_channel_hangup(channel);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
if (switch_core_codec_init(&tech_pvt->write_codec, "L16", 8000, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { if (switch_core_codec_init(&tech_pvt->write_codec, "L16", rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Cannot set read codec\n", switch_channel_get_name(channel)); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s Cannot set read codec\n", switch_channel_get_name(channel));
switch_channel_hangup(channel); switch_channel_hangup(channel);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
tech_pvt->frame.rate = rate;
tech_pvt->frame.codec = &tech_pvt->read_codec; tech_pvt->frame.codec = &tech_pvt->read_codec;
switch_core_session_set_read_codec(session, &tech_pvt->read_codec); switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
switch_core_session_set_write_codec(session, &tech_pvt->write_codec); switch_core_session_set_write_codec(session, &tech_pvt->write_codec);

View File

@ -253,8 +253,10 @@ SWITCH_DECLARE(switch_status) switch_core_codec_encode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *decoded_data, void *decoded_data,
size_t decoded_data_len, size_t decoded_data_len,
int decoded_rate,
void *encoded_data, void *encoded_data,
size_t *encoded_data_len, size_t *encoded_data_len,
int *encoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
assert(codec != NULL); assert(codec != NULL);
@ -271,15 +273,17 @@ SWITCH_DECLARE(switch_status) switch_core_codec_encode(switch_codec *codec,
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
return codec->implementation->encode(codec, other_codec, decoded_data, decoded_data_len, encoded_data, encoded_data_len, flag); return codec->implementation->encode(codec, other_codec, decoded_data, decoded_data_len, decoded_rate, encoded_data, encoded_data_len, encoded_rate, flag);
} }
SWITCH_DECLARE(switch_status) switch_core_codec_decode(switch_codec *codec, SWITCH_DECLARE(switch_status) switch_core_codec_decode(switch_codec *codec,
switch_codec *other_codec, switch_codec *other_codec,
void *encoded_data, void *encoded_data,
size_t encoded_data_len, size_t encoded_data_len,
int encoded_rate,
void *decoded_data, void *decoded_data,
size_t *decoded_data_len, size_t *decoded_data_len,
int *decoded_rate,
unsigned int *flag) unsigned int *flag)
{ {
assert(codec != NULL); assert(codec != NULL);
@ -296,7 +300,7 @@ SWITCH_DECLARE(switch_status) switch_core_codec_decode(switch_codec *codec,
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
return codec->implementation->decode(codec, other_codec, encoded_data, encoded_data_len, decoded_data, decoded_data_len, flag); return codec->implementation->decode(codec, other_codec, encoded_data, encoded_data_len, encoded_rate, decoded_data, decoded_data_len, decoded_rate, flag);
} }
SWITCH_DECLARE(switch_status) switch_core_codec_destroy(switch_codec *codec) SWITCH_DECLARE(switch_status) switch_core_codec_destroy(switch_codec *codec)
@ -696,15 +700,19 @@ SWITCH_DECLARE(switch_status) switch_core_session_read_frame(switch_core_session
if (status == SWITCH_STATUS_SUCCESS && need_codec) { if (status == SWITCH_STATUS_SUCCESS && need_codec) {
switch_frame *enc_frame, *read_frame = *frame; switch_frame *enc_frame, *read_frame = *frame;
if (read_frame->codec) { if (read_frame->codec->codec_interface == session->read_codec->codec_interface) {
status = SWITCH_STATUS_SUCCESS;
} else if (read_frame->codec) {
unsigned int flag = 0; unsigned int flag = 0;
session->raw_read_frame.datalen = session->raw_read_frame.buflen; session->raw_read_frame.datalen = session->raw_read_frame.buflen;
status = switch_core_codec_decode(read_frame->codec, status = switch_core_codec_decode(read_frame->codec,
session->read_codec, session->read_codec,
read_frame->data, read_frame->data,
read_frame->datalen, read_frame->datalen,
read_frame->rate,
session->raw_read_frame.data, session->raw_read_frame.data,
&session->raw_read_frame.datalen, &session->raw_read_frame.datalen,
&session->raw_read_frame.rate,
&flag); &flag);
switch (status) { switch (status) {
@ -744,6 +752,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_read_frame(switch_core_session
session->raw_read_frame.datalen = switch_buffer_read(session->raw_read_buffer, session->raw_read_frame.datalen = switch_buffer_read(session->raw_read_buffer,
session->raw_read_frame.data, session->raw_read_frame.data,
session->read_codec->implementation->bytes_per_frame); session->read_codec->implementation->bytes_per_frame);
session->raw_read_frame.rate = session->read_codec->implementation->samples_per_second;
enc_frame = &session->raw_read_frame; enc_frame = &session->raw_read_frame;
} }
session->enc_read_frame.datalen = session->enc_read_frame.buflen; session->enc_read_frame.datalen = session->enc_read_frame.buflen;
@ -751,8 +760,10 @@ SWITCH_DECLARE(switch_status) switch_core_session_read_frame(switch_core_session
(*frame)->codec, (*frame)->codec,
session->raw_read_frame.data, session->raw_read_frame.data,
session->raw_read_frame.datalen, session->raw_read_frame.datalen,
session->raw_read_frame.rate,
session->enc_read_frame.data, session->enc_read_frame.data,
&session->enc_read_frame.datalen, &session->enc_read_frame.datalen,
&session->enc_read_frame.rate,
&flag); &flag);
@ -801,7 +812,6 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio
unsigned int flag = 0, need_codec = 0, perfect = 0; unsigned int flag = 0, need_codec = 0, perfect = 0;
switch_io_flag io_flag = SWITCH_IO_FLAG_NOOP; switch_io_flag io_flag = SWITCH_IO_FLAG_NOOP;
/* if you think this code is redundant.... too bad! I like to understand what I'm doing */ /* if you think this code is redundant.... too bad! I like to understand what I'm doing */
if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) { if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) {
need_codec = TRUE; need_codec = TRUE;
@ -816,18 +826,24 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio
} }
if (need_codec) { if (need_codec) {
if (frame->codec) {
if (frame->codec->codec_interface == session->write_codec->codec_interface) {
write_frame = frame;
status = SWITCH_STATUS_SUCCESS;
} else if (frame->codec) {
session->raw_write_frame.datalen = session->raw_write_frame.buflen; session->raw_write_frame.datalen = session->raw_write_frame.buflen;
status = switch_core_codec_decode(frame->codec, status = switch_core_codec_decode(frame->codec,
session->write_codec, session->write_codec,
frame->data, frame->data,
frame->datalen, frame->datalen,
frame->rate,
session->raw_write_frame.data, session->raw_write_frame.data,
&session->raw_write_frame.datalen, &session->raw_write_frame.datalen,
&session->raw_write_frame.rate,
&flag); &flag);
switch (status) { switch (status) {
case SWITCH_STATUS_SUCCESS: case SWITCH_STATUS_SUCCESS:
write_frame = &session->raw_write_frame; write_frame = &session->raw_write_frame;
break; break;
@ -866,15 +882,17 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio
if (perfect) { if (perfect) {
enc_frame = write_frame; enc_frame = write_frame;
session->enc_write_frame.datalen = session->enc_write_frame.buflen; session->enc_write_frame.datalen = session->enc_write_frame.buflen;
status = switch_core_codec_encode(session->write_codec, status = switch_core_codec_encode(session->write_codec,
frame->codec, frame->codec,
enc_frame->data, enc_frame->data,
enc_frame->datalen, enc_frame->datalen,
enc_frame->rate,
session->enc_write_frame.data, session->enc_write_frame.data,
&session->enc_write_frame.datalen, &session->enc_write_frame.datalen,
&session->enc_write_frame.rate,
&flag); &flag);
switch (status) { switch (status) {
case SWITCH_STATUS_SUCCESS: case SWITCH_STATUS_SUCCESS:
write_frame = &session->enc_write_frame; write_frame = &session->enc_write_frame;
@ -907,13 +925,16 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio
bytes))) { bytes))) {
enc_frame = &session->raw_write_frame; enc_frame = &session->raw_write_frame;
session->raw_write_frame.rate = session->write_codec->implementation->samples_per_second;
session->enc_write_frame.datalen = session->enc_write_frame.buflen; session->enc_write_frame.datalen = session->enc_write_frame.buflen;
status = switch_core_codec_encode(session->write_codec, status = switch_core_codec_encode(session->write_codec,
frame->codec, frame->codec,
enc_frame->data, enc_frame->data,
enc_frame->datalen, enc_frame->datalen,
enc_frame->rate,
session->enc_write_frame.data, session->enc_write_frame.data,
&session->enc_write_frame.datalen, &session->enc_write_frame.datalen,
&session->enc_write_frame.rate,
&flag); &flag);

View File

@ -35,7 +35,7 @@
#define MAXSAMPLEC (char)0x7F #define MAXSAMPLEC (char)0x7F
SWITCH_DECLARE(int) float_to_short(float *f, short *s, int len) SWITCH_DECLARE(int) switch_float_to_short(float *f, short *s, int len)
{ {
int i; int i;
float ft; float ft;
@ -52,7 +52,7 @@ SWITCH_DECLARE(int) float_to_short(float *f, short *s, int len)
return len; return len;
} }
SWITCH_DECLARE(int) char_to_float(char *c, float *f, int len) SWITCH_DECLARE(int) switch_char_to_float(char *c, float *f, int len)
{ {
int i; int i;
@ -69,7 +69,7 @@ SWITCH_DECLARE(int) char_to_float(char *c, float *f, int len)
return len/2; return len/2;
} }
SWITCH_DECLARE(int) float_to_char(float *f, char *c, int len) SWITCH_DECLARE(int) switch_float_to_char(float *f, char *c, int len)
{ {
int i; int i;
float ft; float ft;
@ -87,18 +87,18 @@ SWITCH_DECLARE(int) float_to_char(float *f, char *c, int len)
return len*2; return len*2;
} }
SWITCH_DECLARE(int) short_to_float(short *s, float *f, int len) SWITCH_DECLARE(int) switch_short_to_float(short *s, float *f, int len)
{ {
int i; int i;
int min, max;
min = max = 0;
for(i=0;i<len;i++) { for(i=0;i<len;i++) {
f[i] = (float)(s[i]) / NORMFACT; f[i] = (float)(s[i]) / NORMFACT;
//f[i] = (float) s[i];
} }
return len; return len;
} }
SWITCH_DECLARE(char *) switch_cut_path(char *in) SWITCH_DECLARE(char *) switch_cut_path(char *in)
{ {
char *p, *ret = in; char *p, *ret = in;