Take audio data from member->session->channel, do resampling, switch_buffer_write writes into member->audio_buffer, and the data will mux in the current conference thread of the conference.
Mixing in the conference thread: read data from audio_buffer, write the mixed data to each member's omember->mux_buffer through switch_buffer_write. The mixed data is
taken out from member/mux_buffer, and switch_core_session_write_frame is written back to the member channel.
Audio processing process:
Audio acquisition and resampling-"mix audio input-"mix-"mix output-"write to member
Three important buffers
in the whole process: the memory allocated in the function conference_member_setup_media:
=>switch_buffer_create_dynamic(&member->resample_buffer //Resample buffer
=>switch_buffer_create_dynamic(&member->audio_buffer //input buffer
=>switch_buffer_create_dynamic(&member-> mux_buffer //output buffer
1. Audio acquisition and resampling:
Start [input thread] in the output thread: conference_loop_launch_input(member, switch_core_session_get_pool(member->session));
conference_loop_input is a thread, conference_loop_output is a loop.
从member->session->channel 拿 audio数据,做重采样处理
=》conference_loop_launch_input
=>conference_loop_input
=>switch_core_session_read_frame
=>switch_resample_process
=>switch_buffer_write(member->audio_buffer, tmp_frame.data, tmp_frame.datalen);
2. Mixing audio input:
conference_thread_run
=》ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes);
switch_buffer_write writes to member->audio_buffer, the data will be mux in the current conference thread of the conference
3. Mixing:
conference_thread_run
copies the audio of each member who is known to be producing audio into the main frame (mux?):
for (omember = conference->members; omember; omember = omember->next) { conference->member_loop_count++;
if (!(conference_utils_member_test_flag(omember, MFLAG_RUNNING) && conference_utils_member_test_flag(omember, MFLAG_HAS_AUDIO))) {
continue;
}
bptr = (int16_t *) omember->frame;
for (x = 0; x < omember->read / 2; x++) {
main_frame[x] += (int32_t) bptr[x];
}
}
Next, process the capabilities of each member separately:
conference_utils_member_test_flag(imember, MFLAG_HAS_AUDIO)
switch_test_flag(rel, RFLAG_CAN_SPEAK)
switch_test_flag(rel, RFLAG_CAN_HEAR)
//In order to maintain the accuracy of sampling samples, the main frame uses 32 bits. Here is the conversion of 32 bits to 16 bits?
switch_normalize_to_16bit(z);
write_frame[x] = (int16_t) z;
The conference_thread_run thread judges whether the member has audio capability by reading the audio_buffer of each member:
switch_buffer_read(imember->audio_buffer, imember->frame, bytes)
conference_utils_member_set_flag_locked(imember, MFLAG_HAS_AUDIO);
ready++;
later will be made according to the judgment of ready Different operations
if available:
read data from audio_buffer, write the mixed data to each member's omember->mux_buffer through switch_buffer_write,
if not available:
ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes);
4. Mix audio output
The data after mixing is taken out from member/mux_buffer
ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes);
5. Write back to the member channel
conference_loop_output
=》switch_core_session_write_frame