opensles_player.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright (c) 2015 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. #ifndef MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_
  11. #define MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_
  12. #include <SLES/OpenSLES.h>
  13. #include <SLES/OpenSLES_Android.h>
  14. #include <SLES/OpenSLES_AndroidConfiguration.h>
  15. #include "modules/audio_device/android/audio_common.h"
  16. #include "modules/audio_device/android/audio_manager.h"
  17. #include "modules/audio_device/android/opensles_common.h"
  18. #include "modules/audio_device/audio_device_generic.h"
  19. #include "modules/audio_device/include/audio_device_defines.h"
  20. #include "modules/utility/include/helpers_android.h"
  21. #include "rtc_base/thread_checker.h"
  22. namespace webrtc {
  23. class FineAudioBuffer;
  24. // Implements 16-bit mono PCM audio output support for Android using the
  25. // C based OpenSL ES API. No calls from C/C++ to Java using JNI is done.
  26. //
  27. // An instance must be created and destroyed on one and the same thread.
  28. // All public methods must also be called on the same thread. A thread checker
  29. // will RTC_DCHECK if any method is called on an invalid thread. Decoded audio
  30. // buffers are requested on a dedicated internal thread managed by the OpenSL
  31. // ES layer.
  32. //
  33. // The existing design forces the user to call InitPlayout() after Stoplayout()
  34. // to be able to call StartPlayout() again. This is inline with how the Java-
  35. // based implementation works.
  36. //
  37. // OpenSL ES is a native C API which have no Dalvik-related overhead such as
  38. // garbage collection pauses and it supports reduced audio output latency.
  39. // If the device doesn't claim this feature but supports API level 9 (Android
  40. // platform version 2.3) or later, then we can still use the OpenSL ES APIs but
  41. // the output latency may be higher.
  42. class OpenSLESPlayer {
  43. public:
  44. // Beginning with API level 17 (Android 4.2), a buffer count of 2 or more is
  45. // required for lower latency. Beginning with API level 18 (Android 4.3), a
  46. // buffer count of 1 is sufficient for lower latency. In addition, the buffer
  47. // size and sample rate must be compatible with the device's native output
  48. // configuration provided via the audio manager at construction.
  49. // TODO(henrika): perhaps set this value dynamically based on OS version.
  50. static const int kNumOfOpenSLESBuffers = 2;
  51. explicit OpenSLESPlayer(AudioManager* audio_manager);
  52. ~OpenSLESPlayer();
  53. int Init();
  54. int Terminate();
  55. int InitPlayout();
  56. bool PlayoutIsInitialized() const { return initialized_; }
  57. int StartPlayout();
  58. int StopPlayout();
  59. bool Playing() const { return playing_; }
  60. int SpeakerVolumeIsAvailable(bool& available);
  61. int SetSpeakerVolume(uint32_t volume);
  62. int SpeakerVolume(uint32_t& volume) const;
  63. int MaxSpeakerVolume(uint32_t& maxVolume) const;
  64. int MinSpeakerVolume(uint32_t& minVolume) const;
  65. void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
  66. private:
  67. // These callback methods are called when data is required for playout.
  68. // They are both called from an internal "OpenSL ES thread" which is not
  69. // attached to the Dalvik VM.
  70. static void SimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf caller,
  71. void* context);
  72. void FillBufferQueue();
  73. // Reads audio data in PCM format using the AudioDeviceBuffer.
  74. // Can be called both on the main thread (during Start()) and from the
  75. // internal audio thread while output streaming is active.
  76. // If the |silence| flag is set, the audio is filled with zeros instead of
  77. // asking the WebRTC layer for real audio data. This procedure is also known
  78. // as audio priming.
  79. void EnqueuePlayoutData(bool silence);
  80. // Allocate memory for audio buffers which will be used to render audio
  81. // via the SLAndroidSimpleBufferQueueItf interface.
  82. void AllocateDataBuffers();
  83. // Obtaines the SL Engine Interface from the existing global Engine object.
  84. // The interface exposes creation methods of all the OpenSL ES object types.
  85. // This method defines the |engine_| member variable.
  86. bool ObtainEngineInterface();
  87. // Creates/destroys the output mix object.
  88. bool CreateMix();
  89. void DestroyMix();
  90. // Creates/destroys the audio player and the simple-buffer object.
  91. // Also creates the volume object.
  92. bool CreateAudioPlayer();
  93. void DestroyAudioPlayer();
  94. SLuint32 GetPlayState() const;
  95. // Ensures that methods are called from the same thread as this object is
  96. // created on.
  97. rtc::ThreadChecker thread_checker_;
  98. // Stores thread ID in first call to SimpleBufferQueueCallback() from internal
  99. // non-application thread which is not attached to the Dalvik JVM.
  100. // Detached during construction of this object.
  101. rtc::ThreadChecker thread_checker_opensles_;
  102. // Raw pointer to the audio manager injected at construction. Used to cache
  103. // audio parameters and to access the global SL engine object needed by the
  104. // ObtainEngineInterface() method. The audio manager outlives any instance of
  105. // this class.
  106. AudioManager* audio_manager_;
  107. // Contains audio parameters provided to this class at construction by the
  108. // AudioManager.
  109. const AudioParameters audio_parameters_;
  110. // Raw pointer handle provided to us in AttachAudioBuffer(). Owned by the
  111. // AudioDeviceModuleImpl class and called by AudioDeviceModule::Create().
  112. AudioDeviceBuffer* audio_device_buffer_;
  113. bool initialized_;
  114. bool playing_;
  115. // PCM-type format definition.
  116. // TODO(henrika): add support for SLAndroidDataFormat_PCM_EX (android-21) if
  117. // 32-bit float representation is needed.
  118. SLDataFormat_PCM pcm_format_;
  119. // Queue of audio buffers to be used by the player object for rendering
  120. // audio.
  121. std::unique_ptr<SLint16[]> audio_buffers_[kNumOfOpenSLESBuffers];
  122. // FineAudioBuffer takes an AudioDeviceBuffer which delivers audio data
  123. // in chunks of 10ms. It then allows for this data to be pulled in
  124. // a finer or coarser granularity. I.e. interacting with this class instead
  125. // of directly with the AudioDeviceBuffer one can ask for any number of
  126. // audio data samples.
  127. // Example: native buffer size can be 192 audio frames at 48kHz sample rate.
  128. // WebRTC will provide 480 audio frames per 10ms but OpenSL ES asks for 192
  129. // in each callback (one every 4th ms). This class can then ask for 192 and
  130. // the FineAudioBuffer will ask WebRTC for new data approximately only every
  131. // second callback and also cache non-utilized audio.
  132. std::unique_ptr<FineAudioBuffer> fine_audio_buffer_;
  133. // Keeps track of active audio buffer 'n' in the audio_buffers_[n] queue.
  134. // Example (kNumOfOpenSLESBuffers = 2): counts 0, 1, 0, 1, ...
  135. int buffer_index_;
  136. // This interface exposes creation methods for all the OpenSL ES object types.
  137. // It is the OpenSL ES API entry point.
  138. SLEngineItf engine_;
  139. // Output mix object to be used by the player object.
  140. webrtc::ScopedSLObjectItf output_mix_;
  141. // The audio player media object plays out audio to the speakers. It also
  142. // supports volume control.
  143. webrtc::ScopedSLObjectItf player_object_;
  144. // This interface is supported on the audio player and it controls the state
  145. // of the audio player.
  146. SLPlayItf player_;
  147. // The Android Simple Buffer Queue interface is supported on the audio player
  148. // and it provides methods to send audio data from the source to the audio
  149. // player for rendering.
  150. SLAndroidSimpleBufferQueueItf simple_buffer_queue_;
  151. // This interface exposes controls for manipulating the object’s audio volume
  152. // properties. This interface is supported on the Audio Player object.
  153. SLVolumeItf volume_;
  154. // Last time the OpenSL ES layer asked for audio data to play out.
  155. uint32_t last_play_time_;
  156. };
  157. } // namespace webrtc
  158. #endif // MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_