FS-7654 #resolve

This commit is contained in:
Anthony Minessale 2015-06-12 23:55:24 -05:00
parent 3e2d5e009e
commit d6a0abf1db
4 changed files with 55 additions and 22 deletions

View File

@ -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(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_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); 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); 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) #define switch_resample_calc_buffer_size(_to, _from, _srclen) ((uint32_t)(((float)_to / (float)_from) * (float)_srclen) * 2)

View File

@ -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->read_impl.actual_samples_per_second,
session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate,
&read_frame->flags); &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; codec->cur_frame = NULL;
session->read_codec->cur_frame = NULL; session->read_codec->cur_frame = NULL;
switch_thread_rwlock_unlock(session->bug_rwlock); 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 */ /* mux or demux to match */
if (session->read_impl.number_of_channels != read_frame->codec->implementation->number_of_channels) { if (session->raw_read_frame.channels != session->read_impl.number_of_channels) {
uint32_t rlen = session->raw_read_frame.datalen / 2 / read_frame->codec->implementation->number_of_channels; uint32_t rlen = session->raw_read_frame.datalen / 2 / session->raw_read_frame.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, session->raw_read_frame.channels, session->read_impl.number_of_channels);
switch_mux_channels((int16_t *) session->raw_read_frame.data, rlen, session->raw_read_frame.datalen = rlen * 2 * session->read_impl.number_of_channels;
read_frame->codec->implementation->number_of_channels, session->read_impl.number_of_channels); session->raw_read_frame.samples = session->raw_read_frame.datalen / 2;
session->raw_write_frame.datalen = rlen * 2 * session->read_impl.number_of_channels; session->raw_read_frame.channels = session->read_impl.number_of_channels;
} }
switch (status) { switch (status) {
case SWITCH_STATUS_RESAMPLE: case SWITCH_STATUS_RESAMPLE:
if (!session->read_resampler) { 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); switch_mutex_lock(bp->read_mutex);
if (bp->read_demux_frame) { if (bp->read_demux_frame) {
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; 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); memcpy(data, read_frame->data, read_frame->datalen);
switch_unmerge_sln((int16_t *)data, bytes, bp->read_demux_frame->data, bytes); datalen = switch_unmerge_sln((int16_t *)data, samples,
switch_buffer_write(bp->raw_read_buffer, data, read_frame->datalen); 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 { } else {
switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen); switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen);
} }

View File

@ -1566,6 +1566,8 @@ struct eavesdrop_pvt {
switch_frame_t demux_frame; switch_frame_t demux_frame;
int set_decoded_read; int set_decoded_read;
int errs; int errs;
switch_codec_implementation_t read_impl;
switch_codec_implementation_t tread_impl;
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; 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); switch_buffer_lock(ep->r_buffer);
bytes = (uint32_t) switch_buffer_read(ep->r_buffer, ep->data, rframe->datalen); 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; rframe->samples = rframe->datalen / 2;
ep->demux_frame.data = ep->data; ep->demux_frame.data = ep->data;
ep->demux_frame.datalen = bytes; ep->demux_frame.datalen = bytes;
ep->demux_frame.samples = bytes / 2; ep->demux_frame.samples = bytes / 2;
ep->demux_frame.channels = rframe->channels;
switch_buffer_unlock(ep->r_buffer); switch_buffer_unlock(ep->r_buffer);
switch_core_media_bug_set_read_replace_frame(bug, rframe); switch_core_media_bug_set_read_replace_frame(bug, rframe);
switch_core_media_bug_set_read_demux_frame(bug, &ep->demux_frame); switch_core_media_bug_set_read_demux_frame(bug, &ep->demux_frame);
} }
} }
} }
break; 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); switch_buffer_lock(ep->w_buffer);
bytes = (uint32_t) switch_buffer_read(ep->w_buffer, data, rframe->datalen); 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; rframe->samples = rframe->datalen / 2;
switch_buffer_unlock(ep->w_buffer); 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; uint32_t sanity = 600;
switch_media_bug_flag_t read_flags = 0, write_flags = 0; switch_media_bug_flag_t read_flags = 0, write_flags = 0;
const char *vval; const char *vval;
int buf_size = 0;
if (!switch_channel_media_up(channel)) { if (!switch_channel_media_up(channel)) {
goto end; goto end;
@ -1935,6 +1941,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
goto end; goto end;
} }
switch_core_session_get_read_impl(session, &read_impl);
ep->read_impl = read_impl;
ep->tread_impl = tread_impl;
codec_initialized = 1; codec_initialized = 1;
switch_core_session_set_read_codec(session, &codec); 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.data = buf;
write_frame.buflen = sizeof(buf); write_frame.buflen = sizeof(buf);
write_frame.rate = codec.implementation->actual_samples_per_second; write_frame.rate = codec.implementation->actual_samples_per_second;
/* Make sure that at least one leg is bridged, default to both */ /* Make sure that at least one leg is bridged, default to both */
if (! (flags & (ED_BRIDGE_READ | ED_BRIDGE_WRITE))) { if (! (flags & (ED_BRIDGE_READ | ED_BRIDGE_WRITE))) {
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->eavesdropper = session;
ep->flags = flags; ep->flags = flags;
switch_mutex_init(&ep->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); 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_buffer_add_mutex(ep->buffer, ep->mutex);
switch_mutex_init(&ep->w_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); 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_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_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); switch_buffer_add_mutex(ep->r_buffer, ep->r_mutex);
if (flags & ED_BRIDGE_READ) { 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.datalen = (uint32_t) switch_buffer_read(ep->buffer, buf, len);
write_frame.samples = write_frame.datalen / 2; 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) { if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) {
break; break;
} }

View File

@ -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; int i;
int32_t x, z; int32_t x, z;
if (channels == 0) channels = 1;
if (samples > other_samples) { if (samples > other_samples) {
x = other_samples; x = other_samples;
} else { } else {
x = samples; x = samples;
} }
for (i = 0; i < x; i++) { for (i = 0; i < x * channels; i++) {
z = data[i] + other_data[i]; z = data[i] + other_data[i];
switch_normalize_to_16bit(z); switch_normalize_to_16bit(z);
data[i] = (int16_t) 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; int i;
int32_t x; int32_t x;
if (channels == 0) channels = 1;
if (samples > other_samples) { if (samples > other_samples) {
x = other_samples; x = other_samples;
} else { } else {
x = samples; x = samples;
} }
for (i = 0; i < x; i++) { for (i = 0; i < x * channels; i++) {
data[i] -= other_data[i]; data[i] -= other_data[i];
} }