提交 e98104d1 authored 作者: Anthony Minessale's avatar Anthony Minessale

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
上级 0fbf3f5a
...@@ -106,15 +106,19 @@ SWITCH_DECLARE(switch_status) switch_core_codec_encode(switch_codec *codec, ...@@ -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);
......
...@@ -44,6 +44,7 @@ struct switch_frame { ...@@ -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
......
...@@ -228,15 +228,19 @@ struct switch_codec_implementation { ...@@ -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;
......
...@@ -55,6 +55,7 @@ typedef enum { ...@@ -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;
......
...@@ -70,10 +70,10 @@ SWITCH_DECLARE(switch_status) switch_socket_create_pollfd(switch_pollfd_t *poll, ...@@ -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) \
......
...@@ -79,8 +79,10 @@ static switch_status switch_gsm_encode(switch_codec *codec, ...@@ -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, ...@@ -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;
......
...@@ -74,8 +74,10 @@ static switch_status switch_g729_encode(switch_codec *codec, ...@@ -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, ...@@ -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;
......
...@@ -911,6 +911,7 @@ static switch_status exosip_create_call(eXosip_event_t *event) ...@@ -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) ...@@ -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);
......
...@@ -55,8 +55,10 @@ static switch_status switch_g711u_encode(switch_codec *codec, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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;
......
...@@ -298,6 +298,7 @@ static switch_status iax_set_codec(struct private_object *tech_pvt, struct iax_s ...@@ -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);
......
...@@ -103,7 +103,7 @@ void playback_function(switch_core_session *session, char *data) ...@@ -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) ...@@ -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
......
...@@ -75,6 +75,7 @@ static struct { ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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) ...@@ -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);
......
...@@ -42,21 +42,24 @@ static const char modname[] = "mod_rawaudio"; ...@@ -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,13 +70,16 @@ static int resample(void *handle, double factor, float *src, int srclen, float * ...@@ -67,13 +70,16 @@ 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);
srcpos += srcused; //printf("resampling %d/%d (%d) %d %f\n", srcpos, srclen, MIN(dstlen-out, dstlen), srcused, factor);
if (o >= 0)
srcpos += srcused;
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, ...@@ -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,23 +119,49 @@ static switch_status switch_raw_encode(switch_codec *codec, ...@@ -111,23 +119,49 @@ 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 (!context->enc_from) { if (other_codec &&
printf("Activate Resample %d->%d\n", codec->implementation->samples_per_second, other_codec->implementation->samples_per_second); codec->implementation->samples_per_second != other_codec->implementation->samples_per_second &&
context->enc_from = codec->implementation->samples_per_second; decoded_rate != other_codec->implementation->samples_per_second) {
context->enc_to = other_codec->implementation->samples_per_second; const short *ddp = decoded_data;
context->enc_factor = ((double) context->enc_from / (double)context->enc_to); short *edp = encoded_data;
context->enc_resampler = resample_open(1, context->enc_factor, context->enc_factor); size_t ddplen = decoded_data_len / 2;
context->enc_buf_size = codec->implementation->bytes_per_frame;
context->enc_buf = (float *) switch_core_alloc(codec->memory_pool, context->enc_buf_size); if (!context->enc) {
if (!(context->enc = switch_core_alloc(codec->memory_pool, sizeof(struct raw_resampler)))) {
return SWITCH_STATUS_MEMERR;
}
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_from) { 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, ...@@ -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, ...@@ -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;
} }
......
...@@ -157,8 +157,10 @@ static switch_status switch_speex_encode(switch_codec *codec, ...@@ -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, ...@@ -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;
......
...@@ -198,6 +198,7 @@ static switch_status woomerachan_on_init(switch_core_session *session) ...@@ -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) ...@@ -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);
......
...@@ -253,8 +253,10 @@ SWITCH_DECLARE(switch_status) switch_core_codec_encode(switch_codec *codec, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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;
...@@ -840,7 +856,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio ...@@ -840,7 +856,7 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio
return status; return status;
break; break;
} }
} }
if (session->write_codec) { if (session->write_codec) {
if (write_frame->datalen == session->write_codec->implementation->bytes_per_frame) { if (write_frame->datalen == session->write_codec->implementation->bytes_per_frame) {
...@@ -866,15 +882,17 @@ SWITCH_DECLARE(switch_status) switch_core_session_write_frame(switch_core_sessio ...@@ -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 ...@@ -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);
......
...@@ -35,92 +35,92 @@ ...@@ -35,92 +35,92 @@
#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;
for(i=0;i<len;i++) { for(i=0;i<len;i++) {
ft = f[i] * NORMFACT; ft = f[i] * NORMFACT;
if(ft >= 0) { if(ft >= 0) {
s[i] = (short)(ft+0.5); s[i] = (short)(ft+0.5);
} else { } else {
s[i] = (short)(ft-0.5); s[i] = (short)(ft-0.5);
} }
if (s[i] > (short)MAXSAMPLE) s[i] = (short)MAXSAMPLE; if (s[i] > (short)MAXSAMPLE) s[i] = (short)MAXSAMPLE;
if (s[i] < (short)-MAXSAMPLE) s[i] = (short)-MAXSAMPLE; if (s[i] < (short)-MAXSAMPLE) s[i] = (short)-MAXSAMPLE;
} }
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;
if (len % 2) { if (len % 2) {
return(-1); return(-1);
} }
for(i=1;i<len;i+=2) { for(i=1;i<len;i+=2) {
f[(int)(i/2)] = (float)(((c[i])*0x100) + c[i-1]); f[(int)(i/2)] = (float)(((c[i])*0x100) + c[i-1]);
f[(int)(i/2)] /= NORMFACT; f[(int)(i/2)] /= NORMFACT;
if (f[(int)(i/2)] > MAXSAMPLE) f[(int)(i/2)] = MAXSAMPLE; if (f[(int)(i/2)] > MAXSAMPLE) f[(int)(i/2)] = MAXSAMPLE;
if (f[(int)(i/2)] < -MAXSAMPLE) f[(int)(i/2)] = -MAXSAMPLE; if (f[(int)(i/2)] < -MAXSAMPLE) f[(int)(i/2)] = -MAXSAMPLE;
} }
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;
long l; long l;
for(i=0;i<len;i++) { for(i=0;i<len;i++) {
ft = f[i] * NORMFACT; ft = f[i] * NORMFACT;
if (ft >= 0) { if (ft >= 0) {
l = (long)(ft+0.5); l = (long)(ft+0.5);
} else { } else {
l = (long)(ft-0.5); l = (long)(ft-0.5);
} }
c[i*2] = (unsigned char)((l)&0xff); c[i*2] = (unsigned char)((l)&0xff);
c[i*2+1] = (unsigned char)(((l)>>8)&0xff); c[i*2+1] = (unsigned char)(((l)>>8)&0xff);
} }
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;
char delims[] = "/\\"; char delims[] = "/\\";
char *i; char *i;
for(i = delims; *i; i++) { for(i = delims; *i; i++) {
p = in; p = in;
while((p = strchr(p, *i))) { while((p = strchr(p, *i))) {
ret = ++p; ret = ++p;
} }
} }
return ret; return ret;
} }
SWITCH_DECLARE(void) switch_swap_linear(int16_t *buf, int len) SWITCH_DECLARE(void) switch_swap_linear(int16_t *buf, int len)
{ {
int i; int i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
buf[i] = ((buf[i] >> 8) & 0x00ff) | ((buf[i] << 8) & 0xff00); buf[i] = ((buf[i] >> 8) & 0x00ff) | ((buf[i] << 8) & 0xff00);
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论