声音的采集:
void FakeAudioDevice::ProcessAudio() {
if (capturing_) {
// Capture 10ms of audio. 2 bytes per sample.
const bool keep_capturing = capturer_->Capture(&recording_buffer_);
uint32_t new_mic_level;
if (recording_buffer_.size() > 0) {
audio_callback_->RecordedDataIsAvailable(
recording_buffer_.data(), recording_buffer_.size(), 2, 1,
capturer_->SamplingFrequency(), 0, 0, 0, false, new_mic_level);
}
}
}
AudioFrame与recording_buffer_的转换方法:
1 recording_buffer_转换为AudioFrame:
int32_t AudioTransportImpl::RecordedDataIsAvailable(
const void* audio_data,
const size_t number_of_frames,
const size_t bytes_per_sample,
const size_t number_of_channels,
const uint32_t sample_rate,
const uint32_t audio_delay_milliseconds,
const int32_t /*clock_drift*/,
const uint32_t volume,
const bool key_pressed,
uint32_t& /*new_mic_volume*/) { // NOLINT: to avoid changing APIs
std::unique_ptr<AudioFrame> audio_frame(new AudioFrame());
InitializeCaptureFrame(sample_rate, send_sample_rate_hz,
number_of_channels, send_num_channels,
audio_frame.get());
voe::RemixAndResample(static_cast<const int16_t*>(audio_data),
number_of_frames, number_of_channels, sample_rate,
&capture_resampler_, audio_frame.get());
ProcessCaptureFrame(voe_mic_level, audio_delay_milliseconds, key_pressed,
swap_stereo_channels, audio_processing_,
audio_frame.get());
}
2 AudioFrame转换为recording_buffer_
void CaptureStreamInfo::AddOutput(const AudioFrame& frame) {
RTC_DCHECK(task_);
auto* stream = task_->GetEvent()->mutable_stream();
const size_t data_size =
sizeof(int16_t) * frame.samples_per_channel_ * frame.num_channels_;
stream->set_output_data(frame.data(), data_size);
}
声音处理主过程:
int AudioProcessingImpl::ProcessStream(AudioFrame* frame) {
if (aec_dump_) {
RecordUnprocessedCaptureStream(*frame);
}
capture_.capture_audio->DeinterleaveFrom(frame);
RETURN_ON_ERR(ProcessCaptureStreamLocked());
capture_.capture_audio->InterleaveTo(
frame, submodule_states_.CaptureMultiBandProcessingActive() ||
submodule_states_.CaptureFullBandProcessingActive());
if (aec_dump_) {
RecordProcessedCaptureStream(*frame);
}
}
解交织(多声道处理)处理函数:
void AudioBuffer::DeinterleaveFrom(AudioFrame* frame) {
int16_t* const* deinterleaved;
if (input_num_frames_ == proc_num_frames_) {
deinterleaved = data_->ibuf()->channels();
} else {
deinterleaved = input_buffer_->ibuf()->channels();
}
if (num_proc_channels_ == 1) {
// Downmix and deinterleave simultaneously.
DownmixInterleavedToMono(frame->data(), input_num_frames_,
num_input_channels_, deinterleaved[0]);
} else {
Deinterleave(frame->data(),
input_num_frames_,
num_proc_channels_,
deinterleaved);
}
// Resample.
if (input_num_frames_ != proc_num_frames_) {
for (size_t i = 0; i < num_proc_channels_; ++i) {
input_resamplers_[i]->Resample(input_buffer_->fbuf_const()->channels()[i],
input_num_frames_,
data_->fbuf()->channels()[i],
proc_num_frames_);
}
}
}
统一到单声道处理方法:
template <typename T, typename Intermediate>
void DownmixInterleavedToMonoImpl(const T* interleaved,
size_t num_frames,
int num_channels,
T* deinterleaved) {
const T* const end = interleaved + num_frames * num_channels;
while (interleaved < end) {
const T* const frame_end = interleaved + num_channels;
Intermediate value = *interleaved++;
while (interleaved < frame_end) {
value += *interleaved++;
}
*deinterleaved++ = value / num_channels;
}
}
精简版AudioProcessingImpl类定义
class AudioProcessingImpl : public AudioProcessing {
public:
int ProcessCaptureStreamLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
struct ApmCaptureState {
std::unique_ptr<AudioBuffer> capture_audio;
} capture_ RTC_GUARDED_BY(crit_capture_);
};
精简版AudioBuffer类定义
class AudioBuffer {
public:
void DeinterleaveFrom(AudioFrame* audioFrame);
void InterleaveTo(AudioFrame* frame, bool data_changed) const;
private:
std::unique_ptr<IFChannelBuffer> data_;
};