1 /* 2 * Copyright (c) 2018 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_ANDROID_AAUDIO_PLAYER_H_ 12 #define MODULES_AUDIO_DEVICE_ANDROID_AAUDIO_PLAYER_H_ 13 14 #include <aaudio/AAudio.h> 15 16 #include <memory> 17 18 #include "api/sequence_checker.h" 19 #include "api/task_queue/task_queue_base.h" 20 #include "modules/audio_device/android/aaudio_wrapper.h" 21 #include "modules/audio_device/include/audio_device_defines.h" 22 #include "rtc_base/thread_annotations.h" 23 24 namespace webrtc { 25 26 class AudioDeviceBuffer; 27 class FineAudioBuffer; 28 class AudioManager; 29 30 // Implements low-latency 16-bit mono PCM audio output support for Android 31 // using the C based AAudio API. 32 // 33 // An instance must be created and destroyed on one and the same thread. 34 // All public methods must also be called on the same thread. A thread checker 35 // will DCHECK if any method is called on an invalid thread. Audio buffers 36 // are requested on a dedicated high-priority thread owned by AAudio. 37 // 38 // The existing design forces the user to call InitPlayout() after StopPlayout() 39 // to be able to call StartPlayout() again. This is in line with how the Java- 40 // based implementation works. 41 // 42 // An audio stream can be disconnected, e.g. when an audio device is removed. 43 // This implementation will restart the audio stream using the new preferred 44 // device if such an event happens. 45 // 46 // Also supports automatic buffer-size adjustment based on underrun detections 47 // where the internal AAudio buffer can be increased when needed. It will 48 // reduce the risk of underruns (~glitches) at the expense of an increased 49 // latency. 50 class AAudioPlayer final : public AAudioObserverInterface { 51 public: 52 explicit AAudioPlayer(AudioManager* audio_manager); 53 ~AAudioPlayer(); 54 55 int Init(); 56 int Terminate(); 57 58 int InitPlayout(); 59 bool PlayoutIsInitialized() const; 60 61 int StartPlayout(); 62 int StopPlayout(); 63 bool Playing() const; 64 65 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer); 66 67 // Not implemented in AAudio. 68 int SpeakerVolumeIsAvailable(bool& available); // NOLINT SetSpeakerVolume(uint32_t volume)69 int SetSpeakerVolume(uint32_t volume) { return -1; } SpeakerVolume(uint32_t & volume)70 int SpeakerVolume(uint32_t& volume) const { return -1; } // NOLINT MaxSpeakerVolume(uint32_t & maxVolume)71 int MaxSpeakerVolume(uint32_t& maxVolume) const { return -1; } // NOLINT MinSpeakerVolume(uint32_t & minVolume)72 int MinSpeakerVolume(uint32_t& minVolume) const { return -1; } // NOLINT 73 74 protected: 75 // AAudioObserverInterface implementation. 76 77 // For an output stream, this function should render and write `num_frames` 78 // of data in the streams current data format to the `audio_data` buffer. 79 // Called on a real-time thread owned by AAudio. 80 aaudio_data_callback_result_t OnDataCallback(void* audio_data, 81 int32_t num_frames) override; 82 // AAudio calls this functions if any error occurs on a callback thread. 83 // Called on a real-time thread owned by AAudio. 84 void OnErrorCallback(aaudio_result_t error) override; 85 86 private: 87 // Closes the existing stream and starts a new stream. 88 void HandleStreamDisconnected(); 89 90 // Ensures that methods are called from the same thread as this object is 91 // created on. 92 SequenceChecker main_thread_checker_; 93 94 // Stores thread ID in first call to AAudioPlayer::OnDataCallback from a 95 // real-time thread owned by AAudio. Detached during construction of this 96 // object. 97 SequenceChecker thread_checker_aaudio_; 98 99 // The task queue on which this object is created on. 100 TaskQueueBase* main_thread_; 101 102 // Wraps all AAudio resources. Contains an output stream using the default 103 // output audio device. Can be accessed on both the main thread and the 104 // real-time thread owned by AAudio. See separate AAudio documentation about 105 // thread safety. 106 AAudioWrapper aaudio_; 107 108 // FineAudioBuffer takes an AudioDeviceBuffer which delivers audio data 109 // in chunks of 10ms. It then allows for this data to be pulled in 110 // a finer or coarser granularity. I.e. interacting with this class instead 111 // of directly with the AudioDeviceBuffer one can ask for any number of 112 // audio data samples. 113 // Example: native buffer size can be 192 audio frames at 48kHz sample rate. 114 // WebRTC will provide 480 audio frames per 10ms but AAudio asks for 192 115 // in each callback (once every 4th ms). This class can then ask for 192 and 116 // the FineAudioBuffer will ask WebRTC for new data approximately only every 117 // second callback and also cache non-utilized audio. 118 std::unique_ptr<FineAudioBuffer> fine_audio_buffer_; 119 120 // Counts number of detected underrun events reported by AAudio. 121 int32_t underrun_count_ = 0; 122 123 // True only for the first data callback in each audio session. 124 bool first_data_callback_ = true; 125 126 // Raw pointer handle provided to us in AttachAudioBuffer(). Owned by the 127 // AudioDeviceModuleImpl class and set by AudioDeviceModule::Create(). 128 AudioDeviceBuffer* audio_device_buffer_ RTC_GUARDED_BY(main_thread_checker_) = 129 nullptr; 130 131 bool initialized_ RTC_GUARDED_BY(main_thread_checker_) = false; 132 bool playing_ RTC_GUARDED_BY(main_thread_checker_) = false; 133 134 // Estimated latency between writing an audio frame to the output stream and 135 // the time that same frame is played out on the output audio device. 136 double latency_millis_ RTC_GUARDED_BY(thread_checker_aaudio_) = 0; 137 }; 138 139 } // namespace webrtc 140 141 #endif // MODULES_AUDIO_DEVICE_ANDROID_AAUDIO_PLAYER_H_ 142