FSCORE-288

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11723 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-02-10 00:58:54 +00:00
parent bc1e93bf5d
commit 6e80c32ae2
4 changed files with 38 additions and 23 deletions

View File

@ -85,8 +85,11 @@ SWITCH_BEGIN_EXTERN_C
\param pool the memory pool to use for buffer allocation \param pool the memory pool to use for buffer allocation
\return SWITCH_STATUS_SUCCESS if the handle was created \return SWITCH_STATUS_SUCCESS if the handle was created
*/ */
SWITCH_DECLARE(switch_status_t) switch_resample_create(switch_audio_resampler_t **new_resampler, SWITCH_DECLARE(switch_status_t) switch_resample_perform_create(switch_audio_resampler_t **new_resampler,
int from_rate, switch_size_t from_size, int to_rate, uint32_t to_size, switch_memory_pool_t *pool); int from_rate, switch_size_t from_size, int to_rate,
uint32_t to_size, switch_memory_pool_t *pool, const char *file, const char *func, int line);
#define switch_resample_create(_n, _fr, _fs, _tr, _ts, _p) switch_resample_perform_create(_n, _fr, _fs, _tr, _ts, _p, __FILE__, __SWITCH_FUNC__, __LINE__)
/*! /*!
\brief Destroy an existing resampler handle \brief Destroy an existing resampler handle

View File

@ -568,7 +568,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
switch_frame_t *enc_frame = NULL, *write_frame = frame; switch_frame_t *enc_frame = NULL, *write_frame = frame;
unsigned int flag = 0, need_codec = 0, perfect = 0, do_bugs = 0, do_write = 0, do_resample = 0, ptime_mismatch = 0, pass_cng = 0, resample = 0; unsigned int flag = 0, need_codec = 0, perfect = 0, do_bugs = 0, do_write = 0, do_resample = 0, ptime_mismatch = 0, pass_cng = 0, resample = 0;
int did_write_resample = 0;
switch_assert(session != NULL); switch_assert(session != NULL);
switch_assert(frame != NULL); switch_assert(frame != NULL);
@ -665,7 +666,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &flag); session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &flag);
if (do_resample && status == SWITCH_STATUS_SUCCESS) { if (do_resample && status == SWITCH_STATUS_SUCCESS) {
status = SWITCH_STATUS_RESAMPLE; status = SWITCH_STATUS_RESAMPLE;
@ -675,6 +676,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
case SWITCH_STATUS_RESAMPLE: case SWITCH_STATUS_RESAMPLE:
resample++; resample++;
write_frame = &session->raw_write_frame; write_frame = &session->raw_write_frame;
write_frame->rate = frame->codec->implementation->actual_samples_per_second;
if (!session->write_resampler) { if (!session->write_resampler) {
switch_mutex_lock(session->resample_mutex); switch_mutex_lock(session->resample_mutex);
status = switch_resample_create(&session->write_resampler, status = switch_resample_create(&session->write_resampler,
@ -729,7 +731,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
short *data = write_frame->data; short *data = write_frame->data;
switch_mutex_lock(session->resample_mutex); switch_mutex_lock(session->resample_mutex);
session->write_resampler->from_len = write_frame->datalen / 2; session->write_resampler->from_len = write_frame->datalen / 2;
switch_short_to_float(data, session->write_resampler->from, session->write_resampler->from_len); switch_short_to_float(data, session->write_resampler->from, session->write_resampler->from_len);
@ -742,12 +743,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
write_frame->samples = session->write_resampler->to_len; write_frame->samples = session->write_resampler->to_len;
write_frame->datalen = write_frame->samples * 2; write_frame->datalen = write_frame->samples * 2;
write_frame->rate = session->write_resampler->to_rate; write_frame->rate = session->write_resampler->to_rate;
did_write_resample = 1;
switch_mutex_unlock(session->resample_mutex); switch_mutex_unlock(session->resample_mutex);
} }
if (session->bugs && !switch_channel_test_flag(session->channel, CF_PAUSE_BUGS)) { if (session->bugs && !switch_channel_test_flag(session->channel, CF_PAUSE_BUGS)) {
switch_media_bug_t *bp, *dp, *last = NULL; switch_media_bug_t *bp, *dp, *last = NULL;
switch_thread_rwlock_rdlock(session->bug_rwlock); switch_thread_rwlock_rdlock(session->bug_rwlock);
for (bp = session->bugs; bp; bp = bp->next) { for (bp = session->bugs; bp; bp = bp->next) {
switch_bool_t ok = SWITCH_TRUE; switch_bool_t ok = SWITCH_TRUE;
@ -813,7 +815,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
} }
if (perfect) { if (perfect) {
if (write_frame->datalen < session->write_impl.decoded_bytes_per_packet) { if (write_frame->datalen < session->write_impl.decoded_bytes_per_packet) {
memset(write_frame->data, 255, session->write_impl.decoded_bytes_per_packet - write_frame->datalen); memset(write_frame->data, 255, session->write_impl.decoded_bytes_per_packet - write_frame->datalen);
write_frame->datalen = session->write_impl.decoded_bytes_per_packet; write_frame->datalen = session->write_impl.decoded_bytes_per_packet;
@ -890,7 +892,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
goto error; goto error;
} }
} }
if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) { if (!(switch_buffer_write(session->raw_write_buffer, write_frame->data, write_frame->datalen))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Write Buffer %u bytes Failed!\n", write_frame->datalen);
status = SWITCH_STATUS_MEMERR; goto error; status = SWITCH_STATUS_MEMERR; goto error;
@ -912,20 +914,25 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
enc_frame = &session->raw_write_frame; enc_frame = &session->raw_write_frame;
session->raw_write_frame.rate = session->write_impl.actual_samples_per_second; session->raw_write_frame.rate = session->write_impl.actual_samples_per_second;
session->enc_write_frame.datalen = session->enc_write_frame.buflen; session->enc_write_frame.datalen = session->enc_write_frame.buflen;
if (frame->codec && frame->codec->implementation) { if (frame->codec && frame->codec->implementation) {
rate = frame->codec->implementation->actual_samples_per_second; rate = frame->codec->implementation->actual_samples_per_second;
} else { } else {
rate = session->write_impl.actual_samples_per_second; rate = session->write_impl.actual_samples_per_second;
} }
status = switch_core_codec_encode(session->write_codec, status = switch_core_codec_encode(session->write_codec,
frame->codec, frame->codec,
enc_frame->data, enc_frame->data,
enc_frame->datalen, enc_frame->datalen,
rate, rate,
session->enc_write_frame.data, session->enc_write_frame.data,
&session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag); &session->enc_write_frame.datalen,
&session->enc_write_frame.rate, &flag);
switch (status) { switch (status) {
case SWITCH_STATUS_RESAMPLE: case SWITCH_STATUS_RESAMPLE:
resample++; resample++;
@ -983,7 +990,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
goto error; goto error;
} }
if (session->read_resampler) { if (!did_write_resample && session->read_resampler) {
short *data = write_frame->data; short *data = write_frame->data;
switch_mutex_lock(session->resample_mutex); switch_mutex_lock(session->resample_mutex);

View File

@ -556,7 +556,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
switch_core_session_t *tsession; switch_core_session_t *tsession;
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
switch_codec_t *read_codec = switch_core_session_get_read_codec(session);
int codec_initialized = 0; int codec_initialized = 0;
if ((tsession = switch_core_session_locate(uuid))) { if ((tsession = switch_core_session_locate(uuid))) {
@ -566,11 +565,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
switch_frame_t *read_frame, write_frame = { 0 }; switch_frame_t *read_frame, write_frame = { 0 };
switch_codec_t codec = { 0 }; switch_codec_t codec = { 0 };
int16_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE / 2]; int16_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE / 2];
switch_codec_t *tread_codec = switch_core_session_get_read_codec(tsession);
uint32_t tlen; uint32_t tlen;
const char *macro_name = "eavesdrop_announce"; const char *macro_name = "eavesdrop_announce";
const char *id_name = NULL; const char *id_name = NULL;
switch_codec_implementation_t tread_impl = {0}, read_impl = {0};
if (!switch_channel_media_ready(channel)) { if (!switch_channel_media_ready(channel)) {
goto end; goto end;
} }
@ -579,6 +579,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
goto end; goto end;
} }
switch_core_session_get_read_impl(tsession, &tread_impl);
switch_core_session_get_read_impl(session, &read_impl);
if ((id_name = switch_channel_get_variable(tchannel, "eavesdrop_announce_id"))) { if ((id_name = switch_channel_get_variable(tchannel, "eavesdrop_announce_id"))) {
const char *tmp = switch_channel_get_variable(tchannel, "eavesdrop_annnounce_macro"); const char *tmp = switch_channel_get_variable(tchannel, "eavesdrop_annnounce_macro");
if (tmp) { if (tmp) {
@ -622,16 +625,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
ep = switch_core_session_alloc(session, sizeof(*ep)); ep = switch_core_session_alloc(session, sizeof(*ep));
tlen = tread_codec->implementation->decoded_bytes_per_packet; tlen = tread_impl.decoded_bytes_per_packet;
switch_channel_pre_answer(channel); switch_channel_pre_answer(channel);
if (switch_core_codec_init(&codec, if (switch_core_codec_init(&codec,
"L16", "L16",
NULL, NULL,
tread_codec->implementation->actual_samples_per_second, tread_impl.actual_samples_per_second,
tread_codec->implementation->microseconds_per_packet / 1000, tread_impl.microseconds_per_packet / 1000,
tread_codec->implementation->number_of_channels, tread_impl.number_of_channels,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot init codec\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot init codec\n");
@ -645,7 +648,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
write_frame.codec = &codec; write_frame.codec = &codec;
write_frame.data = buf; write_frame.data = buf;
write_frame.buflen = sizeof(buf); write_frame.buflen = sizeof(buf);
write_frame.rate = read_codec->implementation->actual_samples_per_second; write_frame.rate = codec.implementation->actual_samples_per_second;
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));
@ -731,7 +734,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
switch_buffer_zero(ep->r_buffer); switch_buffer_zero(ep->r_buffer);
switch_buffer_unlock(ep->r_buffer); switch_buffer_unlock(ep->r_buffer);
} }
if (ep->w_buffer) { if (ep->w_buffer) {
switch_buffer_lock(ep->w_buffer); switch_buffer_lock(ep->w_buffer);
switch_buffer_zero(ep->w_buffer); switch_buffer_zero(ep->w_buffer);
@ -760,6 +763,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
while (switch_buffer_inuse(ep->buffer) >= len) { while (switch_buffer_inuse(ep->buffer) >= len) {
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 ((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

@ -53,8 +53,9 @@
#define resample_buffer(a, b, c) a > b ? ((a / 1000) / 2) * c : ((b / 1000) / 2) * c #define resample_buffer(a, b, c) a > b ? ((a / 1000) / 2) * c : ((b / 1000) / 2) * c
SWITCH_DECLARE(switch_status_t) switch_resample_create(switch_audio_resampler_t **new_resampler, SWITCH_DECLARE(switch_status_t) switch_resample_perform_create(switch_audio_resampler_t **new_resampler,
int from_rate, switch_size_t from_size, int to_rate, uint32_t to_size, switch_memory_pool_t *pool) int from_rate, switch_size_t from_size, int to_rate,
uint32_t to_size, switch_memory_pool_t *pool, const char *file, const char *func, int line)
{ {
#ifdef DISABLE_RESAMPLE #ifdef DISABLE_RESAMPLE
*new_resampler = NULL; *new_resampler = NULL;
@ -75,8 +76,8 @@ SWITCH_DECLARE(switch_status_t) switch_resample_create(switch_audio_resampler_t
resampler->rfactor = (lfrom_rate / lto_rate); resampler->rfactor = (lfrom_rate / lto_rate);
resampler->resampler = resample_open(QUALITY, resampler->factor, resampler->factor); resampler->resampler = resample_open(QUALITY, resampler->factor, resampler->factor);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Activate Resampler %d->%d %f\n", resampler->from_rate, resampler->to_rate, switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_NOTICE,
resampler->factor); "Activate Resampler %d->%d %f\n", resampler->from_rate, resampler->to_rate, resampler->factor);
resampler->from_size = resample_buffer(to_rate, from_rate, (uint32_t) from_size); resampler->from_size = resample_buffer(to_rate, from_rate, (uint32_t) from_size);
resampler->from = (float *) switch_core_alloc(pool, resampler->from_size * sizeof(float)); resampler->from = (float *) switch_core_alloc(pool, resampler->from_size * sizeof(float));
resampler->to_size = resample_buffer(to_rate, from_rate, (uint32_t) to_size);; resampler->to_size = resample_buffer(to_rate, from_rate, (uint32_t) to_size);;