git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16119 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2010-01-02 16:57:36 +00:00
parent fb99b2ea2c
commit e8060a8140
1 changed files with 79 additions and 154 deletions

View File

@ -1152,8 +1152,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
has_file_data = 1;
}
if (!conference->relationship_total) {
/* If there are no relationships meaning (user x can specificly not speal to and/or hear user y), use a more efficient muxing technique. */
if (ready || has_file_data) {
/* Use more bits in the main_frame to preserve the exact sum of the audio samples. */
int main_frame[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
@ -1207,6 +1206,28 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
if (switch_test_flag(omember, MFLAG_HAS_AUDIO) && x <= omember->read / 2) {
z -= (int32_t) bptr[x];
}
/* when there are relationships, we have to do more work by scouring all the members to see if there are any
reasons why we should not be hearing a paticular member, and if not, delete their samples as well.
*/
if (conference->relationship_total) {
for (imember = conference->members; imember; imember = imember->next) {
conference_relationship_t *rel;
for (rel = imember->relationships; rel; rel = rel->next) {
if (imember != omember && switch_test_flag(imember, MFLAG_HAS_AUDIO)) {
int16_t *rptr = (int16_t *) imember->frame;
if ((rel->id == omember->id || rel->id == 0) && !switch_test_flag(rel, RFLAG_CAN_SPEAK)) {
z -= (int32_t) rptr[x];
}
if ((rel->id == imember->id || rel->id == 0) && !switch_test_flag(rel, RFLAG_CAN_HEAR)) {
z -= (int32_t) rptr[x];
}
}
}
}
}
/* Now we can convert to 16 bit.*/
switch_normalize_to_16bit(z);
write_frame[x] = (int16_t) z;
@ -1220,102 +1241,6 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
goto end;
}
}
}
} else {
if (ready || has_file_data) {
/* Build a muxed frame for every member that contains the mixed audio of everyone else */
for (omember = conference->members; omember; omember = omember->next) {
if (has_file_data && file_sample_len) {
uint32_t sample_bytes = file_sample_len * 2;
memcpy(omember->mux_frame, file_frame, sample_bytes);
if (sample_bytes < bytes) {
if (conference->comfort_noise_level) {
switch_generate_sln_silence((int16_t *) omember->mux_frame + sample_bytes,
(bytes - sample_bytes) / 2, conference->comfort_noise_level);
} else {
memset(omember->mux_frame + sample_bytes, 255, bytes - sample_bytes);
}
}
} else {
if (conference->comfort_noise_level) {
switch_generate_sln_silence((int16_t *) omember->mux_frame, bytes / 2, conference->comfort_noise_level);
} else {
memset(omember->mux_frame, 255, bytes);
}
}
for (imember = conference->members; imember; imember = imember->next) {
uint32_t x;
int16_t *muxed;
if (imember == omember || !imember->read) {
/* Don't add audio from yourself or if you didn't read any */
continue;
}
/* If they are not supposed to talk to us then don't let them */
if (omember->relationships) {
conference_relationship_t *rel;
if ((rel = member_get_relationship(omember, imember))) {
if (!switch_test_flag(rel, RFLAG_CAN_HEAR)) {
continue;
}
}
}
/* If we are not supposed to hear them then don't let it happen */
if (imember->relationships) {
conference_relationship_t *rel;
if ((rel = member_get_relationship(imember, omember))) {
if (!switch_test_flag(rel, RFLAG_CAN_SPEAK)) {
continue;
}
}
}
#if 0
if (nt && conference->not_talking_buf_len && !switch_test_flag(omember, MFLAG_HAS_AUDIO)) {
memcpy(omember->mux_frame, conference->not_talking_buf, conference->not_talking_buf_len);
continue;
}
#endif
bptr = (int16_t *) imember->frame;
muxed = (int16_t *) omember->mux_frame;
for (x = 0; x < imember->read / 2; x++) {
int32_t z = muxed[x] + bptr[x];
switch_normalize_to_16bit(z);
muxed[x] = (int16_t) z;
}
#if 0
if (total - ready > 1) {
conference->not_talking_buf_len = imember->read;
if (!conference->not_talking_buf) {
conference->not_talking_buf = switch_core_alloc(conference->pool, imember->read + 128);
}
memcpy(conference->not_talking_buf, muxed, conference->not_talking_buf_len);
nt++;
}
#endif
}
}
if (bytes) {
/* Go back and write each member his dedicated copy of the audio frame that does not contain his own audio. */
for (imember = conference->members; imember; imember = imember->next) {
if (switch_test_flag(imember, MFLAG_RUNNING)) {
switch_size_t ok = 1;
switch_mutex_lock(imember->audio_out_mutex);
ok = switch_buffer_write(imember->mux_buffer, imember->mux_frame, bytes);
switch_mutex_unlock(imember->audio_out_mutex);
if (!ok) {
goto end;
}
}
}
}
}
}
if (conference->async_fnode && conference->async_fnode->done) {