audio_device_buffer.h (9604B)
1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef MODULES_AUDIO_DEVICE_AUDIO_DEVICE_BUFFER_H_ 12 #define MODULES_AUDIO_DEVICE_AUDIO_DEVICE_BUFFER_H_ 13 14 #include <atomic> 15 #include <cstddef> 16 #include <cstdint> 17 #include <memory> 18 #include <optional> 19 20 #include "api/audio/audio_device_defines.h" 21 #include "api/environment/environment.h" 22 #include "api/sequence_checker.h" 23 #include "api/task_queue/task_queue_base.h" 24 #include "rtc_base/buffer.h" 25 #include "rtc_base/synchronization/mutex.h" 26 #include "rtc_base/system/no_unique_address.h" 27 #include "rtc_base/thread_annotations.h" 28 #include "rtc_base/timestamp_aligner.h" 29 30 namespace webrtc { 31 32 // Delta times between two successive playout callbacks are limited to this 33 // value before added to an internal array. 34 const size_t kMaxDeltaTimeInMs = 500; 35 // TODO(henrika): remove when no longer used by external client. 36 const size_t kMaxBufferSizeBytes = 3840; // 10ms in stereo @ 96kHz 37 38 class AudioDeviceBuffer { 39 public: 40 enum LogState { 41 LOG_START = 0, 42 LOG_STOP, 43 LOG_ACTIVE, 44 }; 45 46 struct Stats { 47 void ResetRecStats() { 48 rec_callbacks = 0; 49 rec_samples = 0; 50 max_rec_level = 0; 51 } 52 53 void ResetPlayStats() { 54 play_callbacks = 0; 55 play_samples = 0; 56 max_play_level = 0; 57 } 58 59 // Total number of recording callbacks where the source provides 10ms audio 60 // data each time. 61 uint64_t rec_callbacks = 0; 62 63 // Total number of playback callbacks where the sink asks for 10ms audio 64 // data each time. 65 uint64_t play_callbacks = 0; 66 67 // Total number of recorded audio samples. 68 uint64_t rec_samples = 0; 69 70 // Total number of played audio samples. 71 uint64_t play_samples = 0; 72 73 // Contains max level (max(abs(x))) of recorded audio packets over the last 74 // 10 seconds where a new measurement is done twice per second. The level 75 // is reset to zero at each call to LogStats(). 76 int16_t max_rec_level = 0; 77 78 // Contains max level of recorded audio packets over the last 10 seconds 79 // where a new measurement is done twice per second. 80 int16_t max_play_level = 0; 81 }; 82 83 // If `create_detached` is true, the created buffer can be used on another 84 // thread compared to the one on which it was created. It's useful for 85 // testing. 86 explicit AudioDeviceBuffer(const Environment& env, 87 bool create_detached = false); 88 virtual ~AudioDeviceBuffer(); 89 90 int32_t RegisterAudioCallback(AudioTransport* audio_callback); 91 92 void StartPlayout(); 93 void StartRecording(); 94 void StopPlayout(); 95 void StopRecording(); 96 97 int32_t SetRecordingSampleRate(uint32_t fsHz); 98 int32_t SetPlayoutSampleRate(uint32_t fsHz); 99 uint32_t RecordingSampleRate() const; 100 uint32_t PlayoutSampleRate() const; 101 102 int32_t SetRecordingChannels(size_t channels); 103 int32_t SetPlayoutChannels(size_t channels); 104 size_t RecordingChannels() const; 105 size_t PlayoutChannels() const; 106 107 // TODO(bugs.webrtc.org/13621) Deprecate this function 108 virtual int32_t SetRecordedBuffer(const void* audio_buffer, 109 size_t samples_per_channel); 110 111 virtual int32_t SetRecordedBuffer( 112 const void* audio_buffer, 113 size_t samples_per_channel, 114 std::optional<int64_t> capture_timestamp_ns); 115 virtual void SetVQEData(int play_delay_ms, int rec_delay_ms); 116 virtual int32_t DeliverRecordedData(); 117 uint32_t NewMicLevel() const; 118 119 virtual int32_t RequestPlayoutData(size_t samples_per_channel); 120 virtual int32_t GetPlayoutData(void* audio_buffer); 121 122 int32_t SetTypingStatus(bool typing_status); 123 124 private: 125 // Starts/stops periodic logging of audio stats. 126 void StartPeriodicLogging(); 127 void StopPeriodicLogging(); 128 129 // Called periodically on the internal thread created by the TaskQueue. 130 // Updates some stats but dooes it on the task queue to ensure that access of 131 // members is serialized hence avoiding usage of locks. 132 // state = LOG_START => members are initialized and the timer starts. 133 // state = LOG_STOP => no logs are printed and the timer stops. 134 // state = LOG_ACTIVE => logs are printed and the timer is kept alive. 135 void LogStats(LogState state); 136 137 // Updates counters in each play/record callback. These counters are later 138 // (periodically) read by LogStats() using a lock. 139 void UpdateRecStats(int16_t max_abs, size_t samples_per_channel); 140 void UpdatePlayStats(int16_t max_abs, size_t samples_per_channel); 141 142 // Clears all members tracking stats for recording and playout. 143 // These methods both run on the task queue. 144 void ResetRecStats(); 145 void ResetPlayStats(); 146 147 const Environment env_; 148 149 // This object lives on the main (creating) thread and most methods are 150 // called on that same thread. When audio has started some methods will be 151 // called on either a native audio thread for playout or a native thread for 152 // recording. Some members are not annotated since they are "protected by 153 // design" and adding e.g. a race checker can cause failures for very few 154 // edge cases and it is IMHO not worth the risk to use them in this class. 155 // TODO(henrika): see if it is possible to refactor and annotate all members. 156 157 // Main thread for where this object is used. 158 RTC_NO_UNIQUE_ADDRESS SequenceChecker main_thread_checker_{ 159 SequenceChecker::kDetached}; 160 161 Mutex lock_; 162 163 // Task queue used to invoke LogStats() periodically. Tasks are executed on a 164 // worker thread but it does not necessarily have to be the same thread for 165 // each task. 166 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue_; 167 168 // Raw pointer to AudioTransport instance. Supplied to RegisterAudioCallback() 169 // and it must outlive this object. It is not possible to change this member 170 // while any media is active. It is possible to start media without calling 171 // RegisterAudioCallback() but that will lead to ignored audio callbacks in 172 // both directions where native audio will be active but no audio samples will 173 // be transported. 174 AudioTransport* audio_transport_cb_; 175 176 // Sample rate in Hertz. Accessed atomically. 177 std::atomic<uint32_t> rec_sample_rate_; 178 std::atomic<uint32_t> play_sample_rate_; 179 180 // Number of audio channels. Accessed atomically. 181 std::atomic<size_t> rec_channels_; 182 std::atomic<size_t> play_channels_; 183 184 // Keeps track of if playout/recording are active or not. A combination 185 // of these states are used to determine when to start and stop the timer. 186 // Only used on the creating thread and not used to control any media flow. 187 bool playing_ RTC_GUARDED_BY(main_thread_checker_); 188 bool recording_ RTC_GUARDED_BY(main_thread_checker_); 189 190 // Buffer used for audio samples to be played out. Size can be changed 191 // dynamically. The 16-bit samples are interleaved, hence the size is 192 // proportional to the number of channels. 193 BufferT<int16_t> play_buffer_; 194 195 // Byte buffer used for recorded audio samples. Size can be changed 196 // dynamically. 197 BufferT<int16_t> rec_buffer_; 198 199 // Contains true of a key-press has been detected. 200 bool typing_status_; 201 202 // Delay values used by the AEC. 203 int play_delay_ms_; 204 int rec_delay_ms_; 205 206 // Capture timestamp. 207 std::optional<int64_t> capture_timestamp_ns_; 208 // The last time the Timestamp Aligner was used to estimate clock offset 209 // between system clock and capture time from audio. 210 // This is used to prevent estimating the clock offset too often. 211 std::optional<int64_t> align_offsync_estimation_time_; 212 213 // Counts number of times LogStats() has been called. 214 size_t num_stat_reports_ RTC_GUARDED_BY(task_queue_); 215 216 // Time stamp of last timer task (drives logging). 217 int64_t last_timer_task_time_ RTC_GUARDED_BY(task_queue_); 218 219 // Counts number of audio callbacks modulo 50 to create a signal when 220 // a new storage of audio stats shall be done. 221 int16_t rec_stat_count_; 222 int16_t play_stat_count_; 223 224 // Time stamps of when playout and recording starts. 225 int64_t play_start_time_ RTC_GUARDED_BY(main_thread_checker_); 226 int64_t rec_start_time_ RTC_GUARDED_BY(main_thread_checker_); 227 228 // Contains counters for playout and recording statistics. 229 Stats stats_ RTC_GUARDED_BY(lock_); 230 231 // Stores current stats at each timer task. Used to calculate differences 232 // between two successive timer events. 233 Stats last_stats_ RTC_GUARDED_BY(task_queue_); 234 235 // Set to true at construction and modified to false as soon as one audio- 236 // level estimate larger than zero is detected. 237 bool only_silence_recorded_; 238 239 // Set to true when logging of audio stats is enabled for the first time in 240 // StartPeriodicLogging() and set to false by StopPeriodicLogging(). 241 // Setting this member to false prevents (possiby invalid) log messages from 242 // being printed in the LogStats() task. 243 bool log_stats_ RTC_GUARDED_BY(task_queue_); 244 245 // Used for converting capture timestaps (received from AudioRecordThread 246 // via AudioRecordJni::DataIsRecorded) to RTC clock. 247 TimestampAligner timestamp_aligner_; 248 249 // Should *never* be defined in production builds. Only used for testing. 250 // When defined, the output signal will be replaced by a sinus tone at 440Hz. 251 #ifdef AUDIO_DEVICE_PLAYS_SINUS_TONE 252 double phase_; 253 #endif 254 }; 255 256 } // namespace webrtc 257 258 #endif // MODULES_AUDIO_DEVICE_AUDIO_DEVICE_BUFFER_H_