From cf327b45b9f5738950d4fca2b6a7b6030d508cdf Mon Sep 17 00:00:00 2001 From: henrika Date: Fri, 19 Aug 2016 16:37:53 +0200 Subject: [PATCH] Cleanup of the AudioDeviceBuffer class. WebRTC works on 10ms buffer sizes in both directions but this class has contained support for any size (with some limits) and for changes on the fly. It makes no sense to maintain such code and we have no tests to test it. This CL ensures that only 10ms audio buffers are supported and that nothing can be changed on the fly. It also updates the style to follow the Google C++ style guide. Finally, I remove very old (not tested and not maintained) support for file handling since the code is never used. It was more or less dead code. BUG=NONE R=magjed@webrtc.org Review URL: https://codereview.webrtc.org/2256833003 . Cr-Commit-Position: refs/heads/master@{#13833} --- .../audio_device/audio_device_buffer.cc | 326 ++++++++---------- .../audio_device/audio_device_buffer.h | 98 +++--- 2 files changed, 191 insertions(+), 233 deletions(-) diff --git a/webrtc/modules/audio_device/audio_device_buffer.cc b/webrtc/modules/audio_device/audio_device_buffer.cc index ba8b6a5b3e..d157c1cb1a 100644 --- a/webrtc/modules/audio_device/audio_device_buffer.cc +++ b/webrtc/modules/audio_device/audio_device_buffer.cc @@ -22,9 +22,6 @@ namespace webrtc { -static const int kHighDelayThresholdMs = 300; -static const int kLogHighDelayIntervalFrames = 500; // 5 seconds. - static const char kTimerQueueName[] = "AudioDeviceBufferTimer"; // Time between two sucessive calls to LogStats(). @@ -33,30 +30,26 @@ static const size_t kTimerIntervalInMilliseconds = kTimerIntervalInSeconds * rtc::kNumMillisecsPerSec; AudioDeviceBuffer::AudioDeviceBuffer() - : _ptrCbAudioTransport(nullptr), + : audio_transport_cb_(nullptr), task_queue_(kTimerQueueName), timer_has_started_(false), - _recSampleRate(0), - _playSampleRate(0), - _recChannels(0), - _playChannels(0), - _recChannel(AudioDeviceModule::kChannelBoth), - _recBytesPerSample(0), - _playBytesPerSample(0), - _recSamples(0), - _recSize(0), - _playSamples(0), - _playSize(0), - _recFile(*FileWrapper::Create()), - _playFile(*FileWrapper::Create()), - _currentMicLevel(0), - _newMicLevel(0), - _typingStatus(false), - _playDelayMS(0), - _recDelayMS(0), - _clockDrift(0), - // Set to the interval in order to log on the first occurrence. - high_delay_counter_(kLogHighDelayIntervalFrames), + rec_sample_rate_(0), + play_sample_rate_(0), + rec_channels_(0), + play_channels_(0), + rec_channel_(AudioDeviceModule::kChannelBoth), + rec_bytes_per_sample_(0), + play_bytes_per_sample_(0), + rec_samples_per_10ms_(0), + rec_bytes_per_10ms_(0), + play_samples_per_10ms_(0), + play_bytes_per_10ms_(0), + current_mic_level_(0), + new_mic_level_(0), + typing_status_(false), + play_delay_ms_(0), + rec_delay_ms_(0), + clock_drift_(0), num_stat_reports_(0), rec_callbacks_(0), last_rec_callbacks_(0), @@ -68,8 +61,6 @@ AudioDeviceBuffer::AudioDeviceBuffer() last_play_samples_(0), last_log_stat_time_(0) { LOG(INFO) << "AudioDeviceBuffer::ctor"; - memset(_recBuffer, 0, kMaxBufferSizeBytes); - memset(_playBuffer, 0, kMaxBufferSizeBytes); } AudioDeviceBuffer::~AudioDeviceBuffer() { @@ -93,27 +84,19 @@ AudioDeviceBuffer::~AudioDeviceBuffer() { LOG(INFO) << "average: " << static_cast(total_diff_time) / num_measurements; } - - _recFile.Flush(); - _recFile.CloseFile(); - delete &_recFile; - - _playFile.Flush(); - _playFile.CloseFile(); - delete &_playFile; } int32_t AudioDeviceBuffer::RegisterAudioCallback( - AudioTransport* audioCallback) { + AudioTransport* audio_callback) { LOG(INFO) << __FUNCTION__; rtc::CritScope lock(&_critSectCb); - _ptrCbAudioTransport = audioCallback; + audio_transport_cb_ = audio_callback; return 0; } int32_t AudioDeviceBuffer::InitPlayout() { - RTC_DCHECK(thread_checker_.CalledOnValidThread()); LOG(INFO) << __FUNCTION__; + RTC_DCHECK(thread_checker_.CalledOnValidThread()); last_playout_time_ = rtc::TimeMillis(); if (!timer_has_started_) { StartTimer(); @@ -123,8 +106,8 @@ int32_t AudioDeviceBuffer::InitPlayout() { } int32_t AudioDeviceBuffer::InitRecording() { - RTC_DCHECK(thread_checker_.CalledOnValidThread()); LOG(INFO) << __FUNCTION__; + RTC_DCHECK(thread_checker_.CalledOnValidThread()); if (!timer_has_started_) { StartTimer(); timer_has_started_ = true; @@ -135,38 +118,40 @@ int32_t AudioDeviceBuffer::InitRecording() { int32_t AudioDeviceBuffer::SetRecordingSampleRate(uint32_t fsHz) { LOG(INFO) << "SetRecordingSampleRate(" << fsHz << ")"; rtc::CritScope lock(&_critSect); - _recSampleRate = fsHz; + rec_sample_rate_ = fsHz; return 0; } int32_t AudioDeviceBuffer::SetPlayoutSampleRate(uint32_t fsHz) { LOG(INFO) << "SetPlayoutSampleRate(" << fsHz << ")"; rtc::CritScope lock(&_critSect); - _playSampleRate = fsHz; + play_sample_rate_ = fsHz; return 0; } int32_t AudioDeviceBuffer::RecordingSampleRate() const { - return _recSampleRate; + return rec_sample_rate_; } int32_t AudioDeviceBuffer::PlayoutSampleRate() const { - return _playSampleRate; + return play_sample_rate_; } int32_t AudioDeviceBuffer::SetRecordingChannels(size_t channels) { + LOG(INFO) << "SetRecordingChannels(" << channels << ")"; rtc::CritScope lock(&_critSect); - _recChannels = channels; - _recBytesPerSample = + rec_channels_ = channels; + rec_bytes_per_sample_ = 2 * channels; // 16 bits per sample in mono, 32 bits in stereo return 0; } int32_t AudioDeviceBuffer::SetPlayoutChannels(size_t channels) { + LOG(INFO) << "SetPlayoutChannels(" << channels << ")"; rtc::CritScope lock(&_critSect); - _playChannels = channels; + play_channels_ = channels; // 16 bits per sample in mono, 32 bits in stereo - _playBytesPerSample = 2 * channels; + play_bytes_per_sample_ = 2 * channels; return 0; } @@ -174,135 +159,101 @@ int32_t AudioDeviceBuffer::SetRecordingChannel( const AudioDeviceModule::ChannelType channel) { rtc::CritScope lock(&_critSect); - if (_recChannels == 1) { + if (rec_channels_ == 1) { return -1; } if (channel == AudioDeviceModule::kChannelBoth) { // two bytes per channel - _recBytesPerSample = 4; + rec_bytes_per_sample_ = 4; } else { // only utilize one out of two possible channels (left or right) - _recBytesPerSample = 2; + rec_bytes_per_sample_ = 2; } - _recChannel = channel; + rec_channel_ = channel; return 0; } int32_t AudioDeviceBuffer::RecordingChannel( AudioDeviceModule::ChannelType& channel) const { - channel = _recChannel; + channel = rec_channel_; return 0; } size_t AudioDeviceBuffer::RecordingChannels() const { - return _recChannels; + return rec_channels_; } size_t AudioDeviceBuffer::PlayoutChannels() const { - return _playChannels; + return play_channels_; } int32_t AudioDeviceBuffer::SetCurrentMicLevel(uint32_t level) { - _currentMicLevel = level; + current_mic_level_ = level; return 0; } -int32_t AudioDeviceBuffer::SetTypingStatus(bool typingStatus) { - _typingStatus = typingStatus; +int32_t AudioDeviceBuffer::SetTypingStatus(bool typing_status) { + typing_status_ = typing_status; return 0; } uint32_t AudioDeviceBuffer::NewMicLevel() const { - return _newMicLevel; + return new_mic_level_; } -void AudioDeviceBuffer::SetVQEData(int playDelayMs, - int recDelayMs, - int clockDrift) { - if (high_delay_counter_ < kLogHighDelayIntervalFrames) { - ++high_delay_counter_; - } else { - if (playDelayMs + recDelayMs > kHighDelayThresholdMs) { - high_delay_counter_ = 0; - LOG(LS_WARNING) << "High audio device delay reported (render=" - << playDelayMs << " ms, capture=" << recDelayMs << " ms)"; - } - } - - _playDelayMS = playDelayMs; - _recDelayMS = recDelayMs; - _clockDrift = clockDrift; +void AudioDeviceBuffer::SetVQEData(int play_delay_ms, + int rec_delay_ms, + int clock_drift) { + play_delay_ms_ = play_delay_ms; + rec_delay_ms_ = rec_delay_ms; + clock_drift_ = clock_drift; } int32_t AudioDeviceBuffer::StartInputFileRecording( const char fileName[kAdmMaxFileNameSize]) { - rtc::CritScope lock(&_critSect); - - _recFile.Flush(); - _recFile.CloseFile(); - - return _recFile.OpenFile(fileName, false) ? 0 : -1; + LOG(LS_WARNING) << "Not implemented"; + return 0; } int32_t AudioDeviceBuffer::StopInputFileRecording() { - rtc::CritScope lock(&_critSect); - - _recFile.Flush(); - _recFile.CloseFile(); - + LOG(LS_WARNING) << "Not implemented"; return 0; } int32_t AudioDeviceBuffer::StartOutputFileRecording( const char fileName[kAdmMaxFileNameSize]) { - rtc::CritScope lock(&_critSect); - - _playFile.Flush(); - _playFile.CloseFile(); - - return _playFile.OpenFile(fileName, false) ? 0 : -1; -} - -int32_t AudioDeviceBuffer::StopOutputFileRecording() { - rtc::CritScope lock(&_critSect); - - _playFile.Flush(); - _playFile.CloseFile(); - + LOG(LS_WARNING) << "Not implemented"; return 0; } -int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audioBuffer, - size_t nSamples) { +int32_t AudioDeviceBuffer::StopOutputFileRecording() { + LOG(LS_WARNING) << "Not implemented"; + return 0; +} + +int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audio_buffer, + size_t num_samples) { + AllocateRecordingBufferIfNeeded(); + RTC_CHECK(rec_buffer_); + // WebRTC can only receive audio in 10ms chunks, hence we fail if the native + // audio layer tries to deliver something else. + RTC_CHECK_EQ(num_samples, rec_samples_per_10ms_); + rtc::CritScope lock(&_critSect); - if (_recBytesPerSample == 0) { - assert(false); - return -1; - } - - _recSamples = nSamples; - _recSize = _recBytesPerSample * nSamples; // {2,4}*nSamples - if (_recSize > kMaxBufferSizeBytes) { - assert(false); - return -1; - } - - if (_recChannel == AudioDeviceModule::kChannelBoth) { - // (default) copy the complete input buffer to the local buffer - memcpy(&_recBuffer[0], audioBuffer, _recSize); + if (rec_channel_ == AudioDeviceModule::kChannelBoth) { + // Copy the complete input buffer to the local buffer. + memcpy(&rec_buffer_[0], audio_buffer, rec_bytes_per_10ms_); } else { - int16_t* ptr16In = (int16_t*)audioBuffer; - int16_t* ptr16Out = (int16_t*)&_recBuffer[0]; - - if (AudioDeviceModule::kChannelRight == _recChannel) { + int16_t* ptr16In = (int16_t*)audio_buffer; + int16_t* ptr16Out = (int16_t*)&rec_buffer_[0]; + if (AudioDeviceModule::kChannelRight == rec_channel_) { ptr16In++; } - - // exctract left or right channel from input buffer to the local buffer - for (size_t i = 0; i < _recSamples; i++) { + // Exctract left or right channel from input buffer to the local buffer. + for (size_t i = 0; i < rec_samples_per_10ms_; i++) { *ptr16Out = *ptr16In; ptr16Out++; ptr16In++; @@ -310,52 +261,40 @@ int32_t AudioDeviceBuffer::SetRecordedBuffer(const void* audioBuffer, } } - if (_recFile.is_open()) { - // write to binary file in mono or stereo (interleaved) - _recFile.Write(&_recBuffer[0], _recSize); - } - // Update some stats but do it on the task queue to ensure that the members // are modified and read on the same thread. task_queue_.PostTask( - rtc::Bind(&AudioDeviceBuffer::UpdateRecStats, this, nSamples)); - + rtc::Bind(&AudioDeviceBuffer::UpdateRecStats, this, num_samples)); return 0; } int32_t AudioDeviceBuffer::DeliverRecordedData() { + RTC_CHECK(rec_buffer_); + RTC_DCHECK(audio_transport_cb_); rtc::CritScope lock(&_critSectCb); - // Ensure that user has initialized all essential members - if ((_recSampleRate == 0) || (_recSamples == 0) || - (_recBytesPerSample == 0) || (_recChannels == 0)) { - RTC_NOTREACHED(); - return -1; - } - if (!_ptrCbAudioTransport) { + if (!audio_transport_cb_) { LOG(LS_WARNING) << "Invalid audio transport"; return 0; } int32_t res(0); uint32_t newMicLevel(0); - uint32_t totalDelayMS = _playDelayMS + _recDelayMS; - res = _ptrCbAudioTransport->RecordedDataIsAvailable( - &_recBuffer[0], _recSamples, _recBytesPerSample, _recChannels, - _recSampleRate, totalDelayMS, _clockDrift, _currentMicLevel, - _typingStatus, newMicLevel); + uint32_t totalDelayMS = play_delay_ms_ + rec_delay_ms_; + res = audio_transport_cb_->RecordedDataIsAvailable( + &rec_buffer_[0], rec_samples_per_10ms_, rec_bytes_per_sample_, + rec_channels_, rec_sample_rate_, totalDelayMS, clock_drift_, + current_mic_level_, typing_status_, newMicLevel); if (res != -1) { - _newMicLevel = newMicLevel; + new_mic_level_ = newMicLevel; + } else { + LOG(LS_ERROR) << "RecordedDataIsAvailable() failed"; } return 0; } -int32_t AudioDeviceBuffer::RequestPlayoutData(size_t nSamples) { - uint32_t playSampleRate = 0; - size_t playBytesPerSample = 0; - size_t playChannels = 0; - +int32_t AudioDeviceBuffer::RequestPlayoutData(size_t num_samples) { // Measure time since last function call and update an array where the // position/index corresponds to time differences (in milliseconds) between // two successive playout callbacks, and the stored value is the number of @@ -367,37 +306,17 @@ int32_t AudioDeviceBuffer::RequestPlayoutData(size_t nSamples) { last_playout_time_ = now_time; playout_diff_times_[diff_time]++; - // TOOD(henrika): improve bad locking model and make it more clear that only - // 10ms buffer sizes is supported in WebRTC. - { - rtc::CritScope lock(&_critSect); - - // Store copies under lock and use copies hereafter to avoid race with - // setter methods. - playSampleRate = _playSampleRate; - playBytesPerSample = _playBytesPerSample; - playChannels = _playChannels; - - // Ensure that user has initialized all essential members - if ((playBytesPerSample == 0) || (playChannels == 0) || - (playSampleRate == 0)) { - RTC_NOTREACHED(); - return -1; - } - - _playSamples = nSamples; - _playSize = playBytesPerSample * nSamples; // {2,4}*nSamples - RTC_CHECK_LE(_playSize, kMaxBufferSizeBytes); - RTC_CHECK_EQ(nSamples, _playSamples); - } - - size_t nSamplesOut(0); + AllocatePlayoutBufferIfNeeded(); + RTC_CHECK(play_buffer_); + // WebRTC can only provide audio in 10ms chunks, hence we fail if the native + // audio layer asks for something else. + RTC_CHECK_EQ(num_samples, play_samples_per_10ms_); rtc::CritScope lock(&_critSectCb); // It is currently supported to start playout without a valid audio // transport object. Leads to warning and silence. - if (!_ptrCbAudioTransport) { + if (!audio_transport_cb_) { LOG(LS_WARNING) << "Invalid audio transport"; return 0; } @@ -405,9 +324,11 @@ int32_t AudioDeviceBuffer::RequestPlayoutData(size_t nSamples) { uint32_t res(0); int64_t elapsed_time_ms = -1; int64_t ntp_time_ms = -1; - res = _ptrCbAudioTransport->NeedMorePlayData( - _playSamples, playBytesPerSample, playChannels, playSampleRate, - &_playBuffer[0], nSamplesOut, &elapsed_time_ms, &ntp_time_ms); + size_t num_samples_out(0); + res = audio_transport_cb_->NeedMorePlayData( + play_samples_per_10ms_, play_bytes_per_sample_, play_channels_, + play_sample_rate_, &play_buffer_[0], num_samples_out, &elapsed_time_ms, + &ntp_time_ms); if (res != 0) { LOG(LS_ERROR) << "NeedMorePlayData() failed"; } @@ -415,23 +336,46 @@ int32_t AudioDeviceBuffer::RequestPlayoutData(size_t nSamples) { // Update some stats but do it on the task queue to ensure that access of // members is serialized hence avoiding usage of locks. task_queue_.PostTask( - rtc::Bind(&AudioDeviceBuffer::UpdatePlayStats, this, nSamplesOut)); - - return static_cast(nSamplesOut); + rtc::Bind(&AudioDeviceBuffer::UpdatePlayStats, this, num_samples_out)); + return static_cast(num_samples_out); } -int32_t AudioDeviceBuffer::GetPlayoutData(void* audioBuffer) { +int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) { rtc::CritScope lock(&_critSect); - RTC_CHECK_LE(_playSize, kMaxBufferSizeBytes); + memcpy(audio_buffer, &play_buffer_[0], play_bytes_per_10ms_); + return static_cast(play_samples_per_10ms_); +} - memcpy(audioBuffer, &_playBuffer[0], _playSize); +void AudioDeviceBuffer::AllocatePlayoutBufferIfNeeded() { + RTC_CHECK(play_bytes_per_sample_); + if (play_buffer_) + return; + LOG(INFO) << __FUNCTION__; + rtc::CritScope lock(&_critSect); + // Derive the required buffer size given sample rate and number of channels. + play_samples_per_10ms_ = static_cast(play_sample_rate_ * 10 / 1000); + play_bytes_per_10ms_ = play_bytes_per_sample_ * play_samples_per_10ms_; + LOG(INFO) << "playout samples per 10ms: " << play_samples_per_10ms_; + LOG(INFO) << "playout bytes per 10ms: " << play_bytes_per_10ms_; + // Allocate memory for the playout audio buffer. It will always contain audio + // samples corresponding to 10ms of audio to be played out. + play_buffer_.reset(new int8_t[play_bytes_per_10ms_]); +} - if (_playFile.is_open()) { - // write to binary file in mono or stereo (interleaved) - _playFile.Write(&_playBuffer[0], _playSize); - } - - return static_cast(_playSamples); +void AudioDeviceBuffer::AllocateRecordingBufferIfNeeded() { + RTC_CHECK(rec_bytes_per_sample_); + if (rec_buffer_) + return; + LOG(INFO) << __FUNCTION__; + rtc::CritScope lock(&_critSect); + // Derive the required buffer size given sample rate and number of channels. + rec_samples_per_10ms_ = static_cast(rec_sample_rate_ * 10 / 1000); + rec_bytes_per_10ms_ = rec_bytes_per_sample_ * rec_samples_per_10ms_; + LOG(INFO) << "recorded samples per 10ms: " << rec_samples_per_10ms_; + LOG(INFO) << "recorded bytes per 10ms: " << rec_bytes_per_10ms_; + // Allocate memory for the recording audio buffer. It will always contain + // audio samples corresponding to 10ms of audio. + rec_buffer_.reset(new int8_t[rec_bytes_per_10ms_]); } void AudioDeviceBuffer::StartTimer() { @@ -455,7 +399,7 @@ void AudioDeviceBuffer::LogStats() { uint32_t diff_samples = rec_samples_ - last_rec_samples_; uint32_t rate = diff_samples / kTimerIntervalInSeconds; LOG(INFO) << "[REC : " << time_since_last << "msec, " - << _recSampleRate / 1000 + << rec_sample_rate_ / 1000 << "kHz] callbacks: " << rec_callbacks_ - last_rec_callbacks_ << ", " << "samples: " << diff_samples << ", " @@ -464,7 +408,7 @@ void AudioDeviceBuffer::LogStats() { diff_samples = play_samples_ - last_play_samples_; rate = diff_samples / kTimerIntervalInSeconds; LOG(INFO) << "[PLAY: " << time_since_last << "msec, " - << _playSampleRate / 1000 + << play_sample_rate_ / 1000 << "kHz] callbacks: " << play_callbacks_ - last_play_callbacks_ << ", " << "samples: " << diff_samples << ", " diff --git a/webrtc/modules/audio_device/audio_device_buffer.h b/webrtc/modules/audio_device/audio_device_buffer.h index f49420c98e..ba484a57c7 100644 --- a/webrtc/modules/audio_device/audio_device_buffer.h +++ b/webrtc/modules/audio_device/audio_device_buffer.h @@ -21,8 +21,6 @@ namespace webrtc { class CriticalSectionWrapper; -const uint32_t kPulsePeriodMs = 1000; -const size_t kMaxBufferSizeBytes = 3840; // 10ms in stereo @ 96kHz // Delta times between two successive playout callbacks are limited to this // value before added to an internal array. const size_t kMaxDeltaTimeInMs = 500; @@ -35,40 +33,47 @@ class AudioDeviceBuffer { virtual ~AudioDeviceBuffer(); void SetId(uint32_t id) {}; - int32_t RegisterAudioCallback(AudioTransport* audioCallback); + int32_t RegisterAudioCallback(AudioTransport* audio_callback); int32_t InitPlayout(); int32_t InitRecording(); - virtual int32_t SetRecordingSampleRate(uint32_t fsHz); - virtual int32_t SetPlayoutSampleRate(uint32_t fsHz); + int32_t SetRecordingSampleRate(uint32_t fsHz); + int32_t SetPlayoutSampleRate(uint32_t fsHz); int32_t RecordingSampleRate() const; int32_t PlayoutSampleRate() const; - virtual int32_t SetRecordingChannels(size_t channels); - virtual int32_t SetPlayoutChannels(size_t channels); + int32_t SetRecordingChannels(size_t channels); + int32_t SetPlayoutChannels(size_t channels); size_t RecordingChannels() const; size_t PlayoutChannels() const; int32_t SetRecordingChannel(const AudioDeviceModule::ChannelType channel); int32_t RecordingChannel(AudioDeviceModule::ChannelType& channel) const; - virtual int32_t SetRecordedBuffer(const void* audioBuffer, size_t nSamples); + virtual int32_t SetRecordedBuffer(const void* audio_buffer, + size_t num_samples); int32_t SetCurrentMicLevel(uint32_t level); - virtual void SetVQEData(int playDelayMS, int recDelayMS, int clockDrift); + virtual void SetVQEData(int play_delay_ms, int rec_delay_ms, int clock_drift); virtual int32_t DeliverRecordedData(); uint32_t NewMicLevel() const; - virtual int32_t RequestPlayoutData(size_t nSamples); - virtual int32_t GetPlayoutData(void* audioBuffer); + virtual int32_t RequestPlayoutData(size_t num_samples); + virtual int32_t GetPlayoutData(void* audio_buffer); + // TODO(henrika): these methods should not be used and does not contain any + // valid implementation. Investigate the possibility to either remove them + // or add a proper implementation if needed. int32_t StartInputFileRecording(const char fileName[kAdmMaxFileNameSize]); int32_t StopInputFileRecording(); int32_t StartOutputFileRecording(const char fileName[kAdmMaxFileNameSize]); int32_t StopOutputFileRecording(); - int32_t SetTypingStatus(bool typingStatus); + int32_t SetTypingStatus(bool typing_status); private: + void AllocatePlayoutBufferIfNeeded(); + void AllocateRecordingBufferIfNeeded(); + // Posts the first delayed task in the task queue and starts the periodic // timer. void StartTimer(); @@ -86,11 +91,15 @@ class AudioDeviceBuffer { // creates this object. rtc::ThreadChecker thread_checker_; + // Raw pointer to AudioTransport instance. Supplied to RegisterAudioCallback() + // and it must outlive this object. + AudioTransport* audio_transport_cb_; + + // TODO(henrika): given usage of thread checker, it should be possible to + // remove all locks in this class. rtc::CriticalSection _critSect; rtc::CriticalSection _critSectCb; - AudioTransport* _ptrCbAudioTransport; - // 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. @@ -99,45 +108,50 @@ class AudioDeviceBuffer { // Ensures that the timer is only started once. bool timer_has_started_; - uint32_t _recSampleRate; - uint32_t _playSampleRate; + // Sample rate in Hertz. + uint32_t rec_sample_rate_; + uint32_t play_sample_rate_; - size_t _recChannels; - size_t _playChannels; + // Number of audio channels. + size_t rec_channels_; + size_t play_channels_; // selected recording channel (left/right/both) - AudioDeviceModule::ChannelType _recChannel; + AudioDeviceModule::ChannelType rec_channel_; - // 2 or 4 depending on mono or stereo - size_t _recBytesPerSample; - size_t _playBytesPerSample; + // Number of bytes per audio sample (2 or 4). + size_t rec_bytes_per_sample_; + size_t play_bytes_per_sample_; - // 10ms in stereo @ 96kHz - int8_t _recBuffer[kMaxBufferSizeBytes]; + // Number of audio samples/bytes per 10ms. + size_t rec_samples_per_10ms_; + size_t rec_bytes_per_10ms_; + size_t play_samples_per_10ms_; + size_t play_bytes_per_10ms_; - // one sample <=> 2 or 4 bytes - size_t _recSamples; - size_t _recSize; // in bytes + // Buffer used for recorded audio samples. Size is given by + // |rec_bytes_per_10ms_| and the buffer is allocated in InitRecording() on the + // main/creating thread. + std::unique_ptr rec_buffer_; - // 10ms in stereo @ 96kHz - int8_t _playBuffer[kMaxBufferSizeBytes]; + // Buffer used for audio samples to be played out. Size is given by + // |play_bytes_per_10ms_| and the buffer is allocated in InitPlayout() on the + // main/creating thread. + std::unique_ptr play_buffer_; - // one sample <=> 2 or 4 bytes - size_t _playSamples; - size_t _playSize; // in bytes + // AGC parameters. + uint32_t current_mic_level_; + uint32_t new_mic_level_; - FileWrapper& _recFile; - FileWrapper& _playFile; + // Contains true of a key-press has been detected. + bool typing_status_; - uint32_t _currentMicLevel; - uint32_t _newMicLevel; + // Delay values used by the AEC. + int play_delay_ms_; + int rec_delay_ms_; - bool _typingStatus; - - int _playDelayMS; - int _recDelayMS; - int _clockDrift; - int high_delay_counter_; + // Contains a clock-drift measurement. + int clock_drift_; // Counts number of times LogStats() has been called. size_t num_stat_reports_;