[mod_opusfile] fix play sample rate (don't use original rate, always use 48k), fix EOF, add unit-test.

This commit is contained in:
Dragos Oancea 2020-01-25 16:42:07 +00:00 committed by Andrey Volk
parent c39a2b11ce
commit 0ec6ec10ae
5 changed files with 176 additions and 8 deletions

View File

@ -1,15 +1,30 @@
include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_opusfile
noinst_LTLIBRARIES = libopusfilemod.la
libopusfilemod_la_SOURCES = mod_opusfile.c
libopusfilemod_la_CFLAGS = $(AM_CFLAGS) $(freeswitch_LDFLAGS) $(OPUSFILE_DECODE_CFLAGS)
mod_LTLIBRARIES = mod_opusfile.la
mod_opusfile_la_SOURCES = mod_opusfile.c
mod_opusfile_la_CFLAGS = $(AM_CFLAGS)
mod_opusfile_la_LIBADD = $(switch_builddir)/libfreeswitch.la
mod_opusfile_la_SOURCES =
mod_opusfile_la_CFLAGS = $(AM_CFLAGS) $(freeswitch_LDFLAGS) $(OPUSFILE_DECODE_CFLAGS)
mod_opusfile_la_LIBADD = libopusfilemod.la $(switch_builddir)/libfreeswitch.la
mod_opusfile_la_LDFLAGS = -avoid-version -module -no-undefined -shared
if HAVE_OPUSFILE_DECODE
mod_opusfile_la_CFLAGS += $(OPUSFILE_DECODE_CFLAGS)
mod_opusfile_la_LIBADD += $(OPUSFILE_DECODE_LIBS)
noinst_PROGRAMS = test/test_opusfile
test_test_opusfile_SOURCES = test/test_opusfile.c
test_test_opusfile_CFLAGS = $(AM_CFLAGS) -I./ -I../ -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\" $(OPUSFILE_DECODE_CFLAGS)
test_test_opusfile_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) $(OPUSFILE_DECODE_LIBS)
test_test_opusfile_LDADD = libopusfilemod.la $(switch_builddir)/libfreeswitch.la
TESTS = $(noinst_PROGRAMS)
endif
if HAVE_OPUSFILE_ENCODE

View File

@ -148,7 +148,7 @@ static switch_status_t switch_opusfile_decode(opus_file_context *context, void *
if (globals.debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[OGG/OPUS Decoder]: EOF reached [%d]\n", ret);
}
context->eof = TRUE;
context->eof = SWITCH_TRUE;
break;
} else /* (ret > 0)*/ {
/*The number of samples read per channel on success*/
@ -161,7 +161,6 @@ static switch_status_t switch_opusfile_decode(opus_file_context *context, void *
}
}
switch_mutex_unlock(context->audio_mutex);
context->eof = FALSE; // for next page
return SWITCH_STATUS_SUCCESS;
}
@ -266,6 +265,8 @@ static switch_status_t switch_opusfile_open(switch_file_handle_t *handle, const
if(context->pcm_offset!=0){
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[OGG/OPUS File] Non-zero starting PCM offset: [%li]\n", (long)context->pcm_offset);
}
context->eof = SWITCH_FALSE;
context->pcm_print_offset = context->pcm_offset - DEFAULT_RATE;
context->bitrate = 0;
context->buffer_seconds = 1;
@ -282,7 +283,6 @@ static switch_status_t switch_opusfile_open(switch_file_handle_t *handle, const
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "[OGG/OPUS File] Channels: %i\n", head->channel_count);
if (head->input_sample_rate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "[OGG/OPUS File] Original sampling rate: %lu Hz\n", (unsigned long)head->input_sample_rate);
handle->samplerate = context->samplerate = head->input_sample_rate;
}
}
if (op_seekable(context->of)) {
@ -365,20 +365,29 @@ static switch_status_t switch_opusfile_read(switch_file_handle_t *handle, void *
if (!handle->handler) {
if (switch_opusfile_decode(context, data, bytes, handle->real_channels) == SWITCH_STATUS_FALSE) {
context->eof = 1;
context->eof = SWITCH_TRUE;
}
}
switch_mutex_lock(context->audio_mutex);
rb = switch_buffer_read(context->audio_buffer, data, bytes);
switch_mutex_unlock(context->audio_mutex);
if (globals.debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[OGG/OPUS File] rb: [%lu] bytes: [%lu]\n", rb, bytes);
}
if (!rb && (context->eof)) {
if (globals.debug) {
// should be same as returned by op_pcm_total()
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[OGG/OPUS File] EOF. sample count: [%lu]\n", handle->sample_count);
}
*len = 0;
return SWITCH_STATUS_FALSE;
}
if (rb) {
*len = rb / sizeof(int16_t) / handle->real_channels;
if (globals.debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[OGG/OPUS File] rb: [%d] *len: [%d]\n", (int)rb, (int)*len);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "[OGG/OPUS File] rb: [%lu] *len: [%lu]\n", rb, *len);
}
} else {
newbytes = (2 * handle->samplerate * handle->real_channels) * context->buffer_seconds;

View File

@ -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_opusfile"/>
</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>

Binary file not shown.

View File

@ -0,0 +1,123 @@
/*
* 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_opusfile.c -- tests mod_opusfile
*
*/
#include <switch.h>
#include <stdlib.h>
#include <test/switch_test.h>
FST_CORE_BEGIN(".")
{
FST_SUITE_BEGIN(test_opusfile)
{
FST_SETUP_BEGIN()
{
fst_requires_module("mod_loopback");
fst_requires_module("mod_opusfile");
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(opusfile_read)
{
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
switch_status_t status;
switch_call_cause_t cause;
/*
$ mediainfo hi.opus
General
Complete name : hi.opus
Format : OGG
File size : 8.55 KiB
Duration : 2s 157ms
Overall bit rate : 32.5 Kbps
Writing application : opusenc from opus-tools 0.1.10
Audio
ID : 277454932 (0x1089A054)
Format : Opus
Duration : 2s 157ms
Channel(s) : 1 channel
Channel positions : Front: C
Sampling rate : 16.0 KHz
Compression mode : Lossy
Writing library : libopus 1.2~alpha2
*/
static char filename[] = "sounds/hi.opus"; // duration in samples: 103200
char path[4096];
switch_file_handle_t fh = { 0 };
int16_t *audiobuf;
switch_size_t len;
sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, filename);
status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session);
fst_check(status == SWITCH_STATUS_SUCCESS);
status = switch_core_file_open(&fh, path, 1, 48000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
fst_check(status == SWITCH_STATUS_SUCCESS);
len = 128 * 1024 * sizeof(*audiobuf);
switch_zmalloc(audiobuf, len);
status = switch_core_file_read(&fh, audiobuf, &len);
fst_check(status == SWITCH_STATUS_SUCCESS);
/* [INFO] mod_opusfile.c:292 [OGG/OPUS File] Duration (samples): 103200 */
/* compare the read sample count with the one in the OGG/OPUS header. */
fst_check(len == 103200);
status = switch_core_file_close(&fh);
fst_check(status == SWITCH_STATUS_SUCCESS);
switch_safe_free(audiobuf);
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()