前言

image.png

代码分析

创建AudioDeviceBuffer的流程

image.png

  1. void WebRtcVoiceEngine::Init() {
  2. ***
  3. // 4、创建ADM
  4. #if defined(WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE)
  5. // No ADM supplied? Create a default one.
  6. if (!adm_) {
  7. adm_ = webrtc::AudioDeviceModule::Create(
  8. webrtc::AudioDeviceModule::kPlatformDefaultAudio, task_queue_factory_);
  9. }
  10. #endif // WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE
  11. RTC_CHECK(adm());
  12. ****
  13. }

—》

  1. rtc::scoped_refptr<AudioDeviceModule> AudioDeviceModule::Create(
  2. AudioLayer audio_layer,
  3. TaskQueueFactory* task_queue_factory) {
  4. RTC_DLOG(INFO) << __FUNCTION__;
  5. return AudioDeviceModule::CreateForTest(audio_layer, task_queue_factory);
  6. }

—》

  1. rtc::scoped_refptr<AudioDeviceModuleForTest> AudioDeviceModule::CreateForTest(
  2. AudioLayer audio_layer,
  3. TaskQueueFactory* task_queue_factory) {
  4. ****
  5. // Create the generic reference counted (platform independent) implementation.
  6. rtc::scoped_refptr<AudioDeviceModuleImpl> audioDevice(
  7. new rtc::RefCountedObject<AudioDeviceModuleImpl>(audio_layer,
  8. task_queue_factory));
  9. **
  10. }

—》

  1. AudioDeviceModuleImpl::AudioDeviceModuleImpl(
  2. AudioLayer audio_layer,
  3. TaskQueueFactory* task_queue_factory)
  4. : audio_layer_(audio_layer), audio_device_buffer_(task_queue_factory) {
  5. RTC_DLOG(INFO) << __FUNCTION__;
  6. }
  7. AudioDeviceBuffer audio_device_buffer_;

—》

  1. AudioDeviceBuffer::AudioDeviceBuffer(TaskQueueFactory* task_queue_factory)
  2. : task_queue_(task_queue_factory->CreateTaskQueue(
  3. kTimerQueueName,
  4. TaskQueueFactory::Priority::NORMAL)),
  5. audio_transport_cb_(nullptr),
  6. rec_sample_rate_(0),
  7. play_sample_rate_(0),
  8. rec_channels_(0),
  9. play_channels_(0),
  10. playing_(false),
  11. recording_(false),
  12. typing_status_(false),
  13. play_delay_ms_(0),
  14. rec_delay_ms_(0),
  15. num_stat_reports_(0),
  16. last_timer_task_time_(0),
  17. rec_stat_count_(0),
  18. play_stat_count_(0),
  19. play_start_time_(0),
  20. only_silence_recorded_(true),
  21. log_stats_(false) {
  22. RTC_LOG(INFO) << "AudioDeviceBuffer::ctor";
  23. #ifdef AUDIO_DEVICE_PLAYS_SINUS_TONE
  24. phase_ = 0.0;
  25. RTC_LOG(WARNING) << "AUDIO_DEVICE_PLAYS_SINUS_TONE is defined!";
  26. #endif
  27. }

注册回调RegisterAudioCallback

image.png

  1. void WebRtcVoiceEngine::Init() {
  2. ***
  3. // 7、 Connect the ADM to our audio path.
  4. // 注册回调,采集到音频数据后,由audio_transport()传输
  5. adm()->RegisterAudioCallback(audio_state()->audio_transport());
  6. ***
  7. }

—》

  1. int32_t AudioDeviceModuleImpl::RegisterAudioCallback(
  2. AudioTransport* audioCallback) {
  3. RTC_LOG(INFO) << __FUNCTION__;
  4. return audio_device_buffer_.RegisterAudioCallback(audioCallback);
  5. }

—》

  1. int32_t AudioDeviceBuffer::RegisterAudioCallback(
  2. AudioTransport* audio_callback) {
  3. RTC_DCHECK_RUN_ON(&main_thread_checker_);
  4. RTC_DLOG(INFO) << __FUNCTION__;
  5. if (playing_ || recording_) {
  6. RTC_LOG(LS_ERROR) << "Failed to set audio transport since media was active";
  7. return -1;
  8. }
  9. audio_transport_cb_ = audio_callback;
  10. return 0;
  11. }

传递数据

就是采集到音频数据后,调用上一步的回调。
image.png
image.png
AudioDeviceWindowsCore::DoCaptureThreadPollDMO

  1. DWORD AudioDeviceWindowsCore::DoCaptureThreadPollDMO() {
  2. ****
  3. ULONG bytesProduced = 0;
  4. BYTE* data;
  5. // Get a pointer to the data buffer. This should be valid until
  6. // the next call to ProcessOutput.
  7. // 获取buffer数据和数据大小
  8. // bytesProduced=320,因为设置输出采样率16000,每个采样2个字节,每次采集10ms数据
  9. hr = _mediaBuffer->GetBufferAndLength(&data, &bytesProduced);
  10. if (FAILED(hr)) {
  11. _TraceCOMError(hr);
  12. keepRecording = false;
  13. assert(false);
  14. break;
  15. }
  16. if (bytesProduced > 0) {
  17. //断点值 160 = 320/2
  18. const int kSamplesProduced = bytesProduced / _recAudioFrameSize;
  19. // TODO(andrew): verify that this is always satisfied. It might
  20. // be that ProcessOutput will try to return more than 10 ms if
  21. // we fail to call it frequently enough.
  22. assert(kSamplesProduced == static_cast<int>(_recBlockSize));
  23. assert(sizeof(BYTE) == sizeof(int8_t));
  24. _ptrAudioBuffer->SetRecordedBuffer(reinterpret_cast<int8_t*>(data),
  25. kSamplesProduced);
  26. _ptrAudioBuffer->SetVQEData(0, 0);
  27. _UnLock(); // Release lock while making the callback.
  28. // 将数据输送到上层逻辑去处理
  29. _ptrAudioBuffer->DeliverRecordedData();
  30. _Lock();
  31. }
  32. ****
  33. }

—》

  1. int32_t AudioDeviceBuffer::DeliverRecordedData() {
  2. if (!audio_transport_cb_) {
  3. RTC_LOG(LS_WARNING) << "Invalid audio transport";
  4. return 0;
  5. }
  6. const size_t frames = rec_buffer_.size() / rec_channels_;
  7. const size_t bytes_per_frame = rec_channels_ * sizeof(int16_t);
  8. uint32_t new_mic_level_dummy = 0;
  9. uint32_t total_delay_ms = play_delay_ms_ + rec_delay_ms_;
  10. int32_t res = audio_transport_cb_->RecordedDataIsAvailable(
  11. rec_buffer_.data(), frames, bytes_per_frame, rec_channels_,
  12. rec_sample_rate_, total_delay_ms, 0, 0, typing_status_,
  13. new_mic_level_dummy);
  14. if (res == -1) {
  15. RTC_LOG(LS_ERROR) << "RecordedDataIsAvailable() failed";
  16. }
  17. return 0;
  18. }

—》

  1. // Not used in Chromium. Process captured audio and distribute to all sending
  2. // streams, and try to do this at the lowest possible sample rate.
  3. int32_t AudioTransportImpl::RecordedDataIsAvailable(
  4. const void* audio_data,
  5. const size_t number_of_frames,
  6. const size_t bytes_per_sample,
  7. const size_t number_of_channels,
  8. const uint32_t sample_rate,
  9. const uint32_t audio_delay_milliseconds,
  10. const int32_t /*clock_drift*/,
  11. const uint32_t /*volume*/,
  12. const bool key_pressed,
  13. uint32_t& /*new_mic_volume*/) { // NOLINT: to avoid changing APIs
  14. RTC_DCHECK(audio_data);
  15. RTC_DCHECK_GE(number_of_channels, 1);
  16. RTC_DCHECK_LE(number_of_channels, 2);
  17. RTC_DCHECK_EQ(2 * number_of_channels, bytes_per_sample);
  18. RTC_DCHECK_GE(sample_rate, AudioProcessing::NativeRate::kSampleRate8kHz);
  19. // 100 = 1 second / data duration (10 ms).
  20. RTC_DCHECK_EQ(number_of_frames * 100, sample_rate);
  21. RTC_DCHECK_LE(bytes_per_sample * number_of_frames * number_of_channels,
  22. AudioFrame::kMaxDataSizeBytes);
  23. int send_sample_rate_hz = 0;
  24. size_t send_num_channels = 0;
  25. bool swap_stereo_channels = false;
  26. {
  27. MutexLock lock(&capture_lock_);
  28. send_sample_rate_hz = send_sample_rate_hz_;
  29. send_num_channels = send_num_channels_;
  30. swap_stereo_channels = swap_stereo_channels_;
  31. }
  32. std::unique_ptr<AudioFrame> audio_frame(new AudioFrame());
  33. InitializeCaptureFrame(sample_rate, send_sample_rate_hz, number_of_channels,
  34. send_num_channels, audio_frame.get());
  35. voe::RemixAndResample(static_cast<const int16_t*>(audio_data),
  36. number_of_frames, number_of_channels, sample_rate,
  37. &capture_resampler_, audio_frame.get());
  38. ProcessCaptureFrame(audio_delay_milliseconds, key_pressed,
  39. swap_stereo_channels, audio_processing_,
  40. audio_frame.get());
  41. // Typing detection (utilizes the APM/VAD decision). We let the VAD determine
  42. // if we're using this feature or not.
  43. // TODO(solenberg): GetConfig() takes a lock. Work around that.
  44. bool typing_detected = false;
  45. if (audio_processing_ &&
  46. audio_processing_->GetConfig().voice_detection.enabled) {
  47. if (audio_frame->vad_activity_ != AudioFrame::kVadUnknown) {
  48. bool vad_active = audio_frame->vad_activity_ == AudioFrame::kVadActive;
  49. typing_detected = typing_detection_.Process(key_pressed, vad_active);
  50. }
  51. }
  52. // Copy frame and push to each sending stream. The copy is required since an
  53. // encoding task will be posted internally to each stream.
  54. {
  55. MutexLock lock(&capture_lock_);
  56. typing_noise_detected_ = typing_detected;
  57. }
  58. RTC_DCHECK_GT(audio_frame->samples_per_channel_, 0);
  59. if (async_audio_processing_)
  60. async_audio_processing_->Process(std::move(audio_frame));
  61. else
  62. SendProcessedData(std::move(audio_frame));
  63. return 0;
  64. }

里面调用ProcessCaptureFrame里面是进行音频的3A数据处理。。