webrtc audio

诸修伟
2023-12-01

音频的基本概念

        采样频率

        单位时间内对模拟信号的采样次数。采样频率越高,声音的还原就越真实越自然,当然数据量就越大。采样率根据使用类型不同大概有以下几种:

8khz:电话等使用,对于记录人声已经足够使用。
22.05khz:广播使用频率。
44.1khz:音频CD。
48khz:DVD、数字电视中使用。
96khz-192khz:DVD-Audio、蓝光高清等使用。
采样精度常用范围为 8bit-32bit,而 CD 中一般都使用 16bit。
        采样位数

        采样位数,也称量化级、样本尺寸、量化数据位数,指每个采样点能够表示的数据范围,它以位(Bit)为单位。采样位数通常有 8bits 或 16bits 两种,采样位数越大,所能记录声音的变化度就越细腻,相应的数据量就越大。8 位字长量化(低品质)和 16 位字长量化(高品质),16 bit 是最常见的采样精度。
        声道数

        声道数是指支持能不同发声的音响的个数,它是衡量音响设备的重要指标之一。
        量化

       将采样后离散信号的幅度用二进制数表示出来的过程称为量化。(日常生活所说的量化,就是设定一个范围或者区间,然后看获取到的数据在这个条件内的收集出来)。
        编码

        采样和量化后的信号还不是数字信号,需要将它转化为数字编码脉冲,这一过程称为编码。模拟音频进采样、量化和编码后形成的二进制序列就是数字音频信号。
        PCM

        PCM(Pulse Code Modulation),即脉冲编码调制,对声音进行采样、量化过程,未经过任何编码和压缩处理。
        比特率

        比特率(也称位速、比特率),是指在一个数据流中每秒钟能通过的信息量,代表了压缩质量。比如 MP3 常用码率有 128kbit/s、160kbit/s、320kbit/s 等等,越高代表着声音音质越好。

        比特率 = 采样率 × 采样深度 × 通道数。比如 采样率 = 44100,采样深度 = 16,通道 = 2 的音频的的比特率就是 44100 * 16 * 2 = 1411200 bps。

AudioDeviceModule

           AudioDeviceModule是一个抽象类,定义了音频相关的接口,如设备枚举(Device enumeration)、设备选择(Device selection)、扬声器音量控制(Speaker volume controls)、麦克风音量控制(Microphone volume controls)、扬声器静音控制(Speaker mute control)、麦克风静音控制(Microphone mute control)、立体声支持( Stereo support)和音频传输设置(Audio transport control)等。

#ifndef MODULES_AUDIO_DEVICE_INCLUDE_AUDIO_DEVICE_H_
#define MODULES_AUDIO_DEVICE_INCLUDE_AUDIO_DEVICE_H_

#include "modules/audio_device/include/audio_device_defines.h"
#include "rtc_base/scoped_ref_ptr.h"
#include "rtc_base/refcount.h"

namespace webrtc {

class AudioDeviceModule : public rtc::RefCountInterface {
 public:
  // Deprecated.
  // TODO(henrika): to be removed.
  enum ErrorCode {
    kAdmErrNone = 0,
    kAdmErrArgument = 1
  };

  enum AudioLayer {
    kPlatformDefaultAudio = 0,
    kWindowsCoreAudio = 2,
    kLinuxAlsaAudio = 3,
    kLinuxPulseAudio = 4,
    kAndroidJavaAudio = 5,
    kAndroidOpenSLESAudio = 6,
    kAndroidJavaInputAndOpenSLESOutputAudio = 7,
    kAndroidAAudioAudio = 8,
    kAndroidJavaInputAndAAudioOutputAudio = 9,
    kDummyAudio = 10
  };

  enum WindowsDeviceType {
    kDefaultCommunicationDevice = -1,
    kDefaultDevice = -2
  };

  // TODO(bugs.webrtc.org/7306): deprecated.
  enum ChannelType {
    kChannelLeft = 0,
    kChannelRight = 1,
    kChannelBoth = 2
  };

 public:
  // Creates an ADM.
  static rtc::scoped_refptr<AudioDeviceModule> Create(
      const AudioLayer audio_layer);
  // TODO(bugs.webrtc.org/7306): deprecated (to be removed).
  static rtc::scoped_refptr<AudioDeviceModule> Create(
      const int32_t id,
      const AudioLayer audio_layer);

  // Retrieve the currently utilized audio layer
  virtual int32_t ActiveAudioLayer(AudioLayer* audioLayer) const = 0;

  // Full-duplex transportation of PCM audio
  virtual int32_t RegisterAudioCallback(AudioTransport* audioCallback) = 0;

  // Main initialization and termination
  virtual int32_t Init() = 0;
  virtual int32_t Terminate() = 0;
  virtual bool Initialized() const = 0;

  // Device enumeration
  virtual int16_t PlayoutDevices() = 0;
  virtual int16_t RecordingDevices() = 0;
  virtual int32_t PlayoutDeviceName(uint16_t index,
                                    char name[kAdmMaxDeviceNameSize],
                                    char guid[kAdmMaxGuidSize]) = 0;
  virtual int32_t RecordingDeviceName(uint16_t index,
                                      char name[kAdmMaxDeviceNameSize],
                                      char guid[kAdmMaxGuidSize]) = 0;

  // Device selection
  virtual int32_t SetPlayoutDevice(uint16_t index) = 0;
  virtual int32_t SetPlayoutDevice(WindowsDeviceType device) = 0;
  virtual int32_t SetRecordingDevice(uint16_t index) = 0;
  virtual int32_t SetRecordingDevice(WindowsDeviceType device) = 0;

  // Audio transport initialization
  virtual int32_t PlayoutIsAvailable(bool* available) = 0;
  virtual int32_t InitPlayout() = 0;
  virtual bool PlayoutIsInitialized() const = 0;
  virtual int32_t RecordingIsAvailable(bool* available) = 0;
  virtual int32_t InitRecording() = 0;
  virtual bool RecordingIsInitialized() const = 0;

  // Audio transport control
  virtual int32_t StartPlayout() = 0;
  virtual int32_t StopPlayout() = 0;
  virtual bool Playing() const = 0;
  virtual int32_t StartRecording() = 0;
  virtual int32_t StopRecording() = 0;
  virtual bool Recording() const = 0;

  // Audio mixer initialization
  virtual int32_t InitSpeaker() = 0;
  virtual bool SpeakerIsInitialized() const = 0;
  virtual int32_t InitMicrophone() = 0;
  virtual bool MicrophoneIsInitialized() const = 0;

  // Speaker volume controls
  virtual int32_t SpeakerVolumeIsAvailable(bool* available) = 0;
  virtual int32_t SetSpeakerVolume(uint32_t volume) = 0;
  virtual int32_t SpeakerVolume(uint32_t* volume) const = 0;
  virtual int32_t MaxSpeakerVolume(uint32_t* maxVolume) const = 0;
  virtual int32_t MinSpeakerVolume(uint32_t* minVolume) const = 0;

  // Microphone volume controls
  virtual int32_t MicrophoneVolumeIsAvailable(bool* available) = 0;
  virtual int32_t SetMicrophoneVolume(uint32_t volume) = 0;
  virtual int32_t MicrophoneVolume(uint32_t* volume) const = 0;
  virtual int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const = 0;
  virtual int32_t MinMicrophoneVolume(uint32_t* minVolume) const = 0;

  // Speaker mute control
  virtual int32_t SpeakerMuteIsAvailable(bool* available) = 0;
  virtual int32_t SetSpeakerMute(bool enable) = 0;
  virtual int32_t SpeakerMute(bool* enabled) const = 0;

  // Microphone mute control
  virtual int32_t MicrophoneMuteIsAvailable(bool* available) = 0;
  virtual int32_t SetMicrophoneMute(bool enable) = 0;
  virtual int32_t MicrophoneMute(bool* enabled) const = 0;

  // Stereo support
  virtual int32_t StereoPlayoutIsAvailable(bool* available) const = 0;
  virtual int32_t SetStereoPlayout(bool enable) = 0;
  virtual int32_t StereoPlayout(bool* enabled) const = 0;
  virtual int32_t StereoRecordingIsAvailable(bool* available) const = 0;
  virtual int32_t SetStereoRecording(bool enable) = 0;
  virtual int32_t StereoRecording(bool* enabled) const = 0;

  // Playout delay
  virtual int32_t PlayoutDelay(uint16_t* delayMS) const = 0;

  // Only supported on Android.
  virtual bool BuiltInAECIsAvailable() const = 0;
  virtual bool BuiltInAGCIsAvailable() const = 0;
  virtual bool BuiltInNSIsAvailable() const = 0;

  // Enables the built-in audio effects. Only supported on Android.
  virtual int32_t EnableBuiltInAEC(bool enable) = 0;
  virtual int32_t EnableBuiltInAGC(bool enable) = 0;
  virtual int32_t EnableBuiltInNS(bool enable) = 0;

// Only supported on iOS.
#if defined(WEBRTC_IOS)
  virtual int GetPlayoutAudioParameters(AudioParameters* params) const = 0;
  virtual int GetRecordAudioParameters(AudioParameters* params) const = 0;
#endif  // WEBRTC_IOS

 protected:
  ~AudioDeviceModule() override {}
};

}  // namespace webrtc

#endif  // MODULES_AUDIO_DEVICE_INCLUDE_AUDIO_DEVICE_H_

          AudioTransport是个关键的对外接口,负责音频数据的传入(调用NeedMorePlayData方法,供Playout使用)和输出(调用RecordedDataIsAvailable方法,数据由Record采集操作产生)。

// ----------------------------------------------------------------------------
//  AudioTransport
// ----------------------------------------------------------------------------

class AudioTransport {
 public:
  virtual int32_t RecordedDataIsAvailable(const void* audioSamples,
                                          const size_t nSamples,
                                          const size_t nBytesPerSample,
                                          const size_t nChannels,
                                          const uint32_t samplesPerSec,
                                          const uint32_t totalDelayMS,
                                          const int32_t clockDrift,
                                          const uint32_t currentMicLevel,
                                          const bool keyPressed,
                                          uint32_t& newMicLevel) = 0;  // NOLINT

  // Implementation has to setup safe values for all specified out parameters.
  virtual int32_t NeedMorePlayData(const size_t nSamples,
                                   const size_t nBytesPerSample,
                                   const size_t nChannels,
                                   const uint32_t samplesPerSec,
                                   void* audioSamples,
                                   size_t& nSamplesOut,  // NOLINT
                                   int64_t* elapsed_time_ms,
                                   int64_t* ntp_time_ms) = 0;  // NOLINT

  // Method to pull mixed render audio data from all active VoE channels.
  // The data will not be passed as reference for audio processing internally.
  virtual void PullRenderData(int bits_per_sample,
                              int sample_rate,
                              size_t number_of_channels,
                              size_t number_of_frames,
                              void* audio_data,
                              int64_t* elapsed_time_ms,
                              int64_t* ntp_time_ms) = 0;

  virtual void OnSpeakerError() = 0;

 protected:
  virtual ~AudioTransport() {}
};

          AudioDeviceModuleImpl实现了AudioDeviceModule接口,创建的时候调用CreatePlatformSpecificObjects方法创建平台相关的AudioDeviceGeneric接口实现。该接口抽象了音频的采集和播放逻辑,在Windows平台下有两种实现方案:

  •   AudioDeviceWindowsWave实现的是传统的Windows Wave APIs方案。
  •  AudioDeviceWindowsCore实现的是Vista之后才支持的Windows Core Audio APIs方案。

         AudioDeviceModuleImpl还维护了一个AudioDeviceBuffer对象来管理音频数据的缓冲区,由它直接与对外接口AudioTransport交互。比如:

  •  当AudioDeviceWindowsWave或者AudioDeviceWindowsCore需要播放音频数据的时候,会调用AudioDeviceBuffer的RequestPlayoutData方法请求播放数据,然后通过GetPlayoutData方法来获取刚请求到的数据。AudioDeviceBuffer的RequestPlayoutData就是调用AudioTransport接口的NeedMorePlayData方法来请求待播放的音频流数据。
  •  当AudioDeviceWindowsWave或者AudioDeviceWindowsCore采集到音频数据后,会调用AudioDeviceBuffer的SetRecordedBuffer方法将采集到的音频数据传递进去,然后调用DeliverRecordedData方法来派发出去,该派发方法就是通过调用AudioTransport接口的RecordedDataIsAvailable来实现。
#ifndef MODULES_AUDIO_DEVICE_AUDIO_DEVICE_IMPL_H_
#define MODULES_AUDIO_DEVICE_AUDIO_DEVICE_IMPL_H_

#if defined(WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE)

#include <memory>

#include "modules/audio_device/audio_device_buffer.h"
#include "modules/audio_device/include/audio_device.h"
#include "rtc_base/checks.h"
#include "rtc_base/criticalsection.h"

namespace webrtc {

class AudioDeviceGeneric;
class AudioManager;

class AudioDeviceModuleImpl : public AudioDeviceModule {
 public:
  enum PlatformType {
    kPlatformNotSupported = 0,
    kPlatformWin32 = 1,
    kPlatformWinCe = 2,
    kPlatformLinux = 3,
    kPlatformMac = 4,
    kPlatformAndroid = 5,
    kPlatformIOS = 6
  };

  int32_t CheckPlatform();
  int32_t CreatePlatformSpecificObjects();
  int32_t AttachAudioBuffer();

  AudioDeviceModuleImpl(const AudioLayer audioLayer);
  ~AudioDeviceModuleImpl() override;

  // Retrieve the currently utilized audio layer
  int32_t ActiveAudioLayer(AudioLayer* audioLayer) const override;

  // Full-duplex transportation of PCM audio
  int32_t RegisterAudioCallback(AudioTransport* audioCallback) override;

  // Main initializaton and termination
  int32_t Init() override;
  int32_t Terminate() override;
  bool Initialized() const override;

  // Device enumeration
  int16_t PlayoutDevices() override;
  int16_t RecordingDevices() override;
  int32_t PlayoutDeviceName(uint16_t index,
                            char name[kAdmMaxDeviceNameSize],
                            char guid[kAdmMaxGuidSize]) override;
  int32_t RecordingDeviceName(uint16_t index,
                              char name[kAdmMaxDeviceNameSize],
                              char guid[kAdmMaxGuidSize]) override;

  // Device selection
  int32_t SetPlayoutDevice(uint16_t index) override;
  int32_t SetPlayoutDevice(WindowsDeviceType device) override;
  int32_t SetRecordingDevice(uint16_t index) override;
  int32_t SetRecordingDevice(WindowsDeviceType device) override;

  // Audio transport initialization
  int32_t PlayoutIsAvailable(bool* available) override;
  int32_t InitPlayout() override;
  bool PlayoutIsInitialized() const override;
  int32_t RecordingIsAvailable(bool* available) override;
  int32_t InitRecording() override;
  bool RecordingIsInitialized() const override;

  // Audio transport control
  int32_t StartPlayout() override;
  int32_t StopPlayout() override;
  bool Playing() const override;
  int32_t StartRecording() override;
  int32_t StopRecording() override;
  bool Recording() const override;

  // Audio mixer initialization
  int32_t InitSpeaker() override;
  bool SpeakerIsInitialized() const override;
  int32_t InitMicrophone() override;
  bool MicrophoneIsInitialized() const override;

  // Speaker volume controls
  int32_t SpeakerVolumeIsAvailable(bool* available) override;
  int32_t SetSpeakerVolume(uint32_t volume) override;
  int32_t SpeakerVolume(uint32_t* volume) const override;
  int32_t MaxSpeakerVolume(uint32_t* maxVolume) const override;
  int32_t MinSpeakerVolume(uint32_t* minVolume) const override;

  // Microphone volume controls
  int32_t MicrophoneVolumeIsAvailable(bool* available) override;
  int32_t SetMicrophoneVolume(uint32_t volume) override;
  int32_t MicrophoneVolume(uint32_t* volume) const override;
  int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override;
  int32_t MinMicrophoneVolume(uint32_t* minVolume) const override;

  // Speaker mute control
  int32_t SpeakerMuteIsAvailable(bool* available) override;
  int32_t SetSpeakerMute(bool enable) override;
  int32_t SpeakerMute(bool* enabled) const override;

  // Microphone mute control
  int32_t MicrophoneMuteIsAvailable(bool* available) override;
  int32_t SetMicrophoneMute(bool enable) override;
  int32_t MicrophoneMute(bool* enabled) const override;

  // Stereo support
  int32_t StereoPlayoutIsAvailable(bool* available) const override;
  int32_t SetStereoPlayout(bool enable) override;
  int32_t StereoPlayout(bool* enabled) const override;
  int32_t StereoRecordingIsAvailable(bool* available) const override;
  int32_t SetStereoRecording(bool enable) override;
  int32_t StereoRecording(bool* enabled) const override;

  // Delay information and control
  int32_t PlayoutDelay(uint16_t* delayMS) const override;

  bool BuiltInAECIsAvailable() const override;
  int32_t EnableBuiltInAEC(bool enable) override;
  bool BuiltInAGCIsAvailable() const override;
  int32_t EnableBuiltInAGC(bool enable) override;
  bool BuiltInNSIsAvailable() const override;
  int32_t EnableBuiltInNS(bool enable) override;

#if defined(WEBRTC_IOS)
  int GetPlayoutAudioParameters(AudioParameters* params) const override;
  int GetRecordAudioParameters(AudioParameters* params) const override;
#endif  // WEBRTC_IOS

#if defined(WEBRTC_ANDROID)
  // Only use this acccessor for test purposes on Android.
  AudioManager* GetAndroidAudioManagerForTest() {
    return audio_manager_android_.get();
  }
#endif
  AudioDeviceBuffer* GetAudioDeviceBuffer() { return &audio_device_buffer_; }

 private:
  PlatformType Platform() const;
  AudioLayer PlatformAudioLayer() const;

  AudioLayer audio_layer_;
  PlatformType platform_type_ = kPlatformNotSupported;
  bool initialized_ = false;
#if defined(WEBRTC_ANDROID)
  // Should be declared first to ensure that it outlives other resources.
  std::unique_ptr<AudioManager> audio_manager_android_;
#endif
  AudioDeviceBuffer audio_device_buffer_;
  std::unique_ptr<AudioDeviceGeneric> audio_device_;
};

}  // namespace webrtc

#endif  // defined(WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE)

#endif  // MODULES_AUDIO_DEVICE_AUDIO_DEVICE_IMPL_H_

        AudioDeviceBuffer保存和Device的交互的音频数据,audio_device_采集的音频会交由audio_device_buffer_处理,在由AudioTransport传输

#ifndef MODULES_AUDIO_DEVICE_AUDIO_DEVICE_BUFFER_H_
#define MODULES_AUDIO_DEVICE_AUDIO_DEVICE_BUFFER_H_

#include "modules/audio_device/include/audio_device.h"
#include "rtc_base/buffer.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/thread_checker.h"
#include "typedefs.h"  // NOLINT(build/include)

namespace webrtc {

// Delta times between two successive playout callbacks are limited to this
// value before added to an internal array.
const size_t kMaxDeltaTimeInMs = 500;
// TODO(henrika): remove when no longer used by external client.
const size_t kMaxBufferSizeBytes = 3840;  // 10ms in stereo @ 96kHz

class AudioDeviceBuffer {
 public:
  enum LogState {
    LOG_START = 0,
    LOG_STOP,
    LOG_ACTIVE,
  };

  struct Stats {
    void ResetRecStats() {
      rec_callbacks = 0;
      rec_samples = 0;
      max_rec_level = 0;
    }

    void ResetPlayStats() {
      play_callbacks = 0;
      play_samples = 0;
      max_play_level = 0;
    }

    // Total number of recording callbacks where the source provides 10ms audio
    // data each time.
    uint64_t rec_callbacks = 0;

    // Total number of playback callbacks where the sink asks for 10ms audio
    // data each time.
    uint64_t play_callbacks = 0;

    // Total number of recorded audio samples.
    uint64_t rec_samples = 0;

    // Total number of played audio samples.
    uint64_t play_samples = 0;

    // Contains max level (max(abs(x))) of recorded audio packets over the last
    // 10 seconds where a new measurement is done twice per second. The level
    // is reset to zero at each call to LogStats().
    int16_t max_rec_level = 0;

    // Contains max level of recorded audio packets over the last 10 seconds
    // where a new measurement is done twice per second.
    int16_t max_play_level = 0;
  };

  AudioDeviceBuffer();
  virtual ~AudioDeviceBuffer();

  int32_t RegisterAudioCallback(AudioTransport* audio_callback);

  void StartPlayout();
  void StartRecording();
  void StopPlayout();
  void StopRecording();

  int32_t SetRecordingSampleRate(uint32_t fsHz);
  int32_t SetPlayoutSampleRate(uint32_t fsHz);
  int32_t RecordingSampleRate() const;
  int32_t PlayoutSampleRate() const;

  int32_t SetRecordingChannels(size_t channels);
  int32_t SetPlayoutChannels(size_t channels);
  size_t RecordingChannels() const;
  size_t PlayoutChannels() const;

  virtual int32_t SetRecordedBuffer(const void* audio_buffer,
                                    size_t samples_per_channel);
  virtual void SetVQEData(int play_delay_ms, int rec_delay_ms);
  virtual int32_t DeliverRecordedData();
  uint32_t NewMicLevel() const;

  virtual int32_t RequestPlayoutData(size_t samples_per_channel);
  virtual int32_t GetPlayoutData(void* audio_buffer);

  virtual void OnSpeakerError();

  int32_t SetTypingStatus(bool typing_status);

  // Called on iOS and Android where the native audio layer can be interrupted
  // by other audio applications. These methods can then be used to reset
  // internal states and detach thread checkers to allow for new audio sessions
  // where native callbacks may come from a new set of I/O threads.
  void NativeAudioPlayoutInterrupted();
  void NativeAudioRecordingInterrupted();

 private:
  // Starts/stops periodic logging of audio stats.
  void StartPeriodicLogging();
  void StopPeriodicLogging();

  // Called periodically on the internal thread created by the TaskQueue.
  // Updates some stats but dooes it on the task queue to ensure that access of
  // members is serialized hence avoiding usage of locks.
  // state = LOG_START => members are initialized and the timer starts.
  // state = LOG_STOP => no logs are printed and the timer stops.
  // state = LOG_ACTIVE => logs are printed and the timer is kept alive.
  void LogStats(LogState state);

  // Updates counters in each play/record callback. These counters are later
  // (periodically) read by LogStats() using a lock.
  void UpdateRecStats(int16_t max_abs, size_t samples_per_channel);
  void UpdatePlayStats(int16_t max_abs, size_t samples_per_channel);

  // Clears all members tracking stats for recording and playout.
  // These methods both run on the task queue.
  void ResetRecStats();
  void ResetPlayStats();

  // This object lives on the main (creating) thread and most methods are
  // called on that same thread. When audio has started some methods will be
  // called on either a native audio thread for playout or a native thread for
  // recording. Some members are not annotated since they are "protected by
  // design" and adding e.g. a race checker can cause failuries for very few
  // edge cases and it is IMHO not worth the risk to use them in this class.
  // TODO(henrika): see if it is possible to refactor and annotate all members.

  // Main thread on which this object is created.
  rtc::ThreadChecker main_thread_checker_;

  // Native (platform specific) audio thread driving the playout side.
  rtc::ThreadChecker playout_thread_checker_;

  // Native (platform specific) audio thread driving the recording side.
  rtc::ThreadChecker recording_thread_checker_;

  rtc::CriticalSection lock_;

  // Task queue used to invoke LogStats() periodically. Tasks are executed on a
  // worker thread but it does not necessarily have to be the same thread for
  // each task.
  rtc::TaskQueue task_queue_;

  // Raw pointer to AudioTransport instance. Supplied to RegisterAudioCallback()
  // and it must outlive this object. It is not possible to change this member
  // while any media is active. It is possible to start media without calling
  // RegisterAudioCallback() but that will lead to ignored audio callbacks in
  // both directions where native audio will be acive but no audio samples will
  // be transported.
  AudioTransport* audio_transport_cb_;

  // The members below that are not annotated are protected by design. They are
  // all set on the main thread (verified by |main_thread_checker_|) and then
  // read on either the playout or recording audio thread. But, media will never
  // be active when the member is set; hence no conflict exists. It is too
  // complex to ensure and verify that this is actually the case.

  // Sample rate in Hertz.
  uint32_t rec_sample_rate_;
  uint32_t play_sample_rate_;

  // Number of audio channels.
  size_t rec_channels_;
  size_t play_channels_;

  // Keeps track of if playout/recording are active or not. A combination
  // of these states are used to determine when to start and stop the timer.
  // Only used on the creating thread and not used to control any media flow.
  bool playing_ RTC_GUARDED_BY(main_thread_checker_);
  bool recording_ RTC_GUARDED_BY(main_thread_checker_);

  // Buffer used for audio samples to be played out. Size can be changed
  // dynamically. The 16-bit samples are interleaved, hence the size is
  // proportional to the number of channels.
  rtc::BufferT<int16_t> play_buffer_ RTC_GUARDED_BY(playout_thread_checker_);

  // Byte buffer used for recorded audio samples. Size can be changed
  // dynamically.
  rtc::BufferT<int16_t> rec_buffer_ RTC_GUARDED_BY(recording_thread_checker_);

  // Contains true of a key-press has been detected.
  bool typing_status_ RTC_GUARDED_BY(recording_thread_checker_);

  // Delay values used by the AEC.
  int play_delay_ms_ RTC_GUARDED_BY(recording_thread_checker_);
  int rec_delay_ms_ RTC_GUARDED_BY(recording_thread_checker_);

  // Counts number of times LogStats() has been called.
  size_t num_stat_reports_ RTC_GUARDED_BY(task_queue_);

  // Time stamp of last timer task (drives logging).
  int64_t last_timer_task_time_ RTC_GUARDED_BY(task_queue_);

  // Counts number of audio callbacks modulo 50 to create a signal when
  // a new storage of audio stats shall be done.
  int16_t rec_stat_count_ RTC_GUARDED_BY(recording_thread_checker_);
  int16_t play_stat_count_ RTC_GUARDED_BY(playout_thread_checker_);

  // Time stamps of when playout and recording starts.
  int64_t play_start_time_ RTC_GUARDED_BY(main_thread_checker_);
  int64_t rec_start_time_ RTC_GUARDED_BY(main_thread_checker_);

  // Contains counters for playout and recording statistics.
  Stats stats_ RTC_GUARDED_BY(lock_);

  // Stores current stats at each timer task. Used to calculate differences
  // between two successive timer events.
  Stats last_stats_ RTC_GUARDED_BY(task_queue_);

  // Set to true at construction and modified to false as soon as one audio-
  // level estimate larger than zero is detected.
  bool only_silence_recorded_;

  // Set to true when logging of audio stats is enabled for the first time in
  // StartPeriodicLogging() and set to false by StopPeriodicLogging().
  // Setting this member to false prevents (possiby invalid) log messages from
  // being printed in the LogStats() task.
  bool log_stats_ RTC_GUARDED_BY(task_queue_);

// Should *never* be defined in production builds. Only used for testing.
// When defined, the output signal will be replaced by a sinus tone at 440Hz.
#ifdef AUDIO_DEVICE_PLAYS_SINUS_TONE
  double phase_ RTC_GUARDED_BY(playout_thread_checker_);
#endif
};

}  // namespace webrtc

#endif  // MODULES_AUDIO_DEVICE_AUDIO_DEVICE_BUFFER_H_

      Audio Processing Module (APM)音频处理模块(APM)提供了语音处理的集合,为实时通信软件设计的组件。

// The Audio Processing Module (APM) provides a collection of voice processing
// components designed for real-time communications software.
//
// APM operates on two audio streams on a frame-by-frame basis. Frames of the
// primary stream, on which all processing is applied, are passed to
// |ProcessStream()|. Frames of the reverse direction stream are passed to
// |ProcessReverseStream()|. On the client-side, this will typically be the
// near-end (capture) and far-end (render) streams, respectively. APM should be
// placed in the signal chain as close to the audio hardware abstraction layer
// (HAL) as possible.
//
// On the server-side, the reverse stream will normally not be used, with
// processing occurring on each incoming stream.
//
// Component interfaces follow a similar pattern and are accessed through
// corresponding getters in APM. All components are disabled at create-time,
// with default settings that are recommended for most situations. New settings
// can be applied without enabling a component. Enabling a component triggers
// memory allocation and initialization to allow it to start processing the
// streams.
//
// Thread safety is provided with the following assumptions to reduce locking
// overhead:
//   1. The stream getters and setters are called from the same thread as
//      ProcessStream(). More precisely, stream functions are never called
//      concurrently with ProcessStream().
//   2. Parameter getters are never called concurrently with the corresponding
//      setter.
//
// APM accepts only linear PCM audio data in chunks of 10 ms. The int16
// interfaces use interleaved data, while the float interfaces use deinterleaved
// data.
//
// Usage example, omitting error checking:
// AudioProcessing* apm = AudioProcessingBuilder().Create();
//
// AudioProcessing::Config config;
// config.high_pass_filter.enabled = true;
// config.gain_controller2.enabled = true;
// apm->ApplyConfig(config)
//
// apm->echo_cancellation()->enable_drift_compensation(false);
// apm->echo_cancellation()->Enable(true);
//
// apm->noise_reduction()->set_level(kHighSuppression);
// apm->noise_reduction()->Enable(true);
//
// apm->gain_control()->set_analog_level_limits(0, 255);
// apm->gain_control()->set_mode(kAdaptiveAnalog);
// apm->gain_control()->Enable(true);
//
// apm->voice_detection()->Enable(true);
//
// // Start a voice call...
//
// // ... Render frame arrives bound for the audio HAL ...
// apm->ProcessReverseStream(render_frame);
//
// // ... Capture frame arrives from the audio HAL ...
// // Call required set_stream_ functions.
// apm->set_stream_delay_ms(delay_ms);
// apm->gain_control()->set_stream_analog_level(analog_level);
//
// apm->ProcessStream(capture_frame);
//
// // Call required stream_ functions.
// analog_level = apm->gain_control()->stream_analog_level();
// has_voice = apm->stream_has_voice();
//
// // Repeate render and capture processing for the duration of the call...
// // Start a new call...
// apm->Initialize();
//
// // Close the application...
// delete apm;
//

 类似资料:

相关阅读

相关文章

相关问答