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