xref: /aosp_15_r20/external/webrtc/modules/audio_device/android/aaudio_player.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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