From c87d2c0b8b75700541ed661ec5b9752911440854 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Dec 2008 01:53:46 +0000 Subject: [PATCH] add mod_celt git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10841 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- conf/autoload_configs/conference.conf.xml | 26 +++ conf/autoload_configs/local_stream.conf.xml | 10 +- src/include/switch_loadable_module.h | 108 ++++++--- src/include/switch_types.h | 4 +- .../mod_conference/mod_conference.c | 2 +- src/mod/codecs/mod_celt/Makefile | 20 ++ src/mod/codecs/mod_celt/mod_celt.c | 217 ++++++++++++++++++ .../codecs/mod_voipcodecs/mod_voipcodecs.c | 4 +- .../mod_local_stream/mod_local_stream.c | 2 +- src/switch_pcm.c | 191 ++++++++++++++- src/switch_time.c | 13 +- 11 files changed, 545 insertions(+), 52 deletions(-) create mode 100644 src/mod/codecs/mod_celt/Makefile create mode 100644 src/mod/codecs/mod_celt/mod_celt.c diff --git a/conf/autoload_configs/conference.conf.xml b/conf/autoload_configs/conference.conf.xml index caa48e8d6d..ab3d81bf00 100644 --- a/conf/autoload_configs/conference.conf.xml +++ b/conf/autoload_configs/conference.conf.xml @@ -150,5 +150,31 @@ + + + + --> diff --git a/conf/autoload_configs/local_stream.conf.xml b/conf/autoload_configs/local_stream.conf.xml index aa31aefaa9..db857697f4 100755 --- a/conf/autoload_configs/local_stream.conf.xml +++ b/conf/autoload_configs/local_stream.conf.xml @@ -22,5 +22,13 @@ - + diff --git a/src/include/switch_loadable_module.h b/src/include/switch_loadable_module.h index 724bb72d93..7f9e4b6b8a 100644 --- a/src/include/switch_loadable_module.h +++ b/src/include/switch_loadable_module.h @@ -41,6 +41,7 @@ #ifndef SWITCH_LOADABLE_MODULE_H #define SWITCH_LOADABLE_MODULE_H +#include #include #include @@ -324,44 +325,74 @@ SWITCH_DECLARE(uint32_t) switch_core_codec_next_id(void); break; \ } - - static inline void switch_core_codec_add_implementation(switch_memory_pool_t *pool, switch_codec_interface_t *codec_interface, - /*! enumeration defining the type of the codec */ - const switch_codec_type_t codec_type, - /*! the IANA code number */ - switch_payload_t ianacode, - /*! the IANA code name */ - const char *iananame, - /*! default fmtp to send (can be overridden by the init function) */ - char *fmtp, - /*! samples transferred per second */ - uint32_t samples_per_second, - /*! actual samples transferred per second for those who are not moron g722 RFC writers */ - uint32_t actual_samples_per_second, - /*! bits transferred per second */ - int bits_per_second, - /*! number of microseconds that denote one frame */ - int microseconds_per_packet, - /*! number of samples that denote one frame */ - uint32_t samples_per_packet, - /*! number of bytes that denote one frame decompressed */ - uint32_t decoded_bytes_per_packet, - /*! number of bytes that denote one frame compressed */ - uint32_t encoded_bytes_per_packet, - /*! number of channels represented */ - uint8_t number_of_channels, - /*! number of frames to send in one network packet */ - int codec_frames_per_packet, - /*! function to initialize a codec handle using this implementation */ - switch_core_codec_init_func_t init, - /*! function to encode raw data into encoded data */ - switch_core_codec_encode_func_t encode, - /*! function to decode encoded data into raw data */ - switch_core_codec_decode_func_t decode, - /*! deinitalize a codec handle using this implementation */ - switch_core_codec_destroy_func_t destroy) +static inline int switch_check_interval(uint32_t rate, uint32_t ptime) { - if (codec_type == SWITCH_CODEC_TYPE_VIDEO || SWITCH_ACCEPTABLE_INTERVAL(microseconds_per_packet / 1000)) { + uint32_t max_ms = 0, ptime_div = 0; + + switch (rate) { + case 22050: + case 11025: + if (ptime < 120) return 1; + break; + case 48000: + max_ms = 20; + ptime_div = 2; + break; + case 32000: + case 16000: + max_ms = 60; + ptime_div = 2; + break; + case 8000: + max_ms = 120; + ptime_div = 2; + break; + } + + if (max_ms && ptime_div && (ptime <= max_ms && (ptime % ptime_div) == 0) && ((rate / 1000) * ptime) < SWITCH_RECOMMENDED_BUFFER_SIZE) { + return 1; + } + + return 0; +} + +static inline void switch_core_codec_add_implementation(switch_memory_pool_t *pool, switch_codec_interface_t *codec_interface, + /*! enumeration defining the type of the codec */ + const switch_codec_type_t codec_type, + /*! the IANA code number */ + switch_payload_t ianacode, + /*! the IANA code name */ + const char *iananame, + /*! default fmtp to send (can be overridden by the init function) */ + char *fmtp, + /*! samples transferred per second */ + uint32_t samples_per_second, + /*! actual samples transferred per second for those who are not moron g722 RFC writers */ + uint32_t actual_samples_per_second, + /*! bits transferred per second */ + int bits_per_second, + /*! number of microseconds that denote one frame */ + int microseconds_per_packet, + /*! number of samples that denote one frame */ + uint32_t samples_per_packet, + /*! number of bytes that denote one frame decompressed */ + uint32_t decoded_bytes_per_packet, + /*! number of bytes that denote one frame compressed */ + uint32_t encoded_bytes_per_packet, + /*! number of channels represented */ + uint8_t number_of_channels, + /*! number of frames to send in one network packet */ + int codec_frames_per_packet, + /*! function to initialize a codec handle using this implementation */ + switch_core_codec_init_func_t init, + /*! function to encode raw data into encoded data */ + switch_core_codec_encode_func_t encode, + /*! function to decode encoded data into raw data */ + switch_core_codec_decode_func_t decode, + /*! deinitalize a codec handle using this implementation */ + switch_core_codec_destroy_func_t destroy) +{ + if (codec_type == SWITCH_CODEC_TYPE_VIDEO || switch_check_interval(actual_samples_per_second, microseconds_per_packet / 1000)) { switch_codec_implementation_t *impl = (switch_codec_implementation_t *) switch_core_alloc(pool, sizeof(*impl)); impl->codec_type = codec_type; impl->ianacode = ianacode; @@ -383,6 +414,9 @@ SWITCH_DECLARE(uint32_t) switch_core_codec_next_id(void); impl->codec_id = codec_interface->codec_id; impl->next = codec_interface->implementations; codec_interface->implementations = impl; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Rejected codec name: %s rate: %u ptime: %u\n", + iananame, actual_samples_per_second, microseconds_per_packet / 1000); } } diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 4eca73a33b..30dc54baef 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -359,9 +359,9 @@ SWITCH_DECLARE_DATA extern switch_directories SWITCH_GLOBAL_dirs; #define SWITCH_SYSTEM_THREAD_STACKSIZE 8192 * 1024 #define SWITCH_MAX_INTERVAL 120 /* we only do up to 120ms */ #define SWITCH_INTERVAL_PAD 10 /* A little extra buffer space to be safe */ -#define SWITCH_MAX_SAMPLE_LEN 32 +#define SWITCH_MAX_SAMPLE_LEN 48 #define SWITCH_BYTES_PER_SAMPLE 2 /* slin is 2 bytes per sample */ -#define SWITCH_RECOMMENDED_BUFFER_SIZE (SWITCH_BYTES_PER_SAMPLE * SWITCH_MAX_SAMPLE_LEN * (SWITCH_MAX_INTERVAL + SWITCH_INTERVAL_PAD)) +#define SWITCH_RECOMMENDED_BUFFER_SIZE 4096 /* worst case of 32khz @60ms we only do 48khz @10ms which is 960 */ #define SWITCH_MAX_CODECS 50 #define SWITCH_MAX_STATE_HANDLERS 30 #define SWITCH_CORE_QUEUE_LEN 100000 diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index ca4aaea8c4..1b8571e009 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -4893,7 +4893,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_m if (!strcasecmp(var, "rate") && !switch_strlen_zero(val)) { uint32_t tmp = atoi(val); - if (tmp == 8000 || tmp == 16000 || tmp == 32000) { + if (tmp == 8000 || tmp == 16000 || tmp == 32000 || tmp == 48000) { rate = tmp; } } else if (!strcasecmp(var, "domain") && !switch_strlen_zero(val)) { diff --git a/src/mod/codecs/mod_celt/Makefile b/src/mod/codecs/mod_celt/Makefile new file mode 100644 index 0000000000..7ce40f6bb9 --- /dev/null +++ b/src/mod/codecs/mod_celt/Makefile @@ -0,0 +1,20 @@ +BASE=../../../.. + +CELT=celt-0.5.0 + +CELT_DIR=$(BASE)/libs/$(CELT) +LOCAL_CFLAGS=-I$(CELT_DIR)/libcelt +CELT_LA=$(CELT_DIR)/libcelt/.libs/libcelt.la +LOCAL_LIBADD=$(CELT_LA) +include $(BASE)/build/modmake.rules + +$(CELT_DIR): + $(GETLIB) $(CELT).tar.gz + +$(CELT_DIR)/Makefile: $(CELT_DIR) + cd $(CELT_DIR) && CFLAGS=$(AM_CFLAGS) ./configure --disable-shared --with-pic + +$(CELT_LA): $(CELT_DIR)/Makefile + cd $(CELT_DIR) && $(MAKE) + $(TOUCH_TARGET) + diff --git a/src/mod/codecs/mod_celt/mod_celt.c b/src/mod/codecs/mod_celt/mod_celt.c new file mode 100644 index 0000000000..ab13bd2c1e --- /dev/null +++ b/src/mod/codecs/mod_celt/mod_celt.c @@ -0,0 +1,217 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Brian K. West + * + * mod_celt.c -- The CELT ultra-low delay audio codec (http://www.celt-codec.org/) + * + */ + +#include "switch.h" +#include "celt.h" + +SWITCH_MODULE_LOAD_FUNCTION(mod_celt_load); +SWITCH_MODULE_DEFINITION(mod_celt, mod_celt_load, NULL, NULL); + +struct celt_context { + CELTEncoder *encoder_object; + CELTDecoder *decoder_object; + CELTMode *mode_object; + int frame_size; + int bytes_per_packet; +}; + +static switch_status_t switch_celt_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) +{ + struct celt_context *context = NULL; + int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); + int decoding = (flags & SWITCH_CODEC_FLAG_DECODE); + + if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { + return SWITCH_STATUS_FALSE; + } + + context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, 1, codec->implementation->samples_per_packet, NULL); + celt_mode_info(context->mode_object, CELT_GET_FRAME_SIZE, &context->frame_size); + context->bytes_per_packet = (codec->implementation->bits_per_second * context->frame_size/codec->implementation->actual_samples_per_second + 4) / 8; + + /* + if (codec->fmtp_in) { + int x, argc; + char *argv[10]; + argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + if (!strcasecmp(data, "bitrate")) { + bit_rate = atoi(arg); + } + } + } + } + + codec->fmtp_out = switch_core_sprintf(codec->memory_pool, "bitrate=%d", bit_rate); + */ + if (encoding) { + context->encoder_object = celt_encoder_create(context->mode_object); + } + + if (decoding) { + context->decoder_object = celt_decoder_create(context->mode_object); + } + + codec->private_info = context; + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_celt_destroy(switch_codec_t *codec) +{ + codec->private_info = NULL; + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_celt_encode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *decoded_data, + uint32_t decoded_data_len, + uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, + unsigned int *flag) +{ + struct celt_context *context = codec->private_info; + + if (!context) { + return SWITCH_STATUS_FALSE; + } + + *encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (celt_int16_t *)decoded_data, NULL, + (unsigned char *)encoded_data, context->bytes_per_packet); + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_celt_decode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *encoded_data, + uint32_t encoded_data_len, + uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, + unsigned int *flag) +{ + struct celt_context *context = codec->private_info; + + if (!context) { + return SWITCH_STATUS_FALSE; + } + + if (celt_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data)) { + return SWITCH_STATUS_GENERR; + } + + *decoded_data_len = codec->implementation->decoded_bytes_per_packet; + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_celt_load) +{ + switch_codec_interface_t *codec_interface; + int bytes_per_frame; + int samples_per_frame; + int ms_per_frame; + int x; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_CODEC(codec_interface, "CELT ultra-low delay"); + + switch_core_codec_add_implementation(pool, + codec_interface, + SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 114, /* the IANA code number */ + "CELT", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 32000, /* samples transferred per second */ + 32000, /* actual samples transferred per second */ + 32000, /* bits transferred per second */ + 10000, /* number of microseconds per frame */ + 320, /* number of samples per frame */ + 640, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_celt_init, /* function to initialize a codec handle using this implementation */ + switch_celt_encode, /* function to encode raw data into encoded data */ + switch_celt_decode, /* function to decode encoded data into raw data */ + switch_celt_destroy); /* deinitalize a codec handle using this implementation */ + ms_per_frame = 2000; + samples_per_frame = 96; + bytes_per_frame = 192; + + for (x = 0; x < 5; x++) { + switch_core_codec_add_implementation(pool, + codec_interface, + SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 114, /* the IANA code number */ + "CELT", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 48000, /* samples transferred per second */ + 48000, /* actual samples transferred per second */ + 48000, /* bits transferred per second */ + ms_per_frame, /* number of microseconds per frame */ + samples_per_frame, /* number of samples per frame */ + bytes_per_frame, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_celt_init, /* function to initialize a codec handle using this implementation */ + switch_celt_encode, /* function to encode raw data into encoded data */ + switch_celt_decode, /* function to decode encoded data into raw data */ + switch_celt_destroy); /* deinitalize a codec handle using this implementation */ + ms_per_frame += 2000; + samples_per_frame += 96; + bytes_per_frame += 192; + } + + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c b/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c index b9b4a6cecc..48345453db 100644 --- a/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c +++ b/src/mod/codecs/mod_voipcodecs/mod_voipcodecs.c @@ -588,7 +588,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voipcodecs_load) switch_adpcm_destroy); /* deinitalize a codec handle using this implementation */ } mpf = 10000, spf = 160, bpf = 320, ebpf = 160; - for (count = 12; count > 0; count--) { + for (count = 6; count > 0; count--) { switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ @@ -781,7 +781,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voipcodecs_load) /* G722 */ mpf = 10000, spf = 80, bpf = 320, ebpf = 80; SWITCH_ADD_CODEC(codec_interface, "G.722"); - for (count = 12; count > 0; count--) { + for (count = 6; count > 0; count--) { switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index c091ac8ffc..ce6f94a636 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -450,7 +450,7 @@ static void launch_threads(void) if (!strcasecmp(var, "rate")) { int tmp = atoi(val); - if (tmp == 8000 || tmp == 16000 || tmp == 32000) { + if (tmp == 8000 || tmp == 16000 || tmp == 32000 || tmp == 48000) { source->rate = tmp; } } else if (!strcasecmp(var, "shuffle")) { diff --git a/src/switch_pcm.c b/src/switch_pcm.c index bcc6f3de27..262ebca06a 100644 --- a/src/switch_pcm.c +++ b/src/switch_pcm.c @@ -323,6 +323,7 @@ SWITCH_MODULE_LOAD_FUNCTION(core_pcm_load) switch_codec_interface_t *codec_interface; int mpf = 10000, spf = 80, bpf = 160, ebpf = 160, bps = 128000, rate = 8000, counta = 1, countb = 12; switch_payload_t ianacode[4] = { 0, 10, 117, 119 }; + int samples_per_frame, bytes_per_frame, ms_per_frame, x; /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); @@ -342,7 +343,12 @@ SWITCH_MODULE_LOAD_FUNCTION(core_pcm_load) SWITCH_ADD_CODEC(codec_interface, "RAW Signed Linear (16 bit)"); for (counta = 1; counta <= 3; counta++) { - for (countb = 12; countb > 0; countb--) { + if (rate == 8000) { + countb = 12; + } else { + countb = 6; + } + for (; countb > 0; countb--) { switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, ianacode[counta], "L16", NULL, rate, rate, bps, mpf * countb, spf * countb, bpf * countb, ebpf * countb, 1, spf * countb, @@ -356,13 +362,186 @@ SWITCH_MODULE_LOAD_FUNCTION(core_pcm_load) } /* these formats below are for file playing. */ - switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_AUDIO, 118, "L16", NULL, 22050, 22050, 352800, - 20000, 441, 882, 882, 1, 1, switch_raw_init, switch_raw_encode, switch_raw_decode, switch_raw_destroy); + samples_per_frame = 96; + bytes_per_frame = 192; + ms_per_frame = 2000; + + for (x = 0; x < 5; x++) { + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 118, /* the IANA code number */ + "L16", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 48000, /* samples transferred per second */ + 48000, /* actual samples transferred per second */ + 768000, /* bits transferred per second */ + ms_per_frame, /* number of microseconds per frame */ + samples_per_frame, /* number of samples per frame */ + bytes_per_frame, /* number of bytes per frame decompressed */ + bytes_per_frame, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_raw_init, /* function to initialize a codec handle using this implementation */ + switch_raw_encode, /* function to encode raw data into encoded data */ + switch_raw_decode, /* function to decode encoded data into raw data */ + switch_raw_destroy); /* deinitalize a codec handle using this implementation */ + + samples_per_frame += 96; + bytes_per_frame += 192; + ms_per_frame += 2000; + + } + + + samples_per_frame = 8; + bytes_per_frame = 16; + ms_per_frame = 2000; + + for (x = 0; x < 5; x++) { + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 10, /* the IANA code number */ + "L16", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 8000, /* samples transferred per second */ + 8000, /* actual samples transferred per second */ + 128000, /* bits transferred per second */ + ms_per_frame, /* number of microseconds per frame */ + samples_per_frame, /* number of samples per frame */ + bytes_per_frame, /* number of bytes per frame decompressed */ + bytes_per_frame, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_raw_init, /* function to initialize a codec handle using this implementation */ + switch_raw_encode, /* function to encode raw data into encoded data */ + switch_raw_decode, /* function to decode encoded data into raw data */ + switch_raw_destroy); /* deinitalize a codec handle using this implementation */ + + samples_per_frame += 8; + bytes_per_frame += 16; + ms_per_frame += 2000; + + } + + + + samples_per_frame = 16; + bytes_per_frame = 32; + ms_per_frame = 2000; + + for (x = 0; x < 5; x++) { + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 10, /* the IANA code number */ + "L16", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 16000, /* samples transferred per second */ + 16000, /* actual samples transferred per second */ + 256000, /* bits transferred per second */ + ms_per_frame, /* number of microseconds per frame */ + samples_per_frame, /* number of samples per frame */ + bytes_per_frame, /* number of bytes per frame decompressed */ + bytes_per_frame, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_raw_init, /* function to initialize a codec handle using this implementation */ + switch_raw_encode, /* function to encode raw data into encoded data */ + switch_raw_decode, /* function to decode encoded data into raw data */ + switch_raw_destroy); /* deinitalize a codec handle using this implementation */ + + samples_per_frame += 16; + bytes_per_frame += 32; + ms_per_frame += 2000; + + } + + + samples_per_frame = 32; + bytes_per_frame = 64; + ms_per_frame = 2000; + + for (x = 0; x < 5; x++) { + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 10, /* the IANA code number */ + "L16", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 32000, /* samples transferred per second */ + 32000, /* actual samples transferred per second */ + 512000, /* bits transferred per second */ + ms_per_frame, /* number of microseconds per frame */ + samples_per_frame, /* number of samples per frame */ + bytes_per_frame, /* number of bytes per frame decompressed */ + bytes_per_frame, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_raw_init, /* function to initialize a codec handle using this implementation */ + switch_raw_encode, /* function to encode raw data into encoded data */ + switch_raw_decode, /* function to decode encoded data into raw data */ + switch_raw_destroy); /* deinitalize a codec handle using this implementation */ + + samples_per_frame += 32; + bytes_per_frame += 64; + ms_per_frame += 2000; + + } switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_AUDIO, 118, "L16", NULL, 11025, 11025, 176400, - 40000, 441, 882, 882, 1, 1, switch_raw_init, switch_raw_encode, switch_raw_decode, switch_raw_destroy); + SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 118, /* the IANA code number */ + "L16", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 48000, /* samples transferred per second */ + 48000, /* actual samples transferred per second */ + 768000, /* bits transferred per second */ + 20000, /* number of microseconds per frame */ + 960, /* number of samples per frame */ + 1920, /* number of bytes per frame decompressed */ + 1920, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_raw_init, /* function to initialize a codec handle using this implementation */ + switch_raw_encode, /* function to encode raw data into encoded data */ + switch_raw_decode, /* function to decode encoded data into raw data */ + switch_raw_destroy); /* deinitalize a codec handle using this implementation */ + + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 118, /* the IANA code number */ + "L16", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 22050, /* samples transferred per second */ + 22050, /* actual samples transferred per second */ + 352800, /* bits transferred per second */ + 20000, /* number of microseconds per frame */ + 441, /* number of samples per frame */ + 882, /* number of bytes per frame decompressed */ + 882, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_raw_init, /* function to initialize a codec handle using this implementation */ + switch_raw_encode, /* function to encode raw data into encoded data */ + switch_raw_decode, /* function to decode encoded data into raw data */ + switch_raw_destroy); /* deinitalize a codec handle using this implementation */ + + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 118, /* the IANA code number */ + "L16", /* the IANA code name */ + NULL, /* default fmtp to send (can be overridden by the init function) */ + 11025, /* samples transferred per second */ + 11025, /* actual samples transferred per second */ + 176400, /* bits transferred per second */ + 40000, /* number of microseconds per frame */ + 441, /* number of samples per frame */ + 882, /* number of bytes per frame decompressed */ + 882, /* number of bytes per frame compressed */ + 1, /* number of channels represented */ + 1, /* number of frames per network packet */ + switch_raw_init, /* function to initialize a codec handle using this implementation */ + switch_raw_encode, /* function to encode raw data into encoded data */ + switch_raw_decode, /* function to decode encoded data into raw data */ + switch_raw_destroy); /* deinitalize a codec handle using this implementation */ diff --git a/src/switch_time.c b/src/switch_time.c index 405e6ddb11..ed717ee4be 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -44,7 +44,9 @@ #endif #define MAX_TICK UINT32_MAX - 1024 -#define MS_PER_TICK 10 + +static int MS_PER_TICK = 10; + static switch_memory_pool_t *module_pool = NULL; static struct { @@ -252,6 +254,11 @@ static switch_status_t timer_init(switch_timer_t *timer) private_info->start = private_info->reference = TIMER_MATRIX[timer->interval].tick; private_info->roll = TIMER_MATRIX[timer->interval].roll; private_info->ready = 1; + + if (timer->interval < MS_PER_TICK) { + MS_PER_TICK = timer->interval; + } + return SWITCH_STATUS_SUCCESS; } @@ -319,7 +326,7 @@ static switch_status_t timer_next(switch_timer_t *timer) #endif timer_step(timer); - + while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) { check_roll(); if (globals.use_cond_yield == 1) { @@ -506,6 +513,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) } #endif + if ((current_ms % MS_PER_TICK) == 0) { for (x = MS_PER_TICK; x <= MAX_ELEMENTS; x += MS_PER_TICK) { if ((current_ms % x) == 0) { @@ -525,6 +533,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) } } } + if (current_ms == MAX_ELEMENTS) { current_ms = 0; }