diff --git a/conf/vanilla/autoload_configs/opusfile.conf.xml b/conf/vanilla/autoload_configs/opusfile.conf.xml
new file mode 100644
index 0000000000..42e7d42523
--- /dev/null
+++ b/conf/vanilla/autoload_configs/opusfile.conf.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mod/formats/mod_opusfile/mod_opusfile.c b/src/mod/formats/mod_opusfile/mod_opusfile.c
index a065108f5c..f06e835c69 100644
--- a/src/mod/formats/mod_opusfile/mod_opusfile.c
+++ b/src/mod/formats/mod_opusfile/mod_opusfile.c
@@ -24,7 +24,7 @@
* Contributor(s):
*
* Dragos Oancea (mod_opusfile.c)
- *
+ * Yossi Ne'eman
*
* mod_opusfile.c -- Read and Write OGG/Opus files . Some parts inspired from mod_shout.c, libopusfile, libopusenc
*
@@ -59,6 +59,12 @@
SWITCH_MODULE_LOAD_FUNCTION(mod_opusfile_load);
SWITCH_MODULE_DEFINITION(mod_opusfile, mod_opusfile_load, NULL, NULL);
+typedef enum {
+ CHANNELS_FORMAT_DEFAULT = 0,
+ CHANNELS_FORMAT_AMBIX = 1,
+ CHANNELS_FORMAT_DISCRETE = 2
+} CHANNELS_FORMAT;
+
struct opus_file_context {
switch_file_t *fd;
OggOpusFile *of;
@@ -88,11 +94,25 @@ struct opus_file_context {
switch_size_t opusbuflen;
FILE *fp;
#ifdef HAVE_OPUSFILE_ENCODE
+ size_t original_samplerate;
OggOpusEnc *enc;
OggOpusComments *comments;
unsigned char encode_buf[OPUSFILE_MAX];
int encoded_buflen;
size_t samples_encode;
+ FILE *fout;
+ opus_int64 total_bytes;
+ opus_int64 bytes_written;
+ opus_int64 nb_encoded;
+ opus_int64 pages_out;
+ opus_int64 packets_out;
+ opus_int32 peak_bytes;
+ opus_int32 min_bytes;
+ opus_int32 last_length;
+ opus_int32 nb_streams;
+ opus_int32 nb_coupled;
+ int mapping_family;
+ FILE *frange;
#endif
switch_memory_pool_t *pool;
};
@@ -138,6 +158,17 @@ struct opus_stream_context {
size_t samples_encode;
int enc_channels;
unsigned int enc_pagecount;
+ opus_int64 total_bytes;
+ opus_int64 bytes_written;
+ opus_int64 nb_encoded;
+ opus_int64 pages_out;
+ opus_int64 packets_out;
+ opus_int32 peak_bytes;
+ opus_int32 min_bytes;
+ opus_int32 last_length;
+ opus_int32 nb_streams;
+ opus_int32 nb_coupled;
+ FILE *frange;
#endif
unsigned int dec_count;
switch_thread_t *read_stream_thread;
@@ -148,8 +179,128 @@ typedef struct opus_stream_context opus_stream_context_t;
static struct {
int debug;
+ opus_int32 bitrate[4];
+ int complexity;
+ size_t maximum_samplerate;
+ CHANNELS_FORMAT channels_format;
} globals;
+static int opusfile_write_callback(void *user_data, const unsigned char *ptr, opus_int32 len)
+{
+ opus_file_context *data = (opus_file_context *) user_data;
+ data->bytes_written += len;
+ data->pages_out++;
+ return fwrite(ptr, 1, len, data->fout) != (size_t)len;
+}
+
+static int opusfile_close_callback(void *user_data)
+{
+ opus_file_context *data = (opus_file_context *) user_data;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Closing out an opus file. %lu bytes written.\n", (unsigned long) data->bytes_written);
+
+ return fclose(data->fout) != 0;
+}
+
+static switch_status_t opus_obj_init(switch_file_handle_t *handle, opus_file_context *context)
+{
+ switch_status_t retval = SWITCH_STATUS_SUCCESS;
+#ifdef HAVE_OPUSFILE_ENCODE
+ const char *fopen_mode = "wb+";
+ char text_samplerate[6] = { 0 };
+
+ if (switch_test_flag(handle, SWITCH_FILE_WRITE_APPEND)) {
+ fopen_mode = "ab+";
+ }
+
+ if(!context->fout) {
+ context->fout = fopen(handle->file_path, fopen_mode);
+ if(!context->fout) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to open file %s , cannot record the file.\n", handle->file_path);
+ retval = SWITCH_STATUS_FALSE;
+ goto opus_obj_init_end;
+ }
+ }
+
+ if (!context->comments) {
+ context->comments = ope_comments_create();
+ }
+
+ context->channels = handle->channels;
+ handle->seekable = 0;
+
+ // Need to set the proper sample rate for the channel (might override what it currently is
+ if(handle->samplerate > globals.maximum_samplerate) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "The global maximum_samplerate is set to %lu kHz, which is less than the channel's samplerate of %d kHz. Reducing to the global maximum_samplerate.\n", globals.maximum_samplerate / 1000, handle->samplerate / 1000);
+ handle->samplerate = context->samplerate = globals.maximum_samplerate;
+ } else {
+ context->samplerate = handle->samplerate;
+ }
+
+ // opus_multistream_surround_encoder_get_size() in libopus will check these
+ // 2024-01-02 current opus-tools git head introduced logic for additional channel modes
+ if(globals.channels_format == CHANNELS_FORMAT_AMBIX) {
+ context->mapping_family = (context->channels >= 4 && context->channels <= 18) ? 3 : 2;
+ ope_comments_add(context->comments,"CHANNELS_MODE", "AMBIX");
+ } else if(globals.channels_format == CHANNELS_FORMAT_DISCRETE) {
+ context->mapping_family = 255;
+ ope_comments_add(context->comments,"CHANNELS_MODE", "DISCRETE");
+ } else {
+ context->mapping_family = context->channels > 8 ? 255 : context->channels > 2;
+ ope_comments_add(context->comments,"CHANNELS_MODE", "DEFAULT");
+ }
+
+ if(globals.debug) {
+ snprintf(text_samplerate, 6, "%lu", context->original_samplerate);
+ ope_comments_add(context->comments,"SOURCE_SAMPLERATE", text_samplerate);
+ }
+
+#endif
+opus_obj_init_end:
+ return retval;
+}
+
+static switch_status_t opus_obj_init_secondary(opus_file_context *context)
+{
+ int err = 0;
+ switch_status_t retval = SWITCH_STATUS_SUCCESS;
+ OpusEncCallbacks callbacks = { opusfile_write_callback, opusfile_close_callback };
+
+ context->enc = ope_encoder_create_callbacks(&callbacks, context, context->comments, context->samplerate, context->channels, context->mapping_family, &err);
+ if (!context->enc) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open file for writing [%d] [%s]\n", err, ope_strerror(err));
+ switch_thread_rwlock_unlock(context->rwlock);
+ retval = SWITCH_STATUS_FALSE;
+ } else {
+ // Let's set the bitrate and complexity, shall we?
+ opus_int32 i;
+ switch(context->samplerate) {
+ case 48000:
+ i = 3;
+ break;
+ case 32000:
+ i = 2;
+ break;
+ case 16000:
+ i = 1;
+ break;
+ case 8000:
+ default:
+ i = 0;
+ }
+
+ if((err = ope_encoder_ctl(context->enc, OPUS_SET_BITRATE_REQUEST, globals.bitrate[i] * context->channels)) != OPE_OK) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to properly set the bitrate. err: [%d] [%s]\n", err, ope_strerror(err));
+ }
+
+ if((err = ope_encoder_ctl(context->enc, OPUS_SET_COMPLEXITY_REQUEST, globals.complexity)) != OPE_OK) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to properly set the complexity. err: [%d] [%s]\n", err, ope_strerror(err));
+ }
+ }
+
+ return retval;
+}
+
static switch_status_t switch_opusfile_decode(opus_file_context *context, void *data, size_t max_bytes, int channels)
{
int ret = 0;
@@ -256,7 +407,7 @@ static switch_status_t switch_opusfile_open(switch_file_handle_t *handle, const
}
handle->samples = 0;
- handle->samplerate = context->samplerate = DEFAULT_RATE; /*open files at 48 khz always*/
+ context->original_samplerate = handle->samplerate; /* Need to know the source samplerate for proper bitrate selection */
handle->format = 0;
handle->sections = 0;
handle->seekable = 1;
@@ -268,28 +419,20 @@ static switch_status_t switch_opusfile_open(switch_file_handle_t *handle, const
#ifdef HAVE_OPUSFILE_ENCODE
if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
- int err; int mapping_family = 0;
-
- context->channels = handle->channels;
- context->samplerate = handle->samplerate;
- handle->seekable = 0;
- context->comments = ope_comments_create();
- ope_comments_add(context->comments, "METADATA", "Freeswitch/mod_opusfile");
- // opus_multistream_surround_encoder_get_size() in libopus will check these
- if ((context->channels > 2) && (context->channels <= 8)) {
- mapping_family = 1;
- } else if ((context->channels > 8) && (context->channels <= 255)) {
- mapping_family = 255;
- }
- context->enc = ope_encoder_create_file(handle->file_path, context->comments, context->samplerate, context->channels, mapping_family, &err);
- if (!context->enc) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open file for writing [%d] [%s]\n", err, ope_strerror(err));
- switch_thread_rwlock_unlock(context->rwlock);
- return SWITCH_STATUS_FALSE;
+ switch_status_t retval = opus_obj_init(handle, context);
+ if(retval != SWITCH_STATUS_SUCCESS) {
+ return retval;
}
+
switch_thread_rwlock_unlock(context->rwlock);
return SWITCH_STATUS_SUCCESS;
+ } else {
+ // Decoding is always done at 48000 Hz in opus
+ handle->samplerate = context->samplerate = DEFAULT_RATE; // open files for decode at 48 khz always
}
+#else
+ // Decoding is always done at 48000 Hz in opus
+ handle->samplerate = context->samplerate = DEFAULT_RATE; /*open files at 48 khz always*/
#endif
context->of = op_open_file(path, &ret);
@@ -315,7 +458,8 @@ static switch_status_t switch_opusfile_open(switch_file_handle_t *handle, const
}
context->eof = SWITCH_FALSE;
- context->pcm_print_offset = context->pcm_offset - DEFAULT_RATE;
+ // context->pcm_print_offset = context->pcm_offset - DEFAULT_RATE;
+ context->pcm_print_offset = context->pcm_offset - handle->samplerate;
context->bitrate = 0;
context->buffer_seconds = 1;
@@ -463,7 +607,6 @@ static switch_status_t switch_opusfile_write(switch_file_handle_t *handle, void
#ifdef HAVE_OPUSFILE_ENCODE
size_t nsamples = *len;
int err;
- int mapping_family = 0;
opus_file_context *context;
@@ -476,17 +619,10 @@ static switch_status_t switch_opusfile_write(switch_file_handle_t *handle, void
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error no context\n");
return SWITCH_STATUS_FALSE;
}
- if (!context->comments) {
- context->comments = ope_comments_create();
- ope_comments_add(context->comments, "METADATA", "Freeswitch/mod_opusfile");
- }
- if (context->channels > 2) {
- mapping_family = 1;
- }
- if (!context->enc) {
- context->enc = ope_encoder_create_file(handle->file_path, context->comments, handle->samplerate, handle->channels, mapping_family, &err);
- if (!context->enc) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open file for writing. err: [%d] [%s]\n", err, ope_strerror(err));
+
+ if(!context->enc) {
+ if(opus_obj_init_secondary(context) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error initializing the opus encoder context object.\n");
return SWITCH_STATUS_FALSE;
}
}
@@ -511,7 +647,37 @@ static switch_status_t switch_opusfile_write(switch_file_handle_t *handle, void
static switch_status_t switch_opusfile_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string)
{
- return SWITCH_STATUS_FALSE;
+ opus_file_context *context = handle->private_info;
+
+ if (!context->comments) {
+ context->comments = ope_comments_create();
+ }
+
+ switch (col) {
+ case SWITCH_AUDIO_COL_STR_TITLE:
+ ope_comments_add(context->comments,"TITLE", string);
+ break;
+ case SWITCH_AUDIO_COL_STR_COMMENT:
+ ope_comments_add(context->comments,"COMMENT", string);
+ break;
+ case SWITCH_AUDIO_COL_STR_ARTIST:
+ ope_comments_add(context->comments,"ARTIST", string);
+ break;
+ case SWITCH_AUDIO_COL_STR_DATE:
+ ope_comments_add(context->comments,"DATE", string);
+ break;
+ case SWITCH_AUDIO_COL_STR_SOFTWARE:
+ ope_comments_add(context->comments,"ENCODER", string);
+ break;
+ case SWITCH_AUDIO_COL_STR_COPYRIGHT:
+ ope_comments_add(context->comments,"COPYRIGHT", string);
+ break;
+ default:
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Value Ignored %d, %s\n", col, string);
+ break;
+ }
+
+ return SWITCH_STATUS_SUCCESS;
}
static switch_status_t switch_opusfile_get_string(switch_file_handle_t *handle, switch_audio_col_t col, const char **string)
@@ -754,19 +920,19 @@ static switch_status_t switch_opusstream_init(switch_codec_t *codec, switch_code
}
#ifdef HAVE_OPUSFILE_ENCODE
if (encoding) {
- if (!context->comments) {
- context->comments = ope_comments_create();
- ope_comments_add(context->comments, "METADATA", "Freeswitch/mod_opusfile");
- }
if (!context->enc) {
- int mapping_family = 0;
+ opus_int32 i;
+ int mapping_family;
// opus_multistream_surround_encoder_get_size() in libopus will check these
- if ((context->enc_channels > 2) && (context->enc_channels <= 8)) {
- mapping_family = 1;
- } else if ((context->enc_channels > 8) && (context->enc_channels <= 255)) {
- // multichannel/multistream mapping family . https://people.xiph.org/~giles/2013/draft-ietf-codec-oggopus.html#rfc.section.5.1.1
+ // 2024-01-02 current opus-tools git head introduced logic for additional channel modes
+ if(globals.channels_format == CHANNELS_FORMAT_AMBIX) {
+ mapping_family = (context->enc_channels >= 4 && context->enc_channels <= 18) ? 3 : 2;
+ } else if(globals.channels_format == CHANNELS_FORMAT_DISCRETE) {
mapping_family = 255;
+ } else {
+ mapping_family = context->enc_channels > 8 ? 255 : context->enc_channels > 2;
}
+
context->enc = ope_encoder_create_pull(context->comments, !context->samplerate?DEFAULT_RATE:context->samplerate, !context->enc_channels?1:context->enc_channels, mapping_family, &err);
if (!context->enc) {
@@ -776,8 +942,35 @@ static switch_status_t switch_opusstream_init(switch_codec_t *codec, switch_code
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "[OGG/OPUS Stream Encode] Stream opened for encoding\n");
}
- ope_encoder_ctl(context->enc, OPUS_SET_COMPLEXITY_REQUEST, 5);
+ // ope_encoder_ctl(context->enc, OPUS_SET_COMPLEXITY_REQUEST, 5);
ope_encoder_ctl(context->enc, OPUS_SET_APPLICATION_REQUEST, OPUS_APPLICATION_VOIP);
+
+ // Let's set the bitrate and complexity, shall we?
+ switch(context->samplerate) {
+ case 32000:
+ i = 2;
+ break;
+ case 16000:
+ i = 1;
+ break;
+ case 8000:
+ i = 0;
+ break;
+ case 48000:
+ default:
+ i = 3;
+ }
+
+ err = ope_encoder_ctl(context->enc, OPUS_SET_BITRATE_REQUEST, globals.bitrate[i] * context->enc_channels);
+ if(err != OPE_OK) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to properly set the bitrate. err: [%d] [%s]\n", err, ope_strerror(err));
+ }
+
+ // err = ope_encoder_ctl(context->enc, OPUS_SET_COMPLEXITY(globals.complexity));
+ err = ope_encoder_ctl(context->enc, OPUS_SET_COMPLEXITY_REQUEST, globals.complexity);
+ if(err != OPE_OK) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to properly set the complexity. err: [%d] [%s]\n", err, ope_strerror(err));
+ }
}
}
#endif
@@ -1141,12 +1334,112 @@ end:
return status;
}
+/* Load config */
+static switch_status_t opusfile_load_config(switch_bool_t reload)
+{
+ const char *channels_format_str = "Discrete mode";
+ char *cf = "opusfile.conf";
+ switch_xml_t cfg, xml = NULL, param, settings;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+ 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 SWITCH_STATUS_FALSE;;
+ }
+
+ /* Set sane defaults */
+ globals.bitrate[0] = 12000; // Narrowband (8000 Hz) Values from rfc 6716 sec 2.1.1 (except UWB)
+ globals.bitrate[1] = 20000; // Wideband (16000 Hz)
+ globals.bitrate[2] = 36000; // Ultra wideband (32000 Hz), improvised value
+ globals.bitrate[3] = 40000; // Full band (48000 Hz)
+ globals.complexity = 10;
+ globals.channels_format = CHANNELS_FORMAT_DISCRETE;
+ globals.maximum_samplerate = 48000; // The default will be max possible
+
+ 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, "bitrate-nb") && !zstr(val)) {
+ int temp_bitrate = atoi(val);
+ if(temp_bitrate >= 6 && temp_bitrate <= 255) {
+ globals.bitrate[0] = (opus_int32) temp_bitrate * 1000;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "The bitrate per channel must be between 6 and 255 kbps. You set %d kbps. Forcing 12 kbps for narrowband.\n", temp_bitrate);
+ }
+ } else if (!strcasecmp(key, "bitrate-wb") && !zstr(val)) {
+ int temp_bitrate = atoi(val);
+ if(temp_bitrate >= 6 && temp_bitrate <= 255) {
+ globals.bitrate[1] = (opus_int32) temp_bitrate * 1000;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "The bitrate per channel must be between 6 and 255 kbps. You set %d kbps. Forcing 20 kbps for wideband.\n", temp_bitrate);
+ }
+ } else if (!strcasecmp(key, "bitrate-uwb") && !zstr(val)) {
+ int temp_bitrate = atoi(val);
+ if(temp_bitrate >= 6 && temp_bitrate <= 255) {
+ globals.bitrate[2] = (opus_int32) temp_bitrate * 1000;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "The bitrate per channel must be between 6 and 255 kbps. You set %d kbps. Forcing 36 kbps for ultrawideband.\n", temp_bitrate);
+ }
+ } else if (!strcasecmp(key, "bitrate-fb") && !zstr(val)) {
+ int temp_bitrate = atoi(val);
+ if(temp_bitrate >= 6 && temp_bitrate <= 255) {
+ globals.bitrate[3] = (opus_int32) temp_bitrate * 1000;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "The bitrate per channel must be between 6 and 255 kbps. You set %d kbps. Forcing 40 kbps for fullband.\n", temp_bitrate);
+ }
+ } else if (!strcasecmp(key, "complexity")) {
+ int temp_complexity = atoi(val);
+ if(temp_complexity >= 0 && temp_complexity < 11) {
+ globals.complexity = temp_complexity;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "opusfile complexity must be between 0-10, you set %d which is out of range. Setting value to 10.\n", temp_complexity);
+ }
+ } else if (!strcasecmp(key, "maximum-samplerate")) {
+ int temp_max_samplerate = atoi(val);
+ if(temp_max_samplerate == 8 || temp_max_samplerate == 16 || temp_max_samplerate == 32 || temp_max_samplerate == 48) {
+ globals.maximum_samplerate = temp_max_samplerate * 1000;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "FreeSWITCH only supports samplerates of 8, 16, 32, or 48 kHz. %d kHz is not a valid samplerate. Setting value to 48 kHz.\n", temp_max_samplerate);
+ }
+ } else if (!strcasecmp(key, "channel-format")) {
+ if(!strcasecmp(val, "default")) {
+ globals.channels_format = CHANNELS_FORMAT_DEFAULT;
+ channels_format_str = "Default mode";
+ } else if(!strcasecmp(val, "ambix")) {
+ globals.channels_format = CHANNELS_FORMAT_AMBIX;
+ channels_format_str = "Ambix mode";
+ } else if(!strcasecmp(val, "discrete")) {
+ globals.channels_format = CHANNELS_FORMAT_DISCRETE;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is not a known channels format. Using Discrete.", val);
+ }
+ }
+ }
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Runtime configuration parameters:\n\tNarrowband bitrate:\t\t%d kbps\n\tWideband bitrate:\t\t%d kbps\n\tUltrawideband bitrate:\t\t%d kbps\n\tFullband bitrate:\t\t%d kbps\n\tComplexity:\t\t\t%d\n\tChannels format:\t\t%s\n\tGlobal max sample rate:\t\t%lu kHz\n", globals.bitrate[0]/1000, globals.bitrate[1]/1000, globals.bitrate[2]/1000, globals.bitrate[3]/1000, globals.complexity, channels_format_str, globals.maximum_samplerate / 1000);
+
+#ifdef HAVE_OPUSFILE_ENCODE
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opusfile encoding enabled.\n");
+#else
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opusfile encoding not built in. Install libopusenc and then recompile mod_opusfile to enable.\n");
+#endif
+
+ switch_xml_free(xml);
+
+ return status;
+}
+
+
/* Registration */
static char *supported_formats[SWITCH_MAX_CODECS] = { 0 };
SWITCH_MODULE_LOAD_FUNCTION(mod_opusfile_load)
{
+ switch_status_t status;
switch_file_interface_t *file_interface;
switch_api_interface_t *commands_api_interface;
switch_codec_interface_t *codec_interface;
@@ -1154,6 +1447,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opusfile_load)
int RATES[] = {8000, 16000, 24000, 48000};
int i;
+ if ((status = opusfile_load_config(SWITCH_FALSE)) != SWITCH_STATUS_SUCCESS) {
+ return status;
+ }
+
supported_formats[0] = "opus";
*module_interface = switch_loadable_module_create_module_interface(pool, modname);