tweaks for wideband tests

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1883 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-07-14 19:42:09 +00:00
parent 2b4ddd0576
commit 4aab8842cd
4 changed files with 124 additions and 36 deletions

View File

@ -151,6 +151,7 @@ struct conference_member {
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
switch_buffer_t *audio_buffer; switch_buffer_t *audio_buffer;
switch_buffer_t *mux_buffer; switch_buffer_t *mux_buffer;
switch_buffer_t *resample_buffer;
uint32_t flags; uint32_t flags;
switch_mutex_t *flag_mutex; switch_mutex_t *flag_mutex;
switch_mutex_t *audio_in_mutex; switch_mutex_t *audio_in_mutex;
@ -165,6 +166,9 @@ struct conference_member {
int32_t energy_level; int32_t energy_level;
int32_t volume_in_level; int32_t volume_in_level;
int32_t volume_out_level; int32_t volume_out_level;
uint32_t native_rate;
switch_audio_resampler_t *mux_resampler;
switch_audio_resampler_t *read_resampler;
confernce_file_node_t *fnode; confernce_file_node_t *fnode;
conference_relationship_t *relationships; conference_relationship_t *relationships;
struct conference_member *next; struct conference_member *next;
@ -461,7 +465,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
/* Read one frame of audio from each member channel and save it for redistribution */ /* Read one frame of audio from each member channel and save it for redistribution */
for (imember = conference->members; imember; imember = imember->next) { for (imember = conference->members; imember; imember = imember->next) {
if (imember->buflen) { if (imember->buflen) {
memset(imember->frame, 255, bytes); memset(imember->frame, 255, imember->buflen);
} else { } else {
imember->frame = switch_core_alloc(imember->pool, bytes); imember->frame = switch_core_alloc(imember->pool, bytes);
imember->mux_frame = switch_core_alloc(imember->pool, bytes); imember->mux_frame = switch_core_alloc(imember->pool, bytes);
@ -469,12 +473,35 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
} }
switch_mutex_lock(imember->audio_in_mutex); switch_mutex_lock(imember->audio_in_mutex);
if ((imember->read = (uint32_t)switch_buffer_read(imember->audio_buffer, imember->frame, imember->buflen))) { /* if there is audio in the resample buffer it takes precedence over the other data */
ready++; /* Tally of how many channels had data */ if (imember->mux_resampler && switch_buffer_inuse(imember->resample_buffer) >= bytes) {
imember->read = switch_buffer_read(imember->resample_buffer, imember->frame, bytes);
ready++;
} else if ((imember->read = (uint32_t)switch_buffer_read(imember->audio_buffer, imember->frame, imember->buflen))) {
/* If the caller is not at the right sample rate resample him to suit and buffer accordingly */
if (imember->mux_resampler) {
int16_t *bptr = (int16_t *) imember->frame;
int16_t out[1024];
int len = (int) imember->read;
imember->mux_resampler->from_len = switch_short_to_float(bptr, imember->mux_resampler->from, (int) len / 2);
imember->mux_resampler->to_len = switch_resample_process(imember->mux_resampler, imember->mux_resampler->from,
imember->mux_resampler->from_len, imember->mux_resampler->to,
imember->mux_resampler->to_size, 0);
switch_float_to_short(imember->mux_resampler->to, out, len);
len = imember->mux_resampler->to_len * 2;
switch_buffer_write(imember->resample_buffer, out, len);
if (switch_buffer_inuse(imember->resample_buffer) >= bytes) {
imember->read = switch_buffer_read(imember->resample_buffer, imember->frame, bytes);
ready++;
}
} else {
ready++; /* Tally of how many channels had data */
}
} }
switch_mutex_unlock(imember->audio_in_mutex); switch_mutex_unlock(imember->audio_in_mutex);
} }
/* If a file or speech event is being played */ /* If a file or speech event is being played */
if (conference->fnode) { if (conference->fnode) {
/* Lead in time */ /* Lead in time */
@ -550,9 +577,11 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
if (imember->read > imember->len) { if (imember->read > imember->len) {
imember->len = imember->read; imember->len = imember->read;
} }
bptr = (int16_t *) imember->frame; bptr = (int16_t *) imember->frame;
muxed = (int16_t *) omember->mux_frame; muxed = (int16_t *) omember->mux_frame;
for (x = 0; x < imember->read / 2; x++) { for (x = 0; x < imember->read / 2; x++) {
int32_t z = muxed[x] + bptr[x]; int32_t z = muxed[x] + bptr[x];
@ -865,22 +894,29 @@ static void conference_loop(conference_member_t *member)
} }
} }
} else { } else {
if (switch_buffer_inuse(member->mux_buffer)) { switch_buffer_t *use_buffer = NULL;
uint32_t mux_used = switch_buffer_inuse(member->mux_buffer);
//uint32_t res_used = member->mux_resampler ? switch_buffer_inuse(member->resample_buffer) : 0;
if (mux_used) {
/* Flush the output buffer and write all the data (presumably muxed) back to the channel */ /* Flush the output buffer and write all the data (presumably muxed) back to the channel */
switch_mutex_lock(member->audio_out_mutex); switch_mutex_lock(member->audio_out_mutex);
write_frame.data = data; write_frame.data = data;
while ((write_frame.datalen = (uint32_t)switch_buffer_read(member->mux_buffer, write_frame.data, bytes))) { use_buffer = member->mux_buffer;
while ((write_frame.datalen = (uint32_t)switch_buffer_read(use_buffer, write_frame.data, bytes))) {
if (write_frame.datalen && switch_test_flag(member, MFLAG_CAN_HEAR)) { if (write_frame.datalen && switch_test_flag(member, MFLAG_CAN_HEAR)) {
write_frame.samples = write_frame.datalen / 2; write_frame.samples = write_frame.datalen / 2;
/* Check for output volume adjustments */ /* Check for output volume adjustments */
if (member->volume_out_level) { if (member->volume_out_level) {
switch_change_sln_volume(write_frame.data, write_frame.samples, member->volume_out_level); switch_change_sln_volume(write_frame.data, write_frame.samples, member->volume_out_level);
} }
switch_core_session_write_frame(member->session, &write_frame, -1, 0); switch_core_session_write_frame(member->session, &write_frame, -1, 0);
} }
} }
switch_mutex_unlock(member->audio_out_mutex); switch_mutex_unlock(member->audio_out_mutex);
} else { } else {
switch_core_timer_next(&timer); switch_core_timer_next(&timer);
@ -2226,13 +2262,18 @@ static void conference_function(switch_core_session_t *session, char *data)
} }
} }
/* Save the original read codec. */ /* Save the original read codec. */
read_codec = switch_core_session_get_read_codec(session); read_codec = switch_core_session_get_read_codec(session);
member.native_rate = read_codec->implementation->samples_per_second;
/* Setup a Signed Linear codec for reading audio. */ /* Setup a Signed Linear codec for reading audio. */
if (switch_core_codec_init(&member.read_codec, if (switch_core_codec_init(&member.read_codec,
"L16", "L16",
//conference->rate,
read_codec->implementation->samples_per_second, read_codec->implementation->samples_per_second,
//conference->interval,
read_codec->implementation->microseconds_per_frame / 1000, read_codec->implementation->microseconds_per_frame / 1000,
1, 1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
@ -2247,11 +2288,30 @@ static void conference_function(switch_core_session_t *session, char *data)
goto done; goto done;
} }
if (read_codec->implementation->samples_per_second != conference->rate) {
switch_audio_resampler_t **resampler = read_codec->implementation->samples_per_second > conference->rate ?
&member.read_resampler : &member.mux_resampler;
switch_resample_create(resampler,
read_codec->implementation->samples_per_second,
read_codec->implementation->samples_per_second * 20,
conference->rate,
conference->rate * 20,
switch_core_session_get_pool(session));
/* Setup an audio buffer for the resampled audio */
if (switch_buffer_create(pool, &member.resample_buffer, CONF_BUFFER_SIZE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error Creating Audio Buffer!\n");
goto done;
}
}
/* Setup a Signed Linear codec for writing audio. */ /* Setup a Signed Linear codec for writing audio. */
if (switch_core_codec_init(&member.write_codec, if (switch_core_codec_init(&member.write_codec,
"L16", "L16",
read_codec->implementation->samples_per_second, conference->rate,
read_codec->implementation->microseconds_per_frame / 1000, //read_codec->implementation->samples_per_second,
conference->interval,
//read_codec->implementation->microseconds_per_frame / 1000,
1, 1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, NULL,
@ -2444,7 +2504,19 @@ static void *SWITCH_THREAD_FUNC input_thread_run(switch_thread_t *thread, void *
/* skip frames that are not actual media or when we are muted or silent */ /* skip frames that are not actual media or when we are muted or silent */
if ((talking || energy_level == 0) && switch_test_flag(member, MFLAG_CAN_SPEAK)) { if ((talking || energy_level == 0) && switch_test_flag(member, MFLAG_CAN_SPEAK)) {
if (member->read_resampler) {
int16_t *bptr = (int16_t *) read_frame->data;
int len = (int) read_frame->datalen;;
member->read_resampler->from_len = switch_short_to_float(bptr, member->read_resampler->from, (int) len / 2);
member->read_resampler->to_len = switch_resample_process(member->read_resampler, member->read_resampler->from,
member->read_resampler->from_len, member->read_resampler->to,
member->read_resampler->to_size, 0);
switch_float_to_short(member->read_resampler->to, read_frame->data, len);
len = member->read_resampler->to_len * 2;
read_frame->datalen = len;
read_frame->samples = len / 2;
}
/* Check for input volume adjustments */ /* Check for input volume adjustments */
if (member->volume_in_level) { if (member->volume_in_level) {
switch_change_sln_volume(read_frame->data, read_frame->datalen / 2, member->volume_in_level); switch_change_sln_volume(read_frame->data, read_frame->datalen / 2, member->volume_in_level);

View File

@ -208,7 +208,6 @@ static switch_status_t switch_speex_encode(switch_codec_t *codec,
*encoded_data_len = speex_bits_write(&context->encoder_bits, (char *) encoded_data, context->encoder_frame_size); *encoded_data_len = speex_bits_write(&context->encoder_bits, (char *) encoded_data, context->encoder_frame_size);
speex_bits_reset(&context->encoder_bits); speex_bits_reset(&context->encoder_bits);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -231,9 +230,10 @@ static switch_status_t switch_speex_decode(switch_codec_t *codec,
if (*flag & SWITCH_CODEC_FLAG_SILENCE) { if (*flag & SWITCH_CODEC_FLAG_SILENCE) {
speex_decode_int(context->decoder_state, NULL, buf); speex_decode_int(context->decoder_state, NULL, buf);
} else { } else {
speex_bits_read_from(&context->decoder_bits, (char *) encoded_data, (int) *decoded_data_len); speex_bits_read_from(&context->decoder_bits, (char *) encoded_data, (int) encoded_data_len);
speex_decode_int(context->decoder_state, &context->decoder_bits, buf); speex_decode_int(context->decoder_state, &context->decoder_bits, buf);
} }
*decoded_data_len = codec->implementation->bytes_per_frame;
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -276,7 +276,7 @@ static const switch_codec_implementation_t speex_32k_implementation = {
/*.nanoseconds_per_frame */ 20000, /*.nanoseconds_per_frame */ 20000,
/*.samples_per_frame */ 640, /*.samples_per_frame */ 640,
/*.bytes_per_frame */ 1280, /*.bytes_per_frame */ 1280,
/*.encoded_bytes_per_frame */ 1280, /*.encoded_bytes_per_frame */ 43,
/*.number_of_channels */ 1, /*.number_of_channels */ 1,
/*.pref_frames_per_packet */ 1, /*.pref_frames_per_packet */ 1,
/*.max_frames_per_packet */ 1, /*.max_frames_per_packet */ 1,
@ -295,7 +295,7 @@ static const switch_codec_implementation_t speex_16k_implementation = {
/*.nanoseconds_per_frame */ 20000, /*.nanoseconds_per_frame */ 20000,
/*.samples_per_frame */ 320, /*.samples_per_frame */ 320,
/*.bytes_per_frame */ 640, /*.bytes_per_frame */ 640,
/*.encoded_bytes_per_frame */ 640, /*.encoded_bytes_per_frame */ 43,
/*.number_of_channels */ 1, /*.number_of_channels */ 1,
/*.pref_frames_per_packet */ 1, /*.pref_frames_per_packet */ 1,
/*.max_frames_per_packet */ 1, /*.max_frames_per_packet */ 1,
@ -308,14 +308,14 @@ static const switch_codec_implementation_t speex_16k_implementation = {
static const switch_codec_implementation_t speex_8k_implementation = { static const switch_codec_implementation_t speex_8k_implementation = {
/*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO,
/*.ianacode */ 98, /*.ianacode */ 97,
/*.iananame */ "speex", /*.iananame */ "speex",
/*.samples_per_second */ 8000, /*.samples_per_second */ 8000,
/*.bits_per_second */ 128000, /*.bits_per_second */ 128000,
/*.nanoseconds_per_frame */ 20000, /*.nanoseconds_per_frame */ 20000,
/*.samples_per_frame */ 160, /*.samples_per_frame */ 160,
/*.bytes_per_frame */ 320, /*.bytes_per_frame */ 320,
/*.encoded_bytes_per_frame */ 320, /*.encoded_bytes_per_frame */ 29,
/*.number_of_channels */ 1, /*.number_of_channels */ 1,
/*.pref_frames_per_packet */ 1, /*.pref_frames_per_packet */ 1,
/*.max_frames_per_packet */ 1, /*.max_frames_per_packet */ 1,

View File

@ -1007,7 +1007,7 @@ static char *find_reg_url(switch_core_db_t *db, char *key, char *val, switch_siz
struct callback_t cbt = {0}; struct callback_t cbt = {0};
char buf[1024]; char buf[1024];
char *host = NULL; char *host = NULL;
if (db) { if (db) {
udb = db; udb = db;
} else { } else {
@ -1028,6 +1028,7 @@ static char *find_reg_url(switch_core_db_t *db, char *key, char *val, switch_siz
} else { } else {
snprintf(val, len, "select url from sip_registrations where key='%s'", key); snprintf(val, len, "select url from sip_registrations where key='%s'", key);
} }
switch_core_db_exec(udb, val, find_callback, &cbt, &errmsg); switch_core_db_exec(udb, val, find_callback, &cbt, &errmsg);
if (errmsg) { if (errmsg) {

View File

@ -662,28 +662,43 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_
const switch_codec_implementation_t *imp; const switch_codec_implementation_t *imp;
for (x = 0; x < preflen; x++) { for (x = 0; x < preflen; x++) {
char *name, *p, buf[128]; char *cur, *last = NULL, *next = NULL, *name, *p, buf[256];
uint32_t interval = 0, len = 0; uint32_t interval = 0, rate = 0;
name = prefs[x]; switch_copy_string(buf, prefs[x], sizeof(buf));
if ((p = strchr(name, '@'))) { last = name = next = cur = buf;
p++;
len = (uint32_t)(p-name);
if (len > sizeof(buf)) { for (;;) {
len = sizeof(buf); if (!next) {
} break;
switch_copy_string(buf, name, len); }
*(buf + len) = '\0'; if ((p = strchr(next, '@'))) {
interval = atoi(p); *p++ = '\0';
name = buf; }
} next = p;
if (cur != name) {
if (strchr(cur, 'i')) {
interval = atoi(cur);
} else if (strchr(cur, 'k')) {
rate = atoi(cur);
}
}
cur = next;
}
if ((codec_interface = switch_loadable_module_get_codec_interface(name)) != 0 ) { if ((codec_interface = switch_loadable_module_get_codec_interface(name)) != 0 ) {
for (imp = codec_interface->implementations; imp; imp = imp->next) { for (imp = codec_interface->implementations; imp; imp = imp->next) {
if (!interval) { uint8_t match = 1;
array[i++] = imp;
} else if ((uint32_t)(imp->microseconds_per_frame / 1000) == interval) { if (interval && (uint32_t)(imp->microseconds_per_frame / 1000) != interval) {
match = 0;
}
if (match && rate && (uint32_t)imp->samples_per_second != rate) {
match = 0;
}
if (match) {
array[i++] = imp; array[i++] = imp;
} }
} }