Freeswitch conference audio recording

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

Guess you like

Origin blog.csdn.net/weixin_44991625/article/details/107615391