[mod_sndfile] fix playing "raw" and other formats ("r8", "r16", "r24", "r32"), add unit-test
[mod_sndfile] add stereo to mono support for file formats that need it (eg: gsm, vox), add unit test for stereo [mod_sndfile] mono to stereo and stereo to mono unit tests. [unit-tests] mod_sndfile: don't wait for recording file to be flushed to disk by the core, use switch_ivr_stop_record_session() [mod_sndfile] fix format "wve" (Psion Series 3) [mod_sndfile] fix format "htk" (Hidden Markov Model Tool Kit) [mod_sndfile] fix file format "iff" (AIFF) [mod_sndfile] fix file format "xi" (FastTracker 2) [mod_sndfile] fix file format "sds" (Midi Sample Dump Standard) [uni-tests] add more audio file extensions to sndfile unit tests. [mod_sndfile] add config file support (with one param currently: "allowed-extensions") [mod_sndfile] add sample file sndfile.conf.xml to 'testing' and 'vanilla' cfg trees. [mod_sndfile] free() cfg xml [unit-tests] mod_sndfile: unload module test. [unit-tests] mod_sndfile: add conf file unit-test (param that allows only certain file extensions) [unit-tests] adjusts Makefile.am for new CI (tests) [unit-tests] adjust path to sound file. [unit-tests] [mod_sndfile] remove Makefile.am from test/ [unit-tests] [mod_sndfile] fix build (Andrey)
This commit is contained in:
parent
78c7dd2a37
commit
08317fc5c3
|
@ -0,0 +1,9 @@
|
|||
<configuration name="sndfile.conf">
|
||||
<settings>
|
||||
<!-- Allow only these file extensions. Default: allow all sndfile provided extensions + FS custom extra -->
|
||||
<!--
|
||||
<param name="allowed-extensions" value="wav,raw,r8,r16"/>
|
||||
-->
|
||||
</settings>
|
||||
</configuration>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<configuration name="sndfile.conf">
|
||||
<settings>
|
||||
<!-- Allow only these file extensions. Default: allow all sndfile provided extensions + FS custom extra -->
|
||||
<!--
|
||||
<param name="allowed-extensions" value="wav,raw,r8,r16"/>
|
||||
-->
|
||||
</settings>
|
||||
</configuration>
|
||||
|
|
@ -3,12 +3,30 @@ MODNAME=mod_sndfile
|
|||
|
||||
if HAVE_SNDFILE
|
||||
|
||||
noinst_LTLIBRARIES = libsndfilemod.la
|
||||
libsndfilemod_la_SOURCES = mod_sndfile.c
|
||||
libsndfilemod_la_CFLAGS = $(AM_CFLAGS) $(SNDFILE_CFLAGS)
|
||||
|
||||
mod_LTLIBRARIES = mod_sndfile.la
|
||||
mod_sndfile_la_SOURCES = mod_sndfile.c
|
||||
mod_sndfile_la_SOURCES =
|
||||
mod_sndfile_la_CFLAGS = $(AM_CFLAGS) $(SNDFILE_CFLAGS)
|
||||
mod_sndfile_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SNDFILE_LIBS)
|
||||
mod_sndfile_la_LIBADD = libsndfilemod.la $(switch_builddir)/libfreeswitch.la $(SNDFILE_LIBS)
|
||||
mod_sndfile_la_LDFLAGS = -avoid-version -module -no-undefined -shared
|
||||
|
||||
noinst_PROGRAMS = test/test_sndfile test/test_sndfile_conf
|
||||
|
||||
test_test_sndfile_SOURCES = test/test_sndfile.c
|
||||
test_test_sndfile_CFLAGS = $(AM_CFLAGS) -I./ -I../ -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\"
|
||||
test_test_sndfile_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
|
||||
test_test_sndfile_LDADD = libsndfilemod.la
|
||||
|
||||
test_test_sndfile_conf_SOURCES = test/test_sndfile_conf.c
|
||||
test_test_sndfile_conf_CFLAGS = $(AM_CFLAGS) -I./ -I../ -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\"
|
||||
test_test_sndfile_conf_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
|
||||
test_test_sndfile_conf_LDADD = libsndfilemod.la
|
||||
|
||||
TESTS = $(noinst_PROGRAMS)
|
||||
|
||||
else
|
||||
install: error
|
||||
all: error
|
||||
|
|
|
@ -39,6 +39,9 @@ SWITCH_MODULE_DEFINITION(mod_sndfile, mod_sndfile_load, mod_sndfile_shutdown, NU
|
|||
|
||||
static struct {
|
||||
switch_hash_t *format_hash;
|
||||
int debug;
|
||||
char *allowed_extensions[100];
|
||||
int allowed_extensions_count;
|
||||
} globals;
|
||||
|
||||
struct format_map {
|
||||
|
@ -56,6 +59,16 @@ typedef struct sndfile_context sndfile_context;
|
|||
|
||||
static switch_status_t sndfile_perform_open(sndfile_context *context, const char *path, int mode, switch_file_handle_t *handle);
|
||||
|
||||
static void reverse_channel_count(switch_file_handle_t *handle) {
|
||||
/* for recording stereo conferences and stereo calls in audio file formats that support only 1 channel.
|
||||
* "{force_channels=1}" does similar, but here switch_core_open_file() was already called and we
|
||||
* have the handle and we chane the count before _read_ or _write_ are called (where muxing is done). */
|
||||
if (handle->channels > 1) {
|
||||
handle->real_channels = handle->channels;
|
||||
handle->channels = handle->mm.channels = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const char *path)
|
||||
{
|
||||
sndfile_context *context;
|
||||
|
@ -119,41 +132,107 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha
|
|||
|
||||
if (!strcmp(ext, "raw")) {
|
||||
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
|
||||
if (mode & SFM_READ) {
|
||||
context->sfinfo.samplerate = 8000;
|
||||
context->sfinfo.channels = 1;
|
||||
}
|
||||
} else if (!strcmp(ext, "r8")) {
|
||||
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
|
||||
context->sfinfo.samplerate = 8000;
|
||||
if (mode & SFM_READ) {
|
||||
context->sfinfo.samplerate = 8000;
|
||||
context->sfinfo.channels = 1;
|
||||
}
|
||||
} else if (!strcmp(ext, "r16")) {
|
||||
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
|
||||
context->sfinfo.samplerate = 16000;
|
||||
if (mode & SFM_READ) {
|
||||
context->sfinfo.samplerate = 16000;
|
||||
context->sfinfo.channels = 1;
|
||||
}
|
||||
} else if (!strcmp(ext, "r24")) {
|
||||
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_24;
|
||||
context->sfinfo.samplerate = 24000;
|
||||
if (mode & SFM_READ) {
|
||||
context->sfinfo.samplerate = 24000;
|
||||
context->sfinfo.channels = 1;
|
||||
}
|
||||
} else if (!strcmp(ext, "r32")) {
|
||||
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_32;
|
||||
context->sfinfo.samplerate = 32000;
|
||||
if (mode & SFM_READ) {
|
||||
context->sfinfo.samplerate = 32000;
|
||||
context->sfinfo.channels = 1;
|
||||
}
|
||||
} else if (!strcmp(ext, "gsm")) {
|
||||
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_GSM610;
|
||||
context->sfinfo.channels = 1;
|
||||
if (mode & SFM_WRITE) {
|
||||
reverse_channel_count(handle);
|
||||
}
|
||||
context->sfinfo.samplerate = 8000;
|
||||
} else if (!strcmp(ext, "ul") || !strcmp(ext, "ulaw")) {
|
||||
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_ULAW;
|
||||
context->sfinfo.channels = 1;
|
||||
context->sfinfo.samplerate = 8000;
|
||||
if (mode & SFM_READ) {
|
||||
context->sfinfo.samplerate = 8000;
|
||||
context->sfinfo.channels = 1;
|
||||
}
|
||||
} else if (!strcmp(ext, "al") || !strcmp(ext, "alaw")) {
|
||||
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_ALAW;
|
||||
context->sfinfo.channels = 1;
|
||||
context->sfinfo.samplerate = 8000;
|
||||
if (mode & SFM_READ) {
|
||||
context->sfinfo.samplerate = 8000;
|
||||
context->sfinfo.channels = 1;
|
||||
}
|
||||
} else if (!strcmp(ext, "vox")) {
|
||||
context->sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM;
|
||||
context->sfinfo.channels = 1;
|
||||
context->sfinfo.samplerate = 8000;
|
||||
if (mode & SFM_WRITE) {
|
||||
reverse_channel_count(handle);
|
||||
}
|
||||
} else if (!strcmp(ext, "adpcm")) {
|
||||
context->sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM;
|
||||
context->sfinfo.channels = 1;
|
||||
context->sfinfo.samplerate = 8000;
|
||||
if (mode & SFM_WRITE) {
|
||||
reverse_channel_count(handle);
|
||||
}
|
||||
} else if (!strcmp(ext, "oga") || !strcmp(ext, "ogg")) {
|
||||
context->sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
|
||||
context->sfinfo.samplerate = handle->samplerate;
|
||||
if (mode & SFM_READ) {
|
||||
context->sfinfo.samplerate = handle->samplerate;
|
||||
}
|
||||
} else if (!strcmp(ext, "wve")) {
|
||||
context->sfinfo.format = SF_FORMAT_WVE | SF_FORMAT_ALAW;
|
||||
context->sfinfo.channels = 1;
|
||||
context->sfinfo.samplerate = 8000;
|
||||
if (mode & SFM_WRITE) {
|
||||
reverse_channel_count(handle);
|
||||
}
|
||||
} else if (!strcmp(ext, "htk")) {
|
||||
context->sfinfo.format = SF_FORMAT_HTK | SF_FORMAT_PCM_16;
|
||||
context->sfinfo.channels = 1;
|
||||
context->sfinfo.samplerate = 8000;
|
||||
if (mode & SFM_WRITE) {
|
||||
reverse_channel_count(handle);
|
||||
}
|
||||
} else if (!strcmp(ext, "iff")) {
|
||||
context->sfinfo.format = SF_FORMAT_AIFF | SF_FORMAT_PCM_16;
|
||||
context->sfinfo.channels = 1;
|
||||
context->sfinfo.samplerate = 8000;
|
||||
if (mode & SFM_WRITE) {
|
||||
reverse_channel_count(handle);
|
||||
}
|
||||
} else if (!strcmp(ext, "xi")) {
|
||||
context->sfinfo.format = SF_FORMAT_XI | SF_FORMAT_DPCM_16;
|
||||
context->sfinfo.channels = 1;
|
||||
context->sfinfo.samplerate = 44100;
|
||||
if (mode & SFM_WRITE) {
|
||||
reverse_channel_count(handle);
|
||||
}
|
||||
} else if (!strcmp(ext, "sds")) {
|
||||
context->sfinfo.format = SF_FORMAT_SDS | SF_FORMAT_PCM_16;
|
||||
context->sfinfo.channels = 1;
|
||||
context->sfinfo.samplerate = 8000;
|
||||
if (mode & SFM_WRITE) {
|
||||
reverse_channel_count(handle);
|
||||
}
|
||||
}
|
||||
|
||||
if ((mode & SFM_WRITE) && sf_format_check(&context->sfinfo) == 0) {
|
||||
|
@ -204,7 +283,10 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha
|
|||
goto end;
|
||||
}
|
||||
}
|
||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opening File [%s] rate %dhz\n", path, context->sfinfo.samplerate);
|
||||
if (globals.debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
||||
"Opening File [%s] rate [%dhz] channels: [%d]\n", path, context->sfinfo.samplerate, (uint8_t) context->sfinfo.channels);
|
||||
}
|
||||
handle->samples = (unsigned int) context->sfinfo.frames;
|
||||
handle->samplerate = context->sfinfo.samplerate;
|
||||
handle->channels = (uint8_t) context->sfinfo.channels;
|
||||
|
@ -365,6 +447,20 @@ static switch_status_t sndfile_file_get_string(switch_file_handle_t *handle, swi
|
|||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
static switch_bool_t exten_is_allowed(const char *exten) {
|
||||
int i;
|
||||
if (!globals.allowed_extensions[0]) {
|
||||
// defaults to allowing all extensions if param "allowed-extensions" not set in cfg
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
for (i = 0 ; i < globals.allowed_extensions_count; i++) {
|
||||
if (exten && globals.allowed_extensions[i] && !strcasecmp(globals.allowed_extensions[i], exten)) {
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
}
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
/* Registration */
|
||||
|
||||
static char **supported_formats;
|
||||
|
@ -407,6 +503,9 @@ static switch_status_t setup_formats(switch_memory_pool_t *pool)
|
|||
skip = 0;
|
||||
info.format = m;
|
||||
sf_command(NULL, SFC_GET_FORMAT_MAJOR, &info, sizeof(info));
|
||||
if (!exten_is_allowed(info.extension)) {
|
||||
continue;
|
||||
}
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s (extension \"%s\")\n", info.name, info.extension);
|
||||
for (x = 0; x < len; x++) {
|
||||
if (supported_formats[x] == info.extension) {
|
||||
|
@ -470,7 +569,9 @@ static switch_status_t setup_formats(switch_memory_pool_t *pool)
|
|||
}
|
||||
}
|
||||
for (m = 0; m < exlen; m++) {
|
||||
supported_formats[len++] = extras[m];
|
||||
if (exten_is_allowed(extras[m])) {
|
||||
supported_formats[len++] = extras[m];
|
||||
}
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_NOTICE, "================================================================================\n");
|
||||
|
@ -478,12 +579,49 @@ static switch_status_t setup_formats(switch_memory_pool_t *pool)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define SNDFILE_DEBUG_SYNTAX "<on|off>"
|
||||
SWITCH_STANDARD_API(mod_sndfile_debug)
|
||||
{
|
||||
if (zstr(cmd)) {
|
||||
stream->write_function(stream, "-USAGE: %s\n", SNDFILE_DEBUG_SYNTAX);
|
||||
} else {
|
||||
if (!strcasecmp(cmd, "on")) {
|
||||
globals.debug = 1;
|
||||
stream->write_function(stream, "Sndfile Debug: on\n");
|
||||
} else if (!strcasecmp(cmd, "off")) {
|
||||
globals.debug = 0;
|
||||
stream->write_function(stream, "Sndfile Debug: off\n");
|
||||
} else {
|
||||
stream->write_function(stream, "-USAGE: %s\n", SNDFILE_DEBUG_SYNTAX);
|
||||
}
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_sndfile_load)
|
||||
{
|
||||
switch_file_interface_t *file_interface;
|
||||
switch_api_interface_t *commands_api_interface;
|
||||
char *cf = "sndfile.conf";
|
||||
switch_xml_t cfg, xml, settings, param;
|
||||
|
||||
memset(&globals, 0, sizeof(globals));
|
||||
|
||||
switch_core_hash_init(&globals.format_hash);
|
||||
|
||||
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||
if ((settings = switch_xml_child(cfg, "settings"))) {
|
||||
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
|
||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
if (!strcasecmp(var, "allowed-extensions") && val) {
|
||||
globals.allowed_extensions_count = switch_separate_string(val, ',', globals.allowed_extensions, (sizeof(globals.allowed_extensions) / sizeof(globals.allowed_extensions[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
switch_xml_free(xml);
|
||||
}
|
||||
|
||||
if (setup_formats(pool) != SWITCH_STATUS_SUCCESS) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
@ -502,6 +640,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sndfile_load)
|
|||
file_interface->file_set_string = sndfile_file_set_string;
|
||||
file_interface->file_get_string = sndfile_file_get_string;
|
||||
|
||||
SWITCH_ADD_API(commands_api_interface, "sndfile_debug", "Set sndfile debug", mod_sndfile_debug, SNDFILE_DEBUG_SYNTAX);
|
||||
|
||||
switch_console_set_complete("add sndfile_debug on");
|
||||
switch_console_set_complete("add sndfile_debug off");
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,27 @@
|
|||
<document type="freeswitch/xml">
|
||||
|
||||
<section name="configuration" description="Various Configuration">
|
||||
<configuration name="modules.conf" description="Modules">
|
||||
<modules>
|
||||
<load module="mod_loopback"/>
|
||||
<load module="mod_sndfile"/>
|
||||
</modules>
|
||||
</configuration>
|
||||
<configuration name="sndfile.conf">
|
||||
<settings>
|
||||
<!-- Allow only these file extensions. Default: allow all sndfile provided extensions + FS custom extra -->
|
||||
<param name="allowed-extensions" value="wav,raw,r8,r16"/>
|
||||
</settings>
|
||||
</configuration>
|
||||
</section>
|
||||
|
||||
<section name="dialplan" description="Regex/XML Dialplan">
|
||||
<context name="default">
|
||||
<extension name="sample">
|
||||
<condition>
|
||||
<action application="info"/>
|
||||
</condition>
|
||||
</extension>
|
||||
</context>
|
||||
</section>
|
||||
</document>
|
|
@ -0,0 +1,27 @@
|
|||
<document type="freeswitch/xml">
|
||||
|
||||
<section name="configuration" description="Various Configuration">
|
||||
<configuration name="modules.conf" description="Modules">
|
||||
<modules>
|
||||
<load module="mod_loopback"/>
|
||||
<load module="mod_sndfile"/>
|
||||
</modules>
|
||||
</configuration>
|
||||
<configuration name="sndfile.conf">
|
||||
<settings>
|
||||
<!-- Allow only these file extensions. Default: allow all sndfile provided extensions + FS custom extra -->
|
||||
<param name="allowed-extensions" value="wav,raw,r8,r16"/>
|
||||
</settings>
|
||||
</configuration>
|
||||
</section>
|
||||
|
||||
<section name="dialplan" description="Regex/XML Dialplan">
|
||||
<context name="default">
|
||||
<extension name="sample">
|
||||
<condition>
|
||||
<action application="info"/>
|
||||
</condition>
|
||||
</extension>
|
||||
</context>
|
||||
</section>
|
||||
</document>
|
|
@ -0,0 +1,21 @@
|
|||
<document type="freeswitch/xml">
|
||||
|
||||
<section name="configuration" description="Various Configuration">
|
||||
<configuration name="modules.conf" description="Modules">
|
||||
<modules>
|
||||
<load module="mod_loopback"/>
|
||||
<load module="mod_sndfile"/>
|
||||
</modules>
|
||||
</configuration>
|
||||
</section>
|
||||
|
||||
<section name="dialplan" description="Regex/XML Dialplan">
|
||||
<context name="default">
|
||||
<extension name="sample">
|
||||
<condition>
|
||||
<action application="info"/>
|
||||
</condition>
|
||||
</extension>
|
||||
</context>
|
||||
</section>
|
||||
</document>
|
|
@ -0,0 +1,451 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2018, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* 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 <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dragos Oancea <dragos@signalwire.com>
|
||||
*
|
||||
* test_sndfile.c -- tests mod_sndfile
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <test/switch_test.h>
|
||||
|
||||
/* Media files used:
|
||||
*
|
||||
* 1. hi.wav
|
||||
*
|
||||
* General
|
||||
* Complete name : test/sounds/hi.wav
|
||||
* Format : Wave
|
||||
* File size : 67.2 KiB
|
||||
* Duration : 2 s 150 ms
|
||||
* Overall bit rate mode : Constant
|
||||
* Overall bit rate : 256 kb/s
|
||||
*
|
||||
* Audio
|
||||
* Format : PCM
|
||||
* Format settings, Endianness : Little
|
||||
* Format settings, Sign : Signed
|
||||
* Codec ID : 1
|
||||
* Duration : 2 s 150 ms
|
||||
* Bit rate mode : Constant
|
||||
* Bit rate : 256 kb/s
|
||||
* Channel(s) : 1 channel
|
||||
* Sampling rate : 16.0 kHz
|
||||
* Bit depth : 16 bits
|
||||
* Stream size : 67.2 KiB (100%)
|
||||
*
|
||||
*
|
||||
* 2. hello_stereo.wav
|
||||
*
|
||||
*
|
||||
* General
|
||||
* Complete name : sounds/hello_stereo.wav
|
||||
* Format : Wave
|
||||
* File size : 220 KiB
|
||||
* Duration : 1 s 277 ms
|
||||
* Overall bit rate mode : Constant
|
||||
* Overall bit rate : 1 412 kb/s
|
||||
*
|
||||
* Audio
|
||||
* Format : PCM
|
||||
* Format settings, Endianness : Little
|
||||
* Format settings, Sign : Signed
|
||||
* Codec ID : 1
|
||||
* Duration : 1 s 277 ms
|
||||
* Bit rate mode : Constant
|
||||
* Bit rate : 1 411.2 kb/s
|
||||
* Channel(s) : 2 channels
|
||||
* Sampling rate : 44.1 kHz
|
||||
* Bit depth : 16 bits
|
||||
* Stream size : 220 KiB (100%)
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
char *extensions[] = {
|
||||
"aiff", "au", "avr", "caf",
|
||||
"flac", "htk", "iff", "mat",
|
||||
"mpc", "paf", "pvf", "rf64",
|
||||
"sd2", "sds", "sf", "voc",
|
||||
"w64", "wav", "wve", "xi",
|
||||
"raw", "r8", "r16", "r24",
|
||||
"r32", "ul", "ulaw", "al",
|
||||
"alaw", "gsm", "vox", "oga", "ogg"};
|
||||
|
||||
FST_CORE_BEGIN("test_formats_and_muxing")
|
||||
{
|
||||
FST_SUITE_BEGIN(test_sndfile)
|
||||
{
|
||||
FST_SETUP_BEGIN()
|
||||
{
|
||||
fst_requires_module("mod_loopback");
|
||||
fst_requires_module("mod_sndfile");
|
||||
}
|
||||
FST_SETUP_END()
|
||||
|
||||
FST_TEARDOWN_BEGIN()
|
||||
{
|
||||
}
|
||||
FST_TEARDOWN_END()
|
||||
|
||||
FST_TEST_BEGIN(sndfile_write_read_mono)
|
||||
{
|
||||
/* play mono, record mono, open mono */
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_status_t status;
|
||||
switch_call_cause_t cause;
|
||||
static char play_filename[] = "../sounds/hi.wav";
|
||||
char path[4096];
|
||||
switch_file_handle_t fh = { 0 };
|
||||
int16_t *audiobuf;
|
||||
switch_size_t len, rd;
|
||||
char *recording;
|
||||
int i, exlen, timeout_sec = 2, duration = 3000; /*ms*/
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
|
||||
sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
|
||||
switch_api_execute("sndfile_debug", "on", session, &stream);
|
||||
|
||||
switch_safe_free(stream.data);
|
||||
|
||||
exlen = (sizeof(extensions) / sizeof(extensions[0]));
|
||||
|
||||
status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
|
||||
fst_requires(session);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
for (i = 0; i < exlen; i++) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions[i]);
|
||||
|
||||
recording = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions[i]);
|
||||
status = switch_ivr_record_session(session, recording, duration, NULL);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
status = switch_ivr_play_file(session, NULL, path, NULL);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_sleep(1000 * duration); // wait for audio to finish playing
|
||||
|
||||
switch_ivr_stop_record_session(session, "all");
|
||||
|
||||
status = switch_core_file_open(&fh, recording, 1, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
rd = 320; // samples
|
||||
len = rd * sizeof(*audiobuf);
|
||||
switch_zmalloc(audiobuf, len);
|
||||
|
||||
status = switch_core_file_read(&fh, audiobuf, &rd);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
fst_check(rd = 320); // check that we read the wanted number of samples
|
||||
|
||||
status = switch_core_file_close(&fh);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_safe_free(audiobuf);
|
||||
|
||||
unlink(recording);
|
||||
|
||||
switch_safe_free(recording);
|
||||
|
||||
switch_sleep(1000000);
|
||||
}
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
fst_requires(channel);
|
||||
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
fst_check(!switch_channel_ready(channel));
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
|
||||
FST_TEST_END()
|
||||
|
||||
FST_TEST_BEGIN(sndfile_write_read_m2s)
|
||||
{
|
||||
/* play mono file, record mono, open stereo */
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_status_t status;
|
||||
switch_call_cause_t cause;
|
||||
static char play_filename[] = "../sounds/hi.wav";
|
||||
char path[4096];
|
||||
switch_file_handle_t fh = { 0 };
|
||||
int16_t *audiobuf;
|
||||
switch_size_t len, rd;
|
||||
char *recording;
|
||||
int i, exlen, channels = 2, timeout_sec = 2, duration = 3000; /*ms*/
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
|
||||
sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
|
||||
switch_api_execute("sndfile_debug", "on", session, &stream);
|
||||
|
||||
switch_safe_free(stream.data);
|
||||
|
||||
exlen = (sizeof(extensions) / sizeof(extensions[0]));
|
||||
|
||||
for (i = 0; i < exlen; i++) {
|
||||
|
||||
status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
|
||||
fst_requires(session);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions[i]);
|
||||
|
||||
recording = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions[i]);
|
||||
|
||||
status = switch_ivr_record_session(session, recording, duration, NULL);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
status = switch_ivr_play_file(session, NULL, path, NULL);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_sleep(1000 * duration); // wait for audio to finish playing
|
||||
|
||||
switch_ivr_stop_record_session(session, "all");
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
fst_requires(channel);
|
||||
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
fst_check(!switch_channel_ready(channel));
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
|
||||
status = switch_core_file_open(&fh, recording, channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
rd = 320; // samples
|
||||
len = rd * sizeof(*audiobuf) * channels;
|
||||
switch_zmalloc(audiobuf, len);
|
||||
|
||||
status = switch_core_file_read(&fh, audiobuf, &rd);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
fst_check(rd = 320); // check that we read the wanted number of samples
|
||||
|
||||
status = switch_core_file_close(&fh);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_safe_free(audiobuf);
|
||||
|
||||
unlink(recording);
|
||||
|
||||
switch_safe_free(recording);
|
||||
|
||||
switch_sleep(1000000);
|
||||
}
|
||||
}
|
||||
FST_TEST_END()
|
||||
|
||||
FST_TEST_BEGIN(sndfile_write_read_s2m)
|
||||
{
|
||||
/* play stereo wav, record stereo, open stereo file */
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_status_t status;
|
||||
switch_call_cause_t cause;
|
||||
static char play_filename[] = "../sounds/hello_stereo.wav";
|
||||
char path[4096];
|
||||
switch_file_handle_t fh = { 0 };
|
||||
int16_t *audiobuf;
|
||||
switch_size_t len, rd;
|
||||
char *recording, *rec_path;
|
||||
int i, exlen, channels = 2, timeout_sec = 2, duration = 3000; /*ms*/
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
|
||||
sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
|
||||
switch_api_execute("sndfile_debug", "on", session, &stream);
|
||||
|
||||
switch_safe_free(stream.data);
|
||||
|
||||
exlen = (sizeof(extensions) / sizeof(extensions[0]));
|
||||
|
||||
for (i = 0; i < exlen; i++) {
|
||||
|
||||
status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
|
||||
|
||||
fst_requires(session);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions[i]);
|
||||
|
||||
rec_path = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions[i]);
|
||||
recording = switch_mprintf("{force_channels=2}%s", rec_path);
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
fst_requires(channel);
|
||||
|
||||
switch_channel_set_variable(channel, "enable_file_write_buffering", "true");
|
||||
|
||||
status = switch_ivr_record_session(session, recording, duration, NULL);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
status = switch_ivr_play_file(session, NULL, path, NULL);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_sleep(1000 * duration); // wait for audio to finish playing
|
||||
|
||||
switch_ivr_stop_record_session(session, "all");
|
||||
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
fst_check(!switch_channel_ready(channel));
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
|
||||
status = switch_core_file_open(&fh, recording, channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
rd = 320; // samples
|
||||
len = rd * sizeof(*audiobuf) * channels;
|
||||
switch_zmalloc(audiobuf, len);
|
||||
|
||||
status = switch_core_file_read(&fh, audiobuf, &rd);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
fst_check(rd = 320); // check that we read the wanted number of samples
|
||||
|
||||
status = switch_core_file_close(&fh);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_safe_free(audiobuf);
|
||||
|
||||
unlink(rec_path);
|
||||
|
||||
switch_safe_free(rec_path);
|
||||
switch_safe_free(recording);
|
||||
|
||||
switch_sleep(1000000);
|
||||
}
|
||||
}
|
||||
|
||||
FST_TEST_END()
|
||||
|
||||
FST_TEST_BEGIN(sndfile_write_read_stereo)
|
||||
{
|
||||
/* play stereo wav, record stereo, open stereo file */
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_status_t status;
|
||||
switch_call_cause_t cause;
|
||||
static char play_filename[] = "../sounds/hello_stereo.wav";
|
||||
char path[4096];
|
||||
switch_file_handle_t fh = { 0 };
|
||||
int16_t *audiobuf;
|
||||
switch_size_t len, rd;
|
||||
char *recording, *rec_path;
|
||||
int i, exlen, channels = 2, timeout_sec = 2, duration = 3000; /*ms*/
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
|
||||
sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
|
||||
switch_api_execute("sndfile_debug", "on", session, &stream);
|
||||
|
||||
switch_safe_free(stream.data);
|
||||
|
||||
exlen = (sizeof(extensions) / sizeof(extensions[0]));
|
||||
|
||||
for (i = 0; i < exlen; i++) {
|
||||
|
||||
status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
|
||||
fst_requires(session);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions[i]);
|
||||
|
||||
rec_path = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions[i]);
|
||||
recording = switch_mprintf("{force_channels=2}%s", rec_path);
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
fst_requires(channel);
|
||||
|
||||
switch_channel_set_variable(channel, "RECORD_STEREO", "true");
|
||||
switch_channel_set_variable(channel, "enable_file_write_buffering", "true");
|
||||
|
||||
status = switch_ivr_record_session(session, recording, duration, NULL);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
status = switch_ivr_play_file(session, NULL, path, NULL);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_sleep(1000 * duration); // wait for audio to finish playing
|
||||
|
||||
switch_ivr_stop_record_session(session, "all");
|
||||
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
fst_check(!switch_channel_ready(channel));
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
|
||||
status = switch_core_file_open(&fh, recording, channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
rd = 320; // samples
|
||||
len = rd * sizeof(*audiobuf) * channels;
|
||||
switch_zmalloc(audiobuf, len);
|
||||
|
||||
status = switch_core_file_read(&fh, audiobuf, &rd);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
fst_check(rd = 320); // check that we read the wanted number of samples
|
||||
|
||||
status = switch_core_file_close(&fh);
|
||||
fst_requires(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
switch_safe_free(audiobuf);
|
||||
|
||||
unlink(rec_path);
|
||||
|
||||
switch_safe_free(rec_path);
|
||||
switch_safe_free(recording);
|
||||
|
||||
switch_sleep(1000000);
|
||||
}
|
||||
}
|
||||
FST_TEST_END()
|
||||
|
||||
FST_TEST_BEGIN(unload_mod_sndfile)
|
||||
{
|
||||
const char *err = NULL;
|
||||
switch_sleep(1000000);
|
||||
fst_check(switch_loadable_module_unload_module((char *)"../.libs", (char *)"mod_sndfile", SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS);
|
||||
}
|
||||
FST_TEST_END()
|
||||
}
|
||||
FST_SUITE_END()
|
||||
}
|
||||
FST_CORE_END()
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2018, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* 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 <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dragos Oancea <dragos@signalwire.com>
|
||||
*
|
||||
* test_sndfile_conf.c -- tests mod_sndfile config
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <test/switch_test.h>
|
||||
|
||||
char *extensions_will_fail[] = { // not allowed through conf file.
|
||||
"ul", "gsm", "vox", "ogg"
|
||||
};
|
||||
|
||||
char *extensions_will_succeed[] = { // allowed through conf file.
|
||||
"wav", "raw", "r8", "r16"
|
||||
};
|
||||
|
||||
FST_CORE_BEGIN("test_conf")
|
||||
{
|
||||
FST_SUITE_BEGIN(test_sndfile)
|
||||
{
|
||||
FST_SETUP_BEGIN()
|
||||
{
|
||||
fst_requires_module("mod_loopback");
|
||||
fst_requires_module("mod_sndfile");
|
||||
}
|
||||
FST_SETUP_END()
|
||||
|
||||
FST_TEARDOWN_BEGIN()
|
||||
{
|
||||
}
|
||||
FST_TEARDOWN_END()
|
||||
|
||||
FST_TEST_BEGIN(sndfile_exten_not_allowed)
|
||||
{
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_status_t status;
|
||||
switch_call_cause_t cause;
|
||||
char *recording;
|
||||
int i, exlen, timeout_sec = 2;
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
|
||||
switch_api_execute("sndfile_debug", "on", session, &stream);
|
||||
|
||||
switch_safe_free(stream.data);
|
||||
|
||||
exlen = (sizeof(extensions_will_fail) / sizeof(extensions_will_fail[0]));
|
||||
|
||||
status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
|
||||
fst_requires(session);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
for (i = 0; i < exlen; i++) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions_will_fail[i]);
|
||||
|
||||
recording = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions_will_fail[i]);
|
||||
status = switch_ivr_record_session(session, recording, 3000, NULL);
|
||||
fst_check(status == SWITCH_STATUS_GENERR);
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
// not expected
|
||||
unlink(recording);
|
||||
}
|
||||
|
||||
switch_safe_free(recording);
|
||||
}
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
fst_requires(channel);
|
||||
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
fst_check(!switch_channel_ready(channel));
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
|
||||
switch_sleep(1000000);
|
||||
}
|
||||
FST_TEST_END()
|
||||
FST_TEST_BEGIN(sndfile_exten_allowed)
|
||||
{
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_status_t status;
|
||||
switch_call_cause_t cause;
|
||||
char *recording;
|
||||
int i, exlen, timeout_sec = 2;
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
|
||||
switch_api_execute("sndfile_debug", "on", session, &stream);
|
||||
|
||||
switch_safe_free(stream.data);
|
||||
|
||||
exlen = (sizeof(extensions_will_succeed) / sizeof(extensions_will_succeed[0]));
|
||||
|
||||
status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
|
||||
fst_requires(session);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
for (i = 0; i < exlen; i++) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions_will_succeed[i]);
|
||||
|
||||
recording = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions_will_succeed[i]);
|
||||
status = switch_ivr_record_session(session, recording, 3000, NULL);
|
||||
fst_check(status == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
unlink(recording);
|
||||
|
||||
switch_safe_free(recording);
|
||||
}
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
fst_requires(channel);
|
||||
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
fst_check(!switch_channel_ready(channel));
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
|
||||
switch_sleep(1000000);
|
||||
}
|
||||
FST_TEST_END()
|
||||
}
|
||||
FST_SUITE_END()
|
||||
}
|
||||
FST_CORE_END()
|
Loading…
Reference in New Issue