127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org/* 227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org * 427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org * Use of this source code is governed by a BSD-style license 527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org * in the file PATENTS. All contributing project authors may 827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org */ 1027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 1127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_TRACK_JNI_H_ 1227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_TRACK_JNI_H_ 1327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 1427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include <jni.h> 1527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 1627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 1727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/modules/audio_device/android/audio_common.h" 1827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/modules/audio_device/include/audio_device_defines.h" 1927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/modules/audio_device/audio_device_generic.h" 2027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 2127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgnamespace webrtc { 2227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 2327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgclass EventWrapper; 2427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgclass ThreadWrapper; 2527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 2627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgconst uint32_t N_PLAY_SAMPLES_PER_SEC = 16000; // Default is 16 kHz 2727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgconst uint32_t N_PLAY_CHANNELS = 1; // default is mono playout 2827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 2927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgclass AudioTrackJni : public PlayoutDelayProvider { 3027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org public: 3127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org static int32_t SetAndroidAudioDeviceObjects(void* javaVM, void* env, 3227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org void* context); 33f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org static void ClearAndroidAudioDeviceObjects(); 3427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org explicit AudioTrackJni(const int32_t id); 3527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org virtual ~AudioTrackJni(); 3627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 3727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Main initializaton and termination 3827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t Init(); 3927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t Terminate(); 4027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool Initialized() const { return _initialized; } 4127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 4227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Device enumeration 4327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int16_t PlayoutDevices() { return 1; } // There is one device only. 4427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 4527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t PlayoutDeviceName(uint16_t index, 4627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org char name[kAdmMaxDeviceNameSize], 4727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org char guid[kAdmMaxGuidSize]); 4827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 4927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Device selection 5027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SetPlayoutDevice(uint16_t index); 5127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SetPlayoutDevice( 5227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org AudioDeviceModule::WindowsDeviceType device); 5327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 5427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Audio transport initialization 5527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t PlayoutIsAvailable(bool& available); // NOLINT 5627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t InitPlayout(); 5727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool PlayoutIsInitialized() const { return _playIsInitialized; } 5827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 5927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Audio transport control 6027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t StartPlayout(); 6127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t StopPlayout(); 6227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool Playing() const { return _playing; } 6327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 6427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Audio mixer initialization 6527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t InitSpeaker(); 6627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool SpeakerIsInitialized() const { return _speakerIsInitialized; } 6727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 6827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Speaker volume controls 6927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SpeakerVolumeIsAvailable(bool& available); // NOLINT 7027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SetSpeakerVolume(uint32_t volume); 7127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SpeakerVolume(uint32_t& volume) const; // NOLINT 7227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t MaxSpeakerVolume(uint32_t& maxVolume) const; // NOLINT 7327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t MinSpeakerVolume(uint32_t& minVolume) const; // NOLINT 7427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const; // NOLINT 7527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 7627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Speaker mute control 7727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SpeakerMuteIsAvailable(bool& available); // NOLINT 7827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SetSpeakerMute(bool enable); 7927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SpeakerMute(bool& enabled) const; // NOLINT 8027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 8127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 8227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Stereo support 8327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t StereoPlayoutIsAvailable(bool& available); // NOLINT 8427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SetStereoPlayout(bool enable); 8527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t StereoPlayout(bool& enabled) const; // NOLINT 8627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 8727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Delay information and control 8827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SetPlayoutBuffer(const AudioDeviceModule::BufferType type, 8927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint16_t sizeMS); 9027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type, // NOLINT 9127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint16_t& sizeMS) const; 9227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t PlayoutDelay(uint16_t& delayMS) const; // NOLINT 9327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 9427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Attach audio buffer 9527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer); 9627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 9727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SetPlayoutSampleRate(const uint32_t samplesPerSec); 9827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 9927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Error and warning information 10027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool PlayoutWarning() const; 10127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool PlayoutError() const; 10227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org void ClearPlayoutWarning(); 10327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org void ClearPlayoutError(); 10427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 10527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Speaker audio routing 10627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t SetLoudspeakerStatus(bool enable); 10727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t GetLoudspeakerStatus(bool& enable) const; // NOLINT 10827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 10927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org protected: 11027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org virtual int PlayoutDelayMs() { return 0; } 11127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 11227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org private: 113fba14761cb9c35c2e931d7b0ad033136f92453e8andresp@webrtc.org void Lock() EXCLUSIVE_LOCK_FUNCTION(_critSect) { 11427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _critSect.Enter(); 115fba14761cb9c35c2e931d7b0ad033136f92453e8andresp@webrtc.org } 116fba14761cb9c35c2e931d7b0ad033136f92453e8andresp@webrtc.org void UnLock() UNLOCK_FUNCTION(_critSect) { 11727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _critSect.Leave(); 118fba14761cb9c35c2e931d7b0ad033136f92453e8andresp@webrtc.org } 11927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 12027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t InitJavaResources(); 12127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t InitSampleRate(); 12227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 12327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org static bool PlayThreadFunc(void*); 12427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool PlayThreadProcess(); 12527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 12627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // TODO(leozwang): Android holds only one JVM, all these jni handling 12727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // will be consolidated into a single place to make it consistant and 12827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // reliable. Chromium has a good example at base/android. 12927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org static JavaVM* globalJvm; 13027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org static JNIEnv* globalJNIEnv; 13127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org static jobject globalContext; 13227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org static jclass globalScClass; 13327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 13427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org JavaVM* _javaVM; // denotes a Java VM 13527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org JNIEnv* _jniEnvPlay; // The JNI env for playout thread 13627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jclass _javaScClass; // AudioDeviceAndroid class 13727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jobject _javaScObj; // AudioDeviceAndroid object 13827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jobject _javaPlayBuffer; 13927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org void* _javaDirectPlayBuffer; // Direct buffer pointer to play buffer 14027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jmethodID _javaMidPlayAudio; // Method ID of play in AudioDeviceAndroid 14127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 14227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org AudioDeviceBuffer* _ptrAudioBuffer; 14327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org CriticalSectionWrapper& _critSect; 14427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t _id; 14527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool _initialized; 14627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 14727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org EventWrapper& _timeEventPlay; 14827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org EventWrapper& _playStartStopEvent; 14927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org ThreadWrapper* _ptrThreadPlay; 15027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint32_t _playThreadID; 15127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool _playThreadIsInitialized; 15227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool _shutdownPlayThread; 15327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool _playoutDeviceIsSpecified; 15427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 15527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool _playing; 15627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool _playIsInitialized; 15727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool _speakerIsInitialized; 15827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 15927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool _startPlay; 16027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 16127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint16_t _playWarning; 16227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint16_t _playError; 16327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 16427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint16_t _delayPlayout; 16527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 16627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint16_t _samplingFreqOut; // Sampling frequency for Speaker 16727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint32_t _maxSpeakerVolume; // The maximum speaker volume value 16827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool _loudSpeakerOn; 16927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 17027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org}; 17127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 17227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} // namespace webrtc 17327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 17427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_TRACK_JNI_H_ 175