From d6a0abf1db5b9d7dc19a68bab22da6340e23a853 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 12 Jun 2015 23:55:24 -0500 Subject: [PATCH] FS-7654 #resolve --- src/include/switch_resample.h | 4 ++-- src/switch_core_io.c | 27 ++++++++++++++++++--------- src/switch_ivr_async.c | 34 +++++++++++++++++++++++++++------- src/switch_resample.c | 12 ++++++++---- 4 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/include/switch_resample.h b/src/include/switch_resample.h index eb1a30e5cb..b3fb436c86 100644 --- a/src/include/switch_resample.h +++ b/src/include/switch_resample.h @@ -171,8 +171,8 @@ SWITCH_DECLARE(void) switch_change_sln_volume(int16_t *data, uint32_t samples, i SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t samples, int32_t vol); ///\} -SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples); -SWITCH_DECLARE(uint32_t) switch_unmerge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples); +SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels); +SWITCH_DECLARE(uint32_t) switch_unmerge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels); SWITCH_DECLARE(void) switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels); #define switch_resample_calc_buffer_size(_to, _from, _srclen) ((uint32_t)(((float)_to / (float)_from) * (float)_srclen) * 2) diff --git a/src/switch_core_io.c b/src/switch_core_io.c index fce2f41df7..64c0d11593 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -496,6 +496,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi session->read_impl.actual_samples_per_second, session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, &read_frame->flags); + + session->raw_read_frame.samples = session->raw_read_frame.datalen / 2; + session->raw_read_frame.channels = codec->implementation->number_of_channels; codec->cur_frame = NULL; session->read_codec->cur_frame = NULL; switch_thread_rwlock_unlock(session->bug_rwlock); @@ -521,14 +524,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi } /* mux or demux to match */ - if (session->read_impl.number_of_channels != read_frame->codec->implementation->number_of_channels) { - uint32_t rlen = session->raw_read_frame.datalen / 2 / read_frame->codec->implementation->number_of_channels; - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s MUX READ\n", switch_channel_get_name(session->channel)); - switch_mux_channels((int16_t *) session->raw_read_frame.data, rlen, - read_frame->codec->implementation->number_of_channels, session->read_impl.number_of_channels); - session->raw_write_frame.datalen = rlen * 2 * session->read_impl.number_of_channels; + if (session->raw_read_frame.channels != session->read_impl.number_of_channels) { + uint32_t rlen = session->raw_read_frame.datalen / 2 / session->raw_read_frame.channels; + switch_mux_channels((int16_t *) session->raw_read_frame.data, rlen, session->raw_read_frame.channels, session->read_impl.number_of_channels); + session->raw_read_frame.datalen = rlen * 2 * session->read_impl.number_of_channels; + session->raw_read_frame.samples = session->raw_read_frame.datalen / 2; + session->raw_read_frame.channels = session->read_impl.number_of_channels; } + switch (status) { case SWITCH_STATUS_RESAMPLE: if (!session->read_resampler) { @@ -709,11 +713,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_mutex_lock(bp->read_mutex); if (bp->read_demux_frame) { uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; - int bytes = read_frame->datalen / 2; + int bytes = read_frame->datalen; + uint32_t datalen = 0; + uint32_t samples = bytes / 2 / bp->read_demux_frame->channels; memcpy(data, read_frame->data, read_frame->datalen); - switch_unmerge_sln((int16_t *)data, bytes, bp->read_demux_frame->data, bytes); - switch_buffer_write(bp->raw_read_buffer, data, read_frame->datalen); + datalen = switch_unmerge_sln((int16_t *)data, samples, + bp->read_demux_frame->data, samples, + bp->read_demux_frame->channels) * 2 * bp->read_demux_frame->channels; + + switch_buffer_write(bp->raw_read_buffer, data, datalen); } else { switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen); } diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 6baefb2d55..22fe4b7d52 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1566,6 +1566,8 @@ struct eavesdrop_pvt { switch_frame_t demux_frame; int set_decoded_read; int errs; + switch_codec_implementation_t read_impl; + switch_codec_implementation_t tread_impl; uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; }; @@ -1666,18 +1668,21 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data switch_buffer_lock(ep->r_buffer); bytes = (uint32_t) switch_buffer_read(ep->r_buffer, ep->data, rframe->datalen); - rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) ep->data, bytes / 2) * 2; + memcpy(rframe->data, ep->data, rframe->datalen); + rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) ep->data, bytes / 2, rframe->channels) * 2 * rframe->channels; rframe->samples = rframe->datalen / 2; ep->demux_frame.data = ep->data; ep->demux_frame.datalen = bytes; ep->demux_frame.samples = bytes / 2; - + ep->demux_frame.channels = rframe->channels; + switch_buffer_unlock(ep->r_buffer); switch_core_media_bug_set_read_replace_frame(bug, rframe); switch_core_media_bug_set_read_demux_frame(bug, &ep->demux_frame); } } + } break; @@ -1691,7 +1696,7 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data switch_buffer_lock(ep->w_buffer); bytes = (uint32_t) switch_buffer_read(ep->w_buffer, data, rframe->datalen); - rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) data, bytes / 2) * 2; + rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) data, bytes / 2, rframe->channels) * 2 * rframe->channels; rframe->samples = rframe->datalen / 2; switch_buffer_unlock(ep->w_buffer); @@ -1853,6 +1858,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session uint32_t sanity = 600; switch_media_bug_flag_t read_flags = 0, write_flags = 0; const char *vval; + int buf_size = 0; if (!switch_channel_media_up(channel)) { goto end; @@ -1935,6 +1941,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session goto end; } + switch_core_session_get_read_impl(session, &read_impl); + + ep->read_impl = read_impl; + ep->tread_impl = tread_impl; + codec_initialized = 1; switch_core_session_set_read_codec(session, &codec); @@ -1942,24 +1953,26 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session write_frame.data = buf; write_frame.buflen = sizeof(buf); write_frame.rate = codec.implementation->actual_samples_per_second; - + /* Make sure that at least one leg is bridged, default to both */ if (! (flags & (ED_BRIDGE_READ | ED_BRIDGE_WRITE))) { flags |= ED_BRIDGE_READ | ED_BRIDGE_WRITE; } + buf_size = codec.implementation->decoded_bytes_per_packet * 10; + ep->eavesdropper = session; ep->flags = flags; switch_mutex_init(&ep->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); - switch_buffer_create_dynamic(&ep->buffer, 2048, 2048, 8192); + switch_buffer_create_dynamic(&ep->buffer, buf_size, buf_size, buf_size); switch_buffer_add_mutex(ep->buffer, ep->mutex); switch_mutex_init(&ep->w_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); - switch_buffer_create_dynamic(&ep->w_buffer, 2048, 2048, 8192); + switch_buffer_create_dynamic(&ep->w_buffer, buf_size, buf_size, buf_size); switch_buffer_add_mutex(ep->w_buffer, ep->w_mutex); switch_mutex_init(&ep->r_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); - switch_buffer_create_dynamic(&ep->r_buffer, 2048, 2048, 8192); + switch_buffer_create_dynamic(&ep->r_buffer, buf_size, buf_size, buf_size); switch_buffer_add_mutex(ep->r_buffer, ep->r_mutex); if (flags & ED_BRIDGE_READ) { @@ -2178,6 +2191,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session write_frame.datalen = (uint32_t) switch_buffer_read(ep->buffer, buf, len); write_frame.samples = write_frame.datalen / 2; + if (ep->tread_impl.number_of_channels != ep->read_impl.number_of_channels) { + uint32_t rlen = write_frame.datalen / 2 / ep->tread_impl.number_of_channels; + switch_mux_channels((int16_t *) write_frame.data, rlen, ep->tread_impl.number_of_channels, ep->read_impl.number_of_channels); + write_frame.datalen = rlen * 2 * ep->read_impl.number_of_channels; + write_frame.samples = write_frame.datalen / 2; + } + if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) { break; } diff --git a/src/switch_resample.c b/src/switch_resample.c index bca11e578e..d9f041b55f 100644 --- a/src/switch_resample.c +++ b/src/switch_resample.c @@ -228,18 +228,20 @@ SWITCH_DECLARE(void) switch_generate_sln_silence(int16_t *data, uint32_t samples } } -SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples) +SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels) { int i; int32_t x, z; + if (channels == 0) channels = 1; + if (samples > other_samples) { x = other_samples; } else { x = samples; } - for (i = 0; i < x; i++) { + for (i = 0; i < x * channels; i++) { z = data[i] + other_data[i]; switch_normalize_to_16bit(z); data[i] = (int16_t) z; @@ -249,18 +251,20 @@ SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16 } -SWITCH_DECLARE(uint32_t) switch_unmerge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples) +SWITCH_DECLARE(uint32_t) switch_unmerge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels) { int i; int32_t x; + if (channels == 0) channels = 1; + if (samples > other_samples) { x = other_samples; } else { x = samples; } - for (i = 0; i < x; i++) { + for (i = 0; i < x * channels; i++) { data[i] -= other_data[i]; }