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