1 /* 2 * Copyright (c) 2013 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 SDK_ANDROID_SRC_JNI_AUDIO_DEVICE_AUDIO_RECORD_JNI_H_ 12 #define SDK_ANDROID_SRC_JNI_AUDIO_DEVICE_AUDIO_RECORD_JNI_H_ 13 14 #include <jni.h> 15 #include <memory> 16 17 #include "modules/audio_device/audio_device_buffer.h" 18 #include "modules/audio_device/include/audio_device_defines.h" 19 #include "rtc_base/thread_checker.h" 20 #include "sdk/android/src/jni/audio_device/audio_device_module.h" 21 22 namespace webrtc { 23 24 namespace jni { 25 26 // Implements 16-bit mono PCM audio input support for Android using the Java 27 // AudioRecord interface. Most of the work is done by its Java counterpart in 28 // WebRtcAudioRecord.java. This class is created and lives on a thread in 29 // C++-land, but recorded audio buffers are delivered on a high-priority 30 // thread managed by the Java class. 31 // 32 // The Java class makes use of AudioEffect features (mainly AEC) which are 33 // first available in Jelly Bean. If it is instantiated running against earlier 34 // SDKs, the AEC provided by the APM in WebRTC must be used and enabled 35 // separately instead. 36 // 37 // An instance can be created on any thread, but must then be used on one and 38 // the same thread. All public methods must also be called on the same thread. A 39 // thread checker will RTC_DCHECK if any method is called on an invalid thread. 40 // 41 // This class uses AttachCurrentThreadIfNeeded to attach to a Java VM if needed. 42 // Additional thread checking guarantees that no other (possibly non attached) 43 // thread is used. 44 class AudioRecordJni : public AudioInput { 45 public: 46 static ScopedJavaLocalRef<jobject> CreateJavaWebRtcAudioRecord( 47 JNIEnv* env, 48 const JavaRef<jobject>& j_context, 49 const JavaRef<jobject>& j_audio_manager); 50 51 AudioRecordJni(JNIEnv* env, 52 const AudioParameters& audio_parameters, 53 int total_delay_ms, 54 const JavaRef<jobject>& j_webrtc_audio_record); 55 ~AudioRecordJni() override; 56 57 int32_t Init() override; 58 int32_t Terminate() override; 59 60 int32_t InitRecording() override; 61 bool RecordingIsInitialized() const override; 62 63 int32_t StartRecording() override; 64 int32_t StopRecording() override; 65 bool Recording() const override; 66 67 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override; 68 69 bool IsAcousticEchoCancelerSupported() const override; 70 bool IsNoiseSuppressorSupported() const override; 71 72 int32_t EnableBuiltInAEC(bool enable) override; 73 int32_t EnableBuiltInNS(bool enable) override; 74 75 // Called from Java side so we can cache the address of the Java-manged 76 // |byte_buffer| in |direct_buffer_address_|. The size of the buffer 77 // is also stored in |direct_buffer_capacity_in_bytes_|. 78 // This method will be called by the WebRtcAudioRecord constructor, i.e., 79 // on the same thread that this object is created on. 80 void CacheDirectBufferAddress(JNIEnv* env, 81 const JavaParamRef<jobject>& j_caller, 82 const JavaParamRef<jobject>& byte_buffer); 83 84 // Called periodically by the Java based WebRtcAudioRecord object when 85 // recording has started. Each call indicates that there are |length| new 86 // bytes recorded in the memory area |direct_buffer_address_| and it is 87 // now time to send these to the consumer. 88 // This method is called on a high-priority thread from Java. The name of 89 // the thread is 'AudioRecordThread'. 90 void DataIsRecorded(JNIEnv* env, 91 const JavaParamRef<jobject>& j_caller, 92 int length); 93 94 private: 95 // Stores thread ID in constructor. 96 rtc::ThreadChecker thread_checker_; 97 98 // Stores thread ID in first call to OnDataIsRecorded() from high-priority 99 // thread in Java. Detached during construction of this object. 100 rtc::ThreadChecker thread_checker_java_; 101 102 // Wraps the Java specific parts of the AudioRecordJni class. 103 JNIEnv* env_ = nullptr; 104 ScopedJavaGlobalRef<jobject> j_audio_record_; 105 106 const AudioParameters audio_parameters_; 107 108 // Delay estimate of the total round-trip delay (input + output). 109 // Fixed value set once in AttachAudioBuffer() and it can take one out of two 110 // possible values. See audio_common.h for details. 111 const int total_delay_ms_; 112 113 // Cached copy of address to direct audio buffer owned by |j_audio_record_|. 114 void* direct_buffer_address_; 115 116 // Number of bytes in the direct audio buffer owned by |j_audio_record_|. 117 size_t direct_buffer_capacity_in_bytes_; 118 119 // Number audio frames per audio buffer. Each audio frame corresponds to 120 // one sample of PCM mono data at 16 bits per sample. Hence, each audio 121 // frame contains 2 bytes (given that the Java layer only supports mono). 122 // Example: 480 for 48000 Hz or 441 for 44100 Hz. 123 size_t frames_per_buffer_; 124 125 bool initialized_; 126 127 bool recording_; 128 129 // Raw pointer handle provided to us in AttachAudioBuffer(). Owned by the 130 // AudioDeviceModuleImpl class and called by AudioDeviceModule::Create(). 131 AudioDeviceBuffer* audio_device_buffer_; 132 }; 133 134 } // namespace jni 135 136 } // namespace webrtc 137 138 #endif // SDK_ANDROID_SRC_JNI_AUDIO_DEVICE_AUDIO_RECORD_JNI_H_ 139