forked from Mirrors/freeswitch
sample platter
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6706 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
2ff5e3ec40
commit
44636d333f
@ -40,6 +40,7 @@
|
||||
#define SWITCH_MODULE_INTERFACES_H
|
||||
|
||||
#include <switch.h>
|
||||
#include "switch_resample.h"
|
||||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
/*! \brief A table of functions to execute at various states
|
||||
@ -262,6 +263,8 @@ struct switch_file_handle {
|
||||
unsigned int samples;
|
||||
/*! the current samplerate */
|
||||
uint32_t samplerate;
|
||||
/*! the current native samplerate */
|
||||
uint32_t native_rate;
|
||||
/*! the number of channels */
|
||||
uint8_t channels;
|
||||
/*! integer representation of the format */
|
||||
@ -289,6 +292,10 @@ struct switch_file_handle {
|
||||
uint32_t offset_pos;
|
||||
uint32_t last_pos;
|
||||
int32_t vol;
|
||||
switch_audio_resampler_t *resampler;
|
||||
switch_buffer_t *buffer;
|
||||
switch_byte_t *dbuf;
|
||||
switch_size_t dbuflen;
|
||||
};
|
||||
|
||||
/*! \brief Abstract interface to an asr module */
|
||||
|
@ -91,7 +91,7 @@ SWITCH_DECLARE(switch_status_t) switch_resample_create(switch_audio_resampler_t
|
||||
\brief Destroy an existing resampler handle
|
||||
\param resampler the resampler handle to destroy
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_resample_destroy(switch_audio_resampler_t *resampler);
|
||||
SWITCH_DECLARE(void) switch_resample_destroy(switch_audio_resampler_t **resampler);
|
||||
|
||||
/*!
|
||||
\brief Resample one float buffer into another using specifications of a given handle
|
||||
|
@ -1465,6 +1465,9 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t * thread,
|
||||
}
|
||||
}
|
||||
|
||||
switch_resample_destroy(&member->read_resampler);
|
||||
switch_resample_destroy(&member->mux_resampler);
|
||||
|
||||
switch_clear_flag_locked(member, MFLAG_ITHREAD);
|
||||
|
||||
return NULL;
|
||||
|
@ -1239,7 +1239,9 @@ SWITCH_STANDARD_APP(record_function)
|
||||
int argc;
|
||||
char *mydata, *argv[4] = { 0 };
|
||||
char *l = NULL;
|
||||
|
||||
const char *tmp;
|
||||
int rate;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
||||
@ -1280,6 +1282,13 @@ SWITCH_STANDARD_APP(record_function)
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp = switch_channel_get_variable(channel, "record_rate"))) {
|
||||
rate = atoi(tmp);
|
||||
if (rate > 0) {
|
||||
fh.samplerate = rate;
|
||||
}
|
||||
}
|
||||
|
||||
args.input_callback = on_dtmf;
|
||||
status = switch_ivr_record_file(session, &fh, path, &args, limit);
|
||||
|
||||
|
@ -79,7 +79,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||
local_stream_context_t *cp;
|
||||
char file_buf[128] = "", path_buf[512] = "";
|
||||
switch_timer_t timer = {0};
|
||||
|
||||
int fd = -1;
|
||||
|
||||
if (switch_core_timer_init(&timer, source->timer_name, source->interval, source->samples, source->pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't start timer.\n");
|
||||
@ -89,7 +89,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||
|
||||
while(RUNNING) {
|
||||
const char *fname;
|
||||
|
||||
|
||||
if (switch_dir_open(&source->dir_handle, source->location, source->pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't open directory: %s\n", source->location);
|
||||
return NULL;
|
||||
@ -98,27 +98,37 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "open directory: %s\n", source->location);
|
||||
switch_yield(1000000);
|
||||
|
||||
while(RUNNING && (fname = switch_dir_next_file(source->dir_handle, file_buf, sizeof(file_buf)))) {
|
||||
while(RUNNING) {
|
||||
switch_size_t olen;
|
||||
uint8_t abuf[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
|
||||
|
||||
snprintf(path_buf, sizeof(path_buf), "%s%s%s", source->location, SWITCH_PATH_SEPARATOR, fname);
|
||||
if (switch_stristr(".loc", path_buf)) {
|
||||
int fd, bytes;
|
||||
if (fd > -1) {
|
||||
char *p;
|
||||
if (switch_fd_read_line(fd, path_buf, sizeof(path_buf))) {
|
||||
if ((p = strchr(path_buf, '\r')) ||
|
||||
(p = strchr(path_buf, '\n'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
} else {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (!(fname = switch_dir_next_file(source->dir_handle, file_buf, sizeof(file_buf)))) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((fd = open(path_buf, O_RDONLY)) < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s\n", fname);
|
||||
switch_yield(1000000);
|
||||
snprintf(path_buf, sizeof(path_buf), "%s%s%s", source->location, SWITCH_PATH_SEPARATOR, fname);
|
||||
|
||||
if (switch_stristr(".loc", path_buf)) {
|
||||
if ((fd = open(path_buf, O_RDONLY)) < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open %s\n", fname);
|
||||
switch_yield(1000000);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
bytes = read(fd, path_buf, sizeof(path_buf));
|
||||
if ((p = strchr(path_buf, '\r')) ||
|
||||
(p = strchr(path_buf, '\n'))) {
|
||||
*p = '\0';
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
fname = path_buf;
|
||||
@ -139,6 +149,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||
while (RUNNING) {
|
||||
switch_core_timer_next(&timer);
|
||||
olen = source->samples;
|
||||
|
||||
if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
|
||||
switch_core_file_close(&fh);
|
||||
break;
|
||||
@ -156,8 +167,13 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||
}
|
||||
|
||||
switch_dir_close(source->dir_handle);
|
||||
source->dir_handle = NULL;
|
||||
|
||||
}
|
||||
|
||||
if (fd > -1) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
switch_core_destroy_memory_pool(&source->pool);
|
||||
|
||||
@ -168,25 +184,37 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
|
||||
{
|
||||
local_stream_context_t *context;
|
||||
local_stream_source_t *source;
|
||||
char *alt_path = NULL;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing!\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
alt_path = switch_mprintf("%s/%d", path, handle->samplerate);
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
source = switch_core_hash_find(globals.source_hash, path);
|
||||
if ((source = switch_core_hash_find(globals.source_hash, alt_path))) {
|
||||
path = alt_path;
|
||||
} else {
|
||||
source = switch_core_hash_find(globals.source_hash, path);
|
||||
}
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
if (!source) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unknown source %s\n", path);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) {
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
status = SWITCH_STATUS_MEMERR;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
handle->samples = 0;
|
||||
handle->samplerate = source->rate;
|
||||
handle->channels = source->channels;
|
||||
@ -201,7 +229,8 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
|
||||
switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);
|
||||
if (switch_buffer_create_dynamic(&context->audio_buffer, 512, 1024, 0) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
||||
return SWITCH_STATUS_MEMERR;
|
||||
status = SWITCH_STATUS_MEMERR;
|
||||
goto end;
|
||||
}
|
||||
|
||||
context->source = source;
|
||||
@ -211,8 +240,9 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
|
||||
source->context_list = context;
|
||||
switch_mutex_unlock(source->mutex);
|
||||
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
end:
|
||||
switch_safe_free(alt_path);
|
||||
return status;
|
||||
}
|
||||
|
||||
static switch_status_t local_stream_file_close(switch_file_handle_t *handle)
|
||||
@ -350,6 +380,7 @@ static void launch_threads(void)
|
||||
}
|
||||
|
||||
source->samples = switch_bytes_per_frame(source->rate, source->interval);
|
||||
|
||||
switch_core_hash_insert(globals.source_hash, source->name, source);
|
||||
|
||||
switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool);
|
||||
|
@ -26,7 +26,7 @@
|
||||
* Anthony Minessale II <anthmct@yahoo.com>
|
||||
*
|
||||
*
|
||||
* mod_native_file.c -- Framework Demo Module
|
||||
* mod_native_file.c -- Native Files
|
||||
*
|
||||
*/
|
||||
#include <switch.h>
|
||||
|
@ -61,6 +61,9 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha
|
||||
int mode = 0;
|
||||
char *ext;
|
||||
struct format_map *map = NULL;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
char *alt_path = NULL, *next, *last, *ldup = NULL;
|
||||
size_t alt_len = 0;
|
||||
|
||||
if ((ext = strrchr(path, '.')) == 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n");
|
||||
@ -141,11 +144,28 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha
|
||||
if ((mode & SFM_WRITE) && sf_format_check(&context->sfinfo) == 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error : file format is invalid (0x%08X).\n", context->sfinfo.format);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
};
|
||||
}
|
||||
|
||||
if ((context->handle = sf_open(path, mode, &context->sfinfo)) == 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening File [%s] [%s]\n", path, sf_strerror(context->handle));
|
||||
return SWITCH_STATUS_GENERR;
|
||||
alt_len = strlen(path) + 10;
|
||||
switch_zmalloc(alt_path, alt_len);
|
||||
|
||||
switch_copy_string(alt_path, path, alt_len);
|
||||
if ((last = strrchr(alt_path, *SWITCH_PATH_SEPARATOR))) {
|
||||
next = ++last;
|
||||
ldup = strdup(last);
|
||||
switch_assert(ldup);
|
||||
switch_snprintf(next, alt_len - (last - alt_path), "%d%s%s", handle->samplerate, SWITCH_PATH_SEPARATOR, ldup);
|
||||
if ((context->handle = sf_open(alt_path, mode, &context->sfinfo))) {
|
||||
path = alt_path;
|
||||
}
|
||||
}
|
||||
|
||||
if (!context->handle) {
|
||||
if ((context->handle = sf_open(path, mode, &context->sfinfo)) == 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening File [%s] [%s]\n", path, sf_strerror(context->handle));
|
||||
status = SWITCH_STATUS_GENERR;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opening File [%s] %dhz\n", path, context->sfinfo.samplerate);
|
||||
@ -157,8 +177,15 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha
|
||||
handle->seekable = context->sfinfo.seekable;
|
||||
handle->speed = 0;
|
||||
handle->private_info = context;
|
||||
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
end:
|
||||
|
||||
switch_safe_free(alt_path);
|
||||
switch_safe_free(ldup);
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static switch_status_t sndfile_file_close(switch_file_handle_t *handle)
|
||||
|
@ -73,10 +73,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_open(switch_file_handle_t *fh,
|
||||
fh->handler = switch_core_strdup(fh->memory_pool, rhs);
|
||||
}
|
||||
|
||||
if (rate) {
|
||||
fh->samplerate = rate;
|
||||
} else {
|
||||
rate = 8000;
|
||||
if (!fh->samplerate) {
|
||||
if (!(fh->samplerate = rate)) {
|
||||
fh->samplerate = 8000;
|
||||
}
|
||||
}
|
||||
|
||||
if (channels) {
|
||||
@ -85,25 +85,130 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_open(switch_file_handle_t *fh,
|
||||
fh->channels = 1;
|
||||
}
|
||||
|
||||
if ((status = fh->file_interface->file_open(fh, file_path)) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_set_flag(fh, SWITCH_FILE_OPEN);
|
||||
if ((status = fh->file_interface->file_open(fh, file_path)) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if ((flags & SWITCH_FILE_FLAG_READ)) {
|
||||
fh->native_rate = fh->samplerate;
|
||||
} else {
|
||||
fh->native_rate = rate;
|
||||
}
|
||||
|
||||
if (fh->samplerate != rate) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Sample rate doesn't match\n");
|
||||
if ((flags & SWITCH_FILE_FLAG_READ)) {
|
||||
fh->samplerate = rate;
|
||||
}
|
||||
}
|
||||
|
||||
switch_set_flag(fh, SWITCH_FILE_OPEN);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh, void *data, switch_size_t *len)
|
||||
{
|
||||
switch_status_t status;
|
||||
switch_size_t orig_len = *len;
|
||||
|
||||
switch_assert(fh != NULL);
|
||||
switch_assert(fh->file_interface != NULL);
|
||||
|
||||
return fh->file_interface->file_read(fh, data, len);
|
||||
if (fh->buffer && switch_buffer_inuse(fh->buffer)) {
|
||||
*len = switch_buffer_read(fh->buffer, data, orig_len);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if ((status = fh->file_interface->file_read(fh, data, len)) != SWITCH_STATUS_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) {
|
||||
if (!fh->resampler) {
|
||||
if (switch_resample_create(&fh->resampler,
|
||||
fh->native_rate,
|
||||
orig_len * 10,
|
||||
fh->samplerate,
|
||||
orig_len * 10,
|
||||
fh->memory_pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
}
|
||||
|
||||
fh->resampler->from_len = switch_short_to_float(data, fh->resampler->from, (int) *len);
|
||||
fh->resampler->to_len =
|
||||
switch_resample_process(fh->resampler, fh->resampler->from, fh->resampler->from_len, fh->resampler->to, fh->resampler->to_size, 0);
|
||||
|
||||
if (fh->resampler->to_len > orig_len) {
|
||||
if (!fh->buffer) {
|
||||
switch_buffer_create_dynamic(&fh->buffer, fh->resampler->to_len * 2, fh->resampler->to_len * 4, fh->resampler->to_len * 8);
|
||||
switch_assert(fh->buffer);
|
||||
}
|
||||
if (!fh->dbuf) {
|
||||
fh->dbuflen = fh->resampler->to_len * 2;
|
||||
fh->dbuf = switch_core_alloc(fh->memory_pool, fh->dbuflen);
|
||||
}
|
||||
switch_assert(fh->resampler->to_len <= fh->dbuflen);
|
||||
|
||||
switch_float_to_short(fh->resampler->to, (int16_t *) fh->dbuf, fh->resampler->to_len);
|
||||
switch_buffer_write(fh->buffer, fh->dbuf, fh->resampler->to_len * 2);
|
||||
*len = switch_buffer_read(fh->buffer, data, orig_len);
|
||||
} else {
|
||||
switch_float_to_short(fh->resampler->to, data, fh->resampler->to_len);
|
||||
*len = fh->resampler->to_len;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, void *data, switch_size_t *len)
|
||||
{
|
||||
switch_size_t orig_len = *len;
|
||||
|
||||
switch_assert(fh != NULL);
|
||||
switch_assert(fh->file_interface != NULL);
|
||||
|
||||
if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) {
|
||||
if (!fh->resampler) {
|
||||
if (switch_resample_create(&fh->resampler,
|
||||
fh->native_rate,
|
||||
orig_len * 10,
|
||||
fh->samplerate,
|
||||
orig_len * 10,
|
||||
fh->memory_pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
}
|
||||
|
||||
fh->resampler->from_len = switch_short_to_float(data, fh->resampler->from, (int) *len);
|
||||
fh->resampler->to_len =
|
||||
switch_resample_process(fh->resampler, fh->resampler->from, fh->resampler->from_len, fh->resampler->to, fh->resampler->to_size, 0);
|
||||
if (fh->resampler->to_len > orig_len) {
|
||||
if (!fh->dbuf) {
|
||||
fh->dbuflen = fh->resampler->to_len * 2;
|
||||
fh->dbuf = switch_core_alloc(fh->memory_pool, fh->dbuflen);
|
||||
}
|
||||
switch_assert(fh->resampler->to_len <= fh->dbuflen);
|
||||
switch_float_to_short(fh->resampler->to, (int16_t *) fh->dbuf, fh->resampler->to_len);
|
||||
data = fh->dbuf;
|
||||
} else {
|
||||
switch_float_to_short(fh->resampler->to, data, fh->resampler->to_len);
|
||||
}
|
||||
|
||||
*len = fh->resampler->to_len;
|
||||
|
||||
}
|
||||
|
||||
if (!*len) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return fh->file_interface->file_write(fh, data, len);
|
||||
}
|
||||
@ -151,6 +256,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
|
||||
switch_clear_flag(fh, SWITCH_FILE_OPEN);
|
||||
status = fh->file_interface->file_close(fh);
|
||||
|
||||
if (fh->buffer) {
|
||||
switch_buffer_destroy(&fh->buffer);
|
||||
}
|
||||
|
||||
switch_resample_destroy(&fh->resampler);
|
||||
|
||||
|
||||
if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) {
|
||||
switch_core_destroy_memory_pool(&fh->memory_pool);
|
||||
}
|
||||
|
@ -566,11 +566,9 @@ SWITCH_DECLARE(void) switch_core_session_reset(switch_core_session_t *session)
|
||||
char buf[256];
|
||||
switch_size_t has;
|
||||
|
||||
/* sweep theese under the rug, they wont be leaked they will be reclaimed
|
||||
when the session ends.
|
||||
*/
|
||||
session->read_resampler = NULL;
|
||||
session->write_resampler = NULL;
|
||||
/* clear resamplers*/
|
||||
switch_resample_destroy(&session->read_resampler);
|
||||
switch_resample_destroy(&session->write_resampler);
|
||||
|
||||
/* clear indications */
|
||||
switch_core_session_flush_message(session);
|
||||
|
@ -348,8 +348,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
|
||||
const char *vval;
|
||||
time_t start = 0;
|
||||
uint32_t org_silence_hits = 0;
|
||||
switch_audio_resampler_t *resampler = NULL;
|
||||
int16_t resamp_out[2048];
|
||||
|
||||
if (!fh) {
|
||||
fh = &lfh;
|
||||
@ -362,27 +360,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
|
||||
switch_assert(read_codec != NULL);
|
||||
|
||||
fh->channels = read_codec->implementation->number_of_channels;
|
||||
fh->native_rate = read_codec->implementation->actual_samples_per_second;
|
||||
|
||||
if (fh->samplerate) {
|
||||
if (fh->samplerate != read_codec->implementation->actual_samples_per_second) {
|
||||
if (switch_resample_create(&resampler,
|
||||
read_codec->implementation->actual_samples_per_second,
|
||||
read_codec->implementation->actual_samples_per_second * 20,
|
||||
fh->samplerate,
|
||||
fh->samplerate * 20,
|
||||
switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fh->samplerate = read_codec->implementation->actual_samples_per_second;
|
||||
}
|
||||
|
||||
if (switch_core_file_open(fh,
|
||||
file,
|
||||
fh->channels,
|
||||
fh->samplerate,
|
||||
read_codec->implementation->actual_samples_per_second,
|
||||
SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
switch_core_session_reset(session);
|
||||
@ -553,18 +537,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
|
||||
}
|
||||
}
|
||||
|
||||
if (!switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
|
||||
if (!switch_test_flag(fh, SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)) {
|
||||
int16_t *data = read_frame->data;
|
||||
len = (switch_size_t) read_frame->datalen / 2;
|
||||
|
||||
if (resampler) {
|
||||
resampler->from_len = switch_short_to_float(read_frame->data, resampler->from, (int) len);
|
||||
resampler->to_len = switch_resample_process(resampler, resampler->from, resampler->from_len, resampler->to, resampler->to_size, 0);
|
||||
switch_float_to_short(resampler->to, resamp_out, read_frame->datalen);
|
||||
len = resampler->to_len;
|
||||
data = resamp_out;
|
||||
}
|
||||
|
||||
if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
@ -111,11 +111,17 @@ SWITCH_DECLARE(uint32_t) switch_resample_process(switch_audio_resampler_t *resam
|
||||
#endif
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_resample_destroy(switch_audio_resampler_t *resampler)
|
||||
SWITCH_DECLARE(void) switch_resample_destroy(switch_audio_resampler_t **resampler)
|
||||
{
|
||||
|
||||
if (resampler && *resampler) {
|
||||
#ifndef DISABLE_RESAMPLE
|
||||
resample_close(resampler->resampler);
|
||||
if ((*resampler)->resampler) {
|
||||
resample_close((*resampler)->resampler);
|
||||
}
|
||||
#endif
|
||||
*resampler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user