| /* |
| * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #ifndef MODULES_AUDIO_DEVICE_ANDROID_AAUDIO_PLAYER_H_ |
| #define MODULES_AUDIO_DEVICE_ANDROID_AAUDIO_PLAYER_H_ |
| |
| #include <aaudio/AAudio.h> |
| |
| #include <memory> |
| |
| #include "modules/audio_device/android/aaudio_wrapper.h" |
| #include "modules/audio_device/include/audio_device_defines.h" |
| #include "rtc_base/message_handler.h" |
| #include "rtc_base/thread.h" |
| #include "rtc_base/thread_annotations.h" |
| #include "rtc_base/thread_checker.h" |
| |
| namespace webrtc { |
| |
| class AudioDeviceBuffer; |
| class FineAudioBuffer; |
| class AudioManager; |
| |
| // Implements low-latency 16-bit mono PCM audio output support for Android |
| // using the C based AAudio API. |
| // |
| // An instance must be created and destroyed on one and the same thread. |
| // All public methods must also be called on the same thread. A thread checker |
| // will DCHECK if any method is called on an invalid thread. Audio buffers |
| // are requested on a dedicated high-priority thread owned by AAudio. |
| // |
| // The existing design forces the user to call InitPlayout() after StopPlayout() |
| // to be able to call StartPlayout() again. This is in line with how the Java- |
| // based implementation works. |
| // |
| // An audio stream can be disconnected, e.g. when an audio device is removed. |
| // This implementation will restart the audio stream using the new preferred |
| // device if such an event happens. |
| // |
| // Also supports automatic buffer-size adjustment based on underrun detections |
| // where the internal AAudio buffer can be increased when needed. It will |
| // reduce the risk of underruns (~glitches) at the expense of an increased |
| // latency. |
| class AAudioPlayer final : public AAudioObserverInterface, |
| public rtc::MessageHandler { |
| public: |
| explicit AAudioPlayer(AudioManager* audio_manager); |
| ~AAudioPlayer(); |
| |
| int Init(); |
| int Terminate(); |
| |
| int InitPlayout(); |
| bool PlayoutIsInitialized() const; |
| |
| int StartPlayout(); |
| int StopPlayout(); |
| bool Playing() const; |
| |
| void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer); |
| |
| // Not implemented in AAudio. |
| int SpeakerVolumeIsAvailable(bool& available); // NOLINT |
| int SetSpeakerVolume(uint32_t volume) { return -1; } |
| int SpeakerVolume(uint32_t& volume) const { return -1; } // NOLINT |
| int MaxSpeakerVolume(uint32_t& maxVolume) const { return -1; } // NOLINT |
| int MinSpeakerVolume(uint32_t& minVolume) const { return -1; } // NOLINT |
| |
| protected: |
| // AAudioObserverInterface implementation. |
| |
| // For an output stream, this function should render and write |num_frames| |
| // of data in the streams current data format to the |audio_data| buffer. |
| // Called on a real-time thread owned by AAudio. |
| aaudio_data_callback_result_t OnDataCallback(void* audio_data, |
| int32_t num_frames) override; |
| // AAudio calls this functions if any error occurs on a callback thread. |
| // Called on a real-time thread owned by AAudio. |
| void OnErrorCallback(aaudio_result_t error) override; |
| |
| // rtc::MessageHandler used for restart messages from the error-callback |
| // thread to the main (creating) thread. |
| void OnMessage(rtc::Message* msg) override; |
| |
| private: |
| // Closes the existing stream and starts a new stream. |
| void HandleStreamDisconnected(); |
| |
| // Ensures that methods are called from the same thread as this object is |
| // created on. |
| rtc::ThreadChecker main_thread_checker_; |
| |
| // Stores thread ID in first call to AAudioPlayer::OnDataCallback from a |
| // real-time thread owned by AAudio. Detached during construction of this |
| // object. |
| rtc::ThreadChecker thread_checker_aaudio_; |
| |
| // The thread on which this object is created on. |
| rtc::Thread* main_thread_; |
| |
| // Wraps all AAudio resources. Contains an output stream using the default |
| // output audio device. Can be accessed on both the main thread and the |
| // real-time thread owned by AAudio. See separate AAudio documentation about |
| // thread safety. |
| AAudioWrapper aaudio_; |
| |
| // FineAudioBuffer takes an AudioDeviceBuffer which delivers audio data |
| // in chunks of 10ms. It then allows for this data to be pulled in |
| // a finer or coarser granularity. I.e. interacting with this class instead |
| // of directly with the AudioDeviceBuffer one can ask for any number of |
| // audio data samples. |
| // Example: native buffer size can be 192 audio frames at 48kHz sample rate. |
| // WebRTC will provide 480 audio frames per 10ms but AAudio asks for 192 |
| // in each callback (once every 4th ms). This class can then ask for 192 and |
| // the FineAudioBuffer will ask WebRTC for new data approximately only every |
| // second callback and also cache non-utilized audio. |
| std::unique_ptr<FineAudioBuffer> fine_audio_buffer_; |
| |
| // Counts number of detected underrun events reported by AAudio. |
| int32_t underrun_count_ = 0; |
| |
| // True only for the first data callback in each audio session. |
| bool first_data_callback_ = true; |
| |
| // Raw pointer handle provided to us in AttachAudioBuffer(). Owned by the |
| // AudioDeviceModuleImpl class and set by AudioDeviceModule::Create(). |
| AudioDeviceBuffer* audio_device_buffer_ RTC_GUARDED_BY(main_thread_checker_) = |
| nullptr; |
| |
| bool initialized_ RTC_GUARDED_BY(main_thread_checker_) = false; |
| bool playing_ RTC_GUARDED_BY(main_thread_checker_) = false; |
| |
| // Estimated latency between writing an audio frame to the output stream and |
| // the time that same frame is played out on the output audio device. |
| double latency_millis_ RTC_GUARDED_BY(thread_checker_aaudio_) = 0; |
| }; |
| |
| } // namespace webrtc |
| |
| #endif // MODULES_AUDIO_DEVICE_ANDROID_AAUDIO_PLAYER_H_ |