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_RECORD_JNI_H_
1227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_RECORD_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/include/audio_device_defines.h"
1827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/modules/audio_device/audio_device_generic.h"
1927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
2027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgnamespace webrtc {
2127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
2227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgclass EventWrapper;
2327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgclass ThreadWrapper;
2427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgclass PlayoutDelayProvider;
2527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
2627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgconst uint32_t N_REC_SAMPLES_PER_SEC = 16000; // Default is 16 kHz
2727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgconst uint32_t N_REC_CHANNELS = 1; // default is mono recording
2827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgconst uint32_t REC_BUF_SIZE_IN_SAMPLES = 480; // Handle max 10 ms @ 48 kHz
2927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
3027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgclass AudioRecordJni {
3127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org public:
3227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  static int32_t SetAndroidAudioDeviceObjects(void* javaVM, void* env,
3327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org                                              void* context);
34f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org  static void ClearAndroidAudioDeviceObjects();
3527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
3627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  AudioRecordJni(const int32_t id, PlayoutDelayProvider* delay_provider);
3727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  ~AudioRecordJni();
3827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
3927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Main initializaton and termination
4027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t Init();
4127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t Terminate();
4227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool Initialized() const { return _initialized; }
4327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
4427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Device enumeration
4527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int16_t RecordingDevices() { return 1; }  // There is one device only
4627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t RecordingDeviceName(uint16_t index,
4727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org                              char name[kAdmMaxDeviceNameSize],
4827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org                              char guid[kAdmMaxGuidSize]);
4927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
5027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Device selection
5127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t SetRecordingDevice(uint16_t index);
5227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t SetRecordingDevice(
5327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org      AudioDeviceModule::WindowsDeviceType device);
5427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
5527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Audio transport initialization
5627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t RecordingIsAvailable(bool& available);  // NOLINT
5727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t InitRecording();
5827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool RecordingIsInitialized() const { return _recIsInitialized; }
5927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
6027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Audio transport control
6127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t StartRecording();
6227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t StopRecording();
6327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool Recording() const { return _recording; }
6427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
6527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Microphone Automatic Gain Control (AGC)
6627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t SetAGC(bool enable);
6727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool AGC() const { return _AGC; }
6827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
6927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Audio mixer initialization
7027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t InitMicrophone();
7127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool MicrophoneIsInitialized() const { return _micIsInitialized; }
7227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
7327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Microphone volume controls
7427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t MicrophoneVolumeIsAvailable(bool& available);  // NOLINT
7527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // TODO(leozwang): Add microphone volume control when OpenSL APIs
7627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // are available.
7727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t SetMicrophoneVolume(uint32_t volume);
7827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t MicrophoneVolume(uint32_t& volume) const;  // NOLINT
7927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const;  // NOLINT
8027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t MinMicrophoneVolume(uint32_t& minVolume) const;  // NOLINT
8127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t MicrophoneVolumeStepSize(
8227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org      uint16_t& stepSize) const;  // NOLINT
8327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
8427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Microphone mute control
8527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t MicrophoneMuteIsAvailable(bool& available);  // NOLINT
8627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t SetMicrophoneMute(bool enable);
8727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t MicrophoneMute(bool& enabled) const;  // NOLINT
8827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
8927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Microphone boost control
9027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t MicrophoneBoostIsAvailable(bool& available);  // NOLINT
9127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t SetMicrophoneBoost(bool enable);
9227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t MicrophoneBoost(bool& enabled) const;  // NOLINT
9327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
9427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Stereo support
9527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t StereoRecordingIsAvailable(bool& available);  // NOLINT
9627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t SetStereoRecording(bool enable);
9727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t StereoRecording(bool& enabled) const;  // NOLINT
9827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
9927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Delay information and control
10027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t RecordingDelay(uint16_t& delayMS) const;  // NOLINT
10127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
10227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool RecordingWarning() const;
10327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool RecordingError() const;
10427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  void ClearRecordingWarning();
10527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  void ClearRecordingError();
10627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
10727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  // Attach audio buffer
10827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
10927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
11027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t SetRecordingSampleRate(const uint32_t samplesPerSec);
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 RecThreadFunc(void*);
12427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool RecThreadProcess();
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* _jniEnvRec; // The JNI env for recording thread
13627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  jclass _javaScClass; // AudioDeviceAndroid class
13727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  jobject _javaScObj; // AudioDeviceAndroid object
13827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  jobject _javaRecBuffer;
13927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  void* _javaDirectRecBuffer; // Direct buffer pointer to rec buffer
14027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  jmethodID _javaMidRecAudio; // Method ID of rec in AudioDeviceAndroid
14127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
14227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  AudioDeviceBuffer* _ptrAudioBuffer;
14327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  CriticalSectionWrapper& _critSect;
14427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int32_t _id;
14527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  PlayoutDelayProvider* _delay_provider;
14627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool _initialized;
14727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
14827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  EventWrapper& _timeEventRec;
14927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  EventWrapper& _recStartStopEvent;
15027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  ThreadWrapper* _ptrThreadRec;
15127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  uint32_t _recThreadID;
15227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool _recThreadIsInitialized;
15327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool _shutdownRecThread;
15427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
15527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int8_t _recBuffer[2 * REC_BUF_SIZE_IN_SAMPLES];
15627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool _recordingDeviceIsSpecified;
15727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
15827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool _recording;
15927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool _recIsInitialized;
16027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool _micIsInitialized;
16127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
16227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool _startRec;
16327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
16427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  uint16_t _recWarning;
16527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  uint16_t _recError;
16627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
16727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  uint16_t _delayRecording;
16827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
16927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  bool _AGC;
17027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
17127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  uint16_t _samplingFreqIn; // Sampling frequency for Mic
17227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org  int _recAudioSource;
17327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
17427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org};
17527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
17627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org}  // namespace webrtc
17727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org
17827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#endif  // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_RECORD_JNI_H_
179