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