FS-8364: mod_codec2 : improvements, add extra modes: 3200,1400,1200. add config file.
This commit is contained in:
parent
8fc1acbb6c
commit
611449f4b3
|
@ -23,6 +23,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Mathieu Rene <mrene@avgs.ca>
|
||||
* Dragos Oancea <droancea@yahoo.com>
|
||||
*
|
||||
* mod_codec2 -- FreeSWITCH CODEC2 Module
|
||||
*
|
||||
|
@ -51,6 +52,10 @@ SWITCH_MODULE_DEFINITION(mod_codec2, mod_codec2_load, NULL, NULL);
|
|||
struct codec2_context {
|
||||
void *encoder;
|
||||
void *decoder;
|
||||
int mode; /* codec2 operation mode */
|
||||
int nbit; /* nr of bits per frame */
|
||||
int nbyte; /* nr of bytes per frame */
|
||||
int nsam; /* nr of samples per frame */
|
||||
#ifdef LOG_DATA
|
||||
FILE *encoder_in;
|
||||
FILE *encoder_out;
|
||||
|
@ -61,6 +66,12 @@ struct codec2_context {
|
|||
#endif
|
||||
};
|
||||
|
||||
struct {
|
||||
int mode;
|
||||
int ptime;
|
||||
int samples_per_frame;
|
||||
} codec2_prefs;
|
||||
|
||||
#ifdef LOG_DATA
|
||||
static int c2_count = 0;
|
||||
#endif
|
||||
|
@ -80,15 +91,40 @@ static switch_status_t switch_codec2_init(switch_codec_t *codec, switch_codec_fl
|
|||
if (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context)))) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (!codec2_prefs.mode) {
|
||||
codec2_prefs.mode = CODEC2_MODE_2400;
|
||||
}
|
||||
|
||||
if (codec2_prefs.mode == 3200) {
|
||||
context->mode = CODEC2_MODE_3200;
|
||||
} else if (codec2_prefs.mode == 2400) {
|
||||
context->mode = CODEC2_MODE_2400;
|
||||
} else if (codec2_prefs.mode == 1400) {
|
||||
context->mode = CODEC2_MODE_1400;
|
||||
} else if (codec2_prefs.mode == 1200) {
|
||||
context->mode = CODEC2_MODE_1200;
|
||||
} else {
|
||||
/* 3200 might be better for VOIP, but forcing 2400 for backwards compatibility */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mode not supported, forcing CODEC2_MODE_2400. You can try mode 3200 too!\n");
|
||||
context->mode = CODEC2_MODE_2400;
|
||||
}
|
||||
|
||||
if (encoding) {
|
||||
context->encoder = codec2_create(CODEC2_MODE_2400);
|
||||
context->encoder = codec2_create(context->mode);
|
||||
}
|
||||
|
||||
if (decoding) {
|
||||
context->decoder = codec2_create(CODEC2_MODE_2400);
|
||||
context->decoder = codec2_create(context->mode);
|
||||
}
|
||||
|
||||
context->nsam = codec2_samples_per_frame(context->encoder);
|
||||
if (!context->nsam) {
|
||||
context->nsam = CODEC2_SAMPLES_PER_FRAME;
|
||||
}
|
||||
context->nbit = codec2_bits_per_frame(context->encoder);
|
||||
context->nbyte = (context->nbit + 7) / 8;
|
||||
|
||||
codec->private_info = context;
|
||||
|
||||
#ifdef LOG_DATA
|
||||
|
@ -136,7 +172,7 @@ static switch_status_t switch_codec2_encode(switch_codec_t *codec, switch_codec_
|
|||
{
|
||||
struct codec2_context *context = codec->private_info;
|
||||
|
||||
codec2_assert(decoded_data_len == CODEC2_SAMPLES_PER_FRAME * 2);
|
||||
codec2_assert(decoded_data_len == context->nsam * 2);
|
||||
|
||||
#ifdef LOG_DATA
|
||||
fwrite(decoded_data, decoded_data_len, 1, context->encoder_in);
|
||||
|
@ -148,11 +184,11 @@ static switch_status_t switch_codec2_encode(switch_codec_t *codec, switch_codec_
|
|||
#ifdef LOG_DATA
|
||||
fwrite(encode_buf, sizeof(encode_buf), 1, context->encoder_out_unpacked);
|
||||
fflush(context->encoder_out_unpacked);
|
||||
fwrite(encoded_data, 8, 1, context->encoder_out);
|
||||
fwrite(encoded_data, context->nbyte, 1, context->encoder_out);
|
||||
fflush(context->encoder_out);
|
||||
#endif
|
||||
|
||||
*encoded_data_len = 6;
|
||||
*encoded_data_len = context->nbyte;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -169,7 +205,7 @@ static switch_status_t switch_codec2_decode(switch_codec_t *codec,
|
|||
{
|
||||
struct codec2_context *context = codec->private_info;
|
||||
|
||||
codec2_assert(encoded_data_len == 8 /* aligned to 8 */);
|
||||
codec2_assert(encoded_data_len == 8);
|
||||
|
||||
#ifdef LOG_DATA
|
||||
fwrite(encoded_data, encoded_data_len, 1, context->decoder_in);
|
||||
|
@ -181,11 +217,11 @@ static switch_status_t switch_codec2_decode(switch_codec_t *codec,
|
|||
codec2_decode(context->decoder, decoded_data, encoded_data);
|
||||
|
||||
#ifdef LOG_DATA
|
||||
fwrite(decoded_data, CODEC2_SAMPLES_PER_FRAME, 2, context->decoder_out);
|
||||
fwrite(decoded_data, context->nsam, 2, context->decoder_out);
|
||||
fflush(context->decoder_out);
|
||||
#endif
|
||||
|
||||
*decoded_data_len = CODEC2_SAMPLES_PER_FRAME * 2; /* 160 samples */
|
||||
*decoded_data_len = context->nsam * 2; /* eg: 160 samples for 3200,2400 */
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -224,13 +260,58 @@ static switch_status_t switch_codec2_destroy(switch_codec_t *codec)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t codec2_load_config(switch_bool_t reload) {
|
||||
|
||||
char *cf = "codec2.conf";
|
||||
switch_xml_t cfg, xml = NULL, param, settings;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
codec2_prefs.mode = 2400 ;
|
||||
|
||||
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opening of %s failed\n", cf);
|
||||
return status;
|
||||
}
|
||||
|
||||
if ((settings = switch_xml_child(cfg, "settings"))) {
|
||||
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
|
||||
char *key = (char *) switch_xml_attr_soft(param, "name");
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
|
||||
if (!strcasecmp(key, "mode") && !zstr(val)) {
|
||||
codec2_prefs.mode = atoi(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xml) {
|
||||
switch_xml_free(xml);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load)
|
||||
{
|
||||
switch_codec_interface_t *codec_interface;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
if ((status = codec2_load_config(SWITCH_FALSE)) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
/*there is no API call to retrieve ptime per mode, so hardcoding here*/
|
||||
if ((codec2_prefs.mode == 3200) ||(codec2_prefs.mode == 2400)) {
|
||||
codec2_prefs.ptime = 20000;
|
||||
codec2_prefs.samples_per_frame = CODEC2_SAMPLES_PER_FRAME;
|
||||
} else {
|
||||
codec2_prefs.ptime = 40000;
|
||||
codec2_prefs.samples_per_frame = CODEC2_SAMPLES_PER_FRAME * 2;
|
||||
}
|
||||
|
||||
SWITCH_ADD_CODEC(codec_interface, "CODEC2 2400bps");
|
||||
SWITCH_ADD_CODEC(codec_interface, "CODEC2 3200/2400/1400/1200bps");
|
||||
|
||||
switch_core_codec_add_implementation(pool, codec_interface,
|
||||
SWITCH_CODEC_TYPE_AUDIO,
|
||||
|
@ -239,10 +320,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load)
|
|||
NULL,
|
||||
8000, /* samples/sec */
|
||||
8000, /* samples/sec */
|
||||
2400, /* bps */
|
||||
20000, /* ptime */
|
||||
CODEC2_SAMPLES_PER_FRAME, /* samples decoded */
|
||||
CODEC2_SAMPLES_PER_FRAME*2, /* bytes decoded */
|
||||
codec2_prefs.mode, /* bps */
|
||||
codec2_prefs.ptime, /* ptime */
|
||||
codec2_prefs.samples_per_frame, /* samples decoded */
|
||||
codec2_prefs.samples_per_frame * 2, /* bytes decoded */
|
||||
0, /* bytes encoded */
|
||||
1, /* channels */
|
||||
1, /* frames/packet */
|
||||
|
|
Loading…
Reference in New Issue