mix member play file data in with conference so you can hear the bg while hearing the member file
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16408 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
010fa529c8
commit
2ddd9904b2
|
@ -2031,6 +2031,82 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void member_add_file_data(conference_member_t *member, int16_t *data, switch_size_t file_data_len)
|
||||
{
|
||||
switch_size_t file_sample_len = file_data_len / 2;
|
||||
int16_t file_frame[SWITCH_RECOMMENDED_BUFFER_SIZE/2] = {0};
|
||||
|
||||
if (!member->fnode) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if we are done, clean it up */
|
||||
if (member->fnode->done) {
|
||||
conference_file_node_t *fnode;
|
||||
switch_memory_pool_t *pool;
|
||||
|
||||
if (member->fnode->type != NODE_TYPE_SPEECH) {
|
||||
switch_core_file_close(&member->fnode->fh);
|
||||
}
|
||||
|
||||
fnode = member->fnode;
|
||||
member->fnode = member->fnode->next;
|
||||
|
||||
pool = fnode->pool;
|
||||
fnode = NULL;
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
} else {
|
||||
/* skip this frame until leadin time has expired */
|
||||
if (member->fnode->leadin) {
|
||||
member->fnode->leadin--;
|
||||
} else {
|
||||
if (member->fnode->type == NODE_TYPE_SPEECH) {
|
||||
switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_BLOCKING;
|
||||
|
||||
if (switch_core_speech_read_tts(member->fnode->sh, file_frame, &file_data_len, &flags) == SWITCH_STATUS_SUCCESS) {
|
||||
file_sample_len = file_data_len / 2;
|
||||
} else {
|
||||
file_sample_len = file_data_len = 0;
|
||||
}
|
||||
} else if (member->fnode->type == NODE_TYPE_FILE) {
|
||||
switch_core_file_read(&member->fnode->fh, file_frame, &file_sample_len);
|
||||
file_data_len = file_sample_len * 2;
|
||||
}
|
||||
|
||||
if (file_sample_len <= 0) {
|
||||
switch_event_t *event;
|
||||
member->fnode->done++;
|
||||
|
||||
if (test_eflag(member->conference, EFLAG_PLAY_FILE) &&
|
||||
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
|
||||
conference_add_event_data(member->conference, event);
|
||||
conference_add_event_member_data(member, event);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member-done");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", member->fnode->file);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
} else { /* there is file node data to mix into the frame */
|
||||
int32_t i, sample;
|
||||
|
||||
/* Check for output volume adjustments */
|
||||
if (member->volume_out_level) {
|
||||
switch_change_sln_volume(file_frame, file_sample_len, member->volume_out_level);
|
||||
}
|
||||
|
||||
for(i = 0; i < file_sample_len; i++) {
|
||||
sample = data[i] + file_frame[i];
|
||||
switch_normalize_to_16bit(sample);
|
||||
data[i] = sample;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* launch an input thread for the call leg */
|
||||
static void launch_conference_loop_input(conference_member_t *member, switch_memory_pool_t *pool)
|
||||
{
|
||||
|
@ -2196,14 +2272,12 @@ static void conference_loop_output(conference_member_t *member)
|
|||
while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD)
|
||||
&& switch_channel_ready(channel)) {
|
||||
char dtmf[128] = "";
|
||||
uint8_t file_frame[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
|
||||
char *digit;
|
||||
switch_event_t *event;
|
||||
caller_control_action_t *caller_action = NULL;
|
||||
int use_timer = 0;
|
||||
switch_size_t file_sample_len = csamples;
|
||||
switch_size_t file_data_len = file_sample_len * 2;
|
||||
|
||||
switch_buffer_t *use_buffer = NULL;
|
||||
uint32_t mux_used = 0;
|
||||
|
||||
switch_mutex_lock(member->write_mutex);
|
||||
|
||||
|
@ -2287,73 +2361,9 @@ static void conference_loop_output(conference_member_t *member)
|
|||
caller_action = NULL;
|
||||
}
|
||||
|
||||
/* handle file and TTS frames */
|
||||
if (member->fnode) {
|
||||
/* if we are done, clean it up */
|
||||
if (member->fnode->done) {
|
||||
conference_file_node_t *fnode;
|
||||
switch_memory_pool_t *pool;
|
||||
|
||||
if (member->fnode->type != NODE_TYPE_SPEECH) {
|
||||
switch_core_file_close(&member->fnode->fh);
|
||||
}
|
||||
|
||||
fnode = member->fnode;
|
||||
member->fnode = member->fnode->next;
|
||||
|
||||
pool = fnode->pool;
|
||||
fnode = NULL;
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
} else {
|
||||
/* skip this frame until leadin time has expired */
|
||||
if (member->fnode->leadin) {
|
||||
member->fnode->leadin--;
|
||||
} else { /* send the node frame instead of the conference frame to the call leg */
|
||||
if (member->fnode->type == NODE_TYPE_SPEECH) {
|
||||
switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_BLOCKING;
|
||||
|
||||
if (switch_core_speech_read_tts(member->fnode->sh, file_frame, &file_data_len, &flags) == SWITCH_STATUS_SUCCESS) {
|
||||
file_sample_len = file_data_len / 2;
|
||||
} else {
|
||||
file_sample_len = file_data_len = 0;
|
||||
}
|
||||
} else if (member->fnode->type == NODE_TYPE_FILE) {
|
||||
switch_core_file_read(&member->fnode->fh, file_frame, &file_sample_len);
|
||||
file_data_len = file_sample_len * 2;
|
||||
}
|
||||
|
||||
if (file_sample_len <= 0) {
|
||||
member->fnode->done++;
|
||||
|
||||
if (test_eflag(member->conference, EFLAG_PLAY_FILE) &&
|
||||
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
|
||||
conference_add_event_data(member->conference, event);
|
||||
conference_add_event_member_data(member, event);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member-done");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", member->fnode->file);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
} else { /* there is file node data to deliver */
|
||||
write_frame.data = file_frame;
|
||||
write_frame.datalen = (uint32_t) file_data_len;
|
||||
write_frame.samples = (uint32_t) file_sample_len;
|
||||
/* Check for output volume adjustments */
|
||||
if (member->volume_out_level) {
|
||||
switch_change_sln_volume(write_frame.data, write_frame.samples, member->volume_out_level);
|
||||
}
|
||||
write_frame.timestamp = timer.samplecount;
|
||||
switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
switch_core_timer_next(&timer);
|
||||
|
||||
|
||||
/* forget the conference data we played file node data instead */
|
||||
switch_set_flag_locked(member, MFLAG_FLUSH_BUFFER);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch_buffer_t *use_buffer = NULL;
|
||||
uint32_t mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer);
|
||||
use_buffer = NULL;
|
||||
mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer);
|
||||
|
||||
if (mux_used) {
|
||||
if (mux_used < bytes) {
|
||||
|
@ -2385,11 +2395,20 @@ static void conference_loop_output(conference_member_t *member)
|
|||
switch_change_sln_volume(write_frame.data, write_frame.samples, member->volume_out_level);
|
||||
}
|
||||
write_frame.timestamp = timer.samplecount;
|
||||
if (member->fnode) {
|
||||
member_add_file_data(member, write_frame.data, write_frame.datalen);
|
||||
}
|
||||
switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
switch_mutex_unlock(member->audio_out_mutex);
|
||||
} else if (member->fnode) {
|
||||
write_frame.datalen = bytes;
|
||||
write_frame.samples = samples;
|
||||
memset(write_frame.data, 255, write_frame.datalen);
|
||||
member_add_file_data(member, write_frame.data, write_frame.datalen);
|
||||
switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
} else if (!switch_test_flag(member->conference, CFLAG_WASTE_BANDWIDTH)) {
|
||||
if (switch_test_flag(member, MFLAG_WASTE_BANDWIDTH)) {
|
||||
if (member->conference->comfort_noise_level) {
|
||||
|
@ -2397,13 +2416,14 @@ static void conference_loop_output(conference_member_t *member)
|
|||
} else {
|
||||
memset(write_frame.data, 255, bytes);
|
||||
}
|
||||
|
||||
write_frame.datalen = bytes;
|
||||
write_frame.samples = samples;
|
||||
write_frame.timestamp = timer.samplecount;
|
||||
|
||||
switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (switch_test_flag(member, MFLAG_FLUSH_BUFFER)) {
|
||||
if (switch_buffer_inuse(member->mux_buffer)) {
|
||||
|
|
Loading…
Reference in New Issue