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/* 1227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org * Android audio device implementation (JNI/AudioRecord usage) 1327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org */ 1427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 1527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org// TODO(xians): Break out attach and detach current thread to JVM to 1627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org// separate functions. 1727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 1827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/modules/audio_device/android/audio_record_jni.h" 1927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 2027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include <android/log.h> 2127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include <stdlib.h> 2227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 2327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/modules/audio_device/android/audio_common.h" 2427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/modules/audio_device/audio_device_config.h" 2527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/modules/audio_device/audio_device_utility.h" 2627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 2727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h" 2827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h" 2927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 3027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 3127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgnamespace webrtc { 3227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 3327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgJavaVM* AudioRecordJni::globalJvm = NULL; 3427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgJNIEnv* AudioRecordJni::globalJNIEnv = NULL; 3527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgjobject AudioRecordJni::globalContext = NULL; 3627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgjclass AudioRecordJni::globalScClass = NULL; 3727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 3827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::SetAndroidAudioDeviceObjects(void* javaVM, void* env, 3927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org void* context) { 40f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org assert(env); 4127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org globalJvm = reinterpret_cast<JavaVM*>(javaVM); 42f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalJNIEnv = reinterpret_cast<JNIEnv*>(env); 43f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org // Get java class type (note path to class packet). 44f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org jclass javaScClassLocal = globalJNIEnv->FindClass( 45f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org "org/webrtc/voiceengine/WebRtcAudioRecord"); 46f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org if (!javaScClassLocal) { 47f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1, 48f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org "%s: could not find java class", __FUNCTION__); 49f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org return -1; // exception thrown 50f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org } 51f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org 52f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org // Create a global reference to the class (to tell JNI that we are 53f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org // referencing it after this function has returned). 54f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalScClass = reinterpret_cast<jclass> ( 55f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalJNIEnv->NewGlobalRef(javaScClassLocal)); 56f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org if (!globalScClass) { 57f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1, 58f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org "%s: could not create reference", __FUNCTION__); 59f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org return -1; 60f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org } 6127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 62f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalContext = globalJNIEnv->NewGlobalRef( 63f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org reinterpret_cast<jobject>(context)); 64f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org if (!globalContext) { 65f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1, 66f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org "%s: could not create context reference", __FUNCTION__); 67f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org return -1; 6827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 6927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 70f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org // Delete local class ref, we only use the global ref 71f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalJNIEnv->DeleteLocalRef(javaScClassLocal); 7227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 73f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org return 0; 74f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org} 7527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 76f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.orgvoid AudioRecordJni::ClearAndroidAudioDeviceObjects() { 77f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, -1, 78f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org "%s: env is NULL, assuming deinit", __FUNCTION__); 7927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 80f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalJvm = NULL;; 81f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org if (!globalJNIEnv) { 82f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, -1, 83f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org "%s: saved env already NULL", __FUNCTION__); 84f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org return; 8527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 8627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 87f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalJNIEnv->DeleteGlobalRef(globalContext); 88f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalContext = reinterpret_cast<jobject>(NULL); 89f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org 90f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalJNIEnv->DeleteGlobalRef(globalScClass); 91f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalScClass = reinterpret_cast<jclass>(NULL); 92f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org 93f3a2ef39a9ba3d382916bcfb67c952781ab91df3henrike@webrtc.org globalJNIEnv = reinterpret_cast<JNIEnv*>(NULL); 9427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 9527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 9627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgAudioRecordJni::AudioRecordJni( 9727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org const int32_t id, PlayoutDelayProvider* delay_provider) 9827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org : _javaVM(NULL), 9927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _jniEnvRec(NULL), 10027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaScClass(0), 10127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaScObj(0), 10227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaRecBuffer(0), 10327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaDirectRecBuffer(NULL), 10427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaMidRecAudio(0), 10527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrAudioBuffer(NULL), 10627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _critSect(*CriticalSectionWrapper::CreateCriticalSection()), 10727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _id(id), 10827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _delay_provider(delay_provider), 10927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _initialized(false), 11027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _timeEventRec(*EventWrapper::Create()), 11127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recStartStopEvent(*EventWrapper::Create()), 11227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrThreadRec(NULL), 11327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recThreadID(0), 11427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recThreadIsInitialized(false), 11527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _shutdownRecThread(false), 11627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recordingDeviceIsSpecified(false), 11727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recording(false), 11827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recIsInitialized(false), 11927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _micIsInitialized(false), 12027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _startRec(false), 12127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recWarning(0), 12227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recError(0), 12327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _delayRecording(0), 12427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _AGC(false), 12527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _samplingFreqIn((N_REC_SAMPLES_PER_SEC/1000)), 12627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recAudioSource(1) { // 1 is AudioSource.MIC which is our default 12727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org memset(_recBuffer, 0, sizeof(_recBuffer)); 12827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 12927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 13027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgAudioRecordJni::~AudioRecordJni() { 13127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, 13227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s destroyed", __FUNCTION__); 13327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 13427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org Terminate(); 13527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 13627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org delete &_recStartStopEvent; 13727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org delete &_timeEventRec; 13827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org delete &_critSect; 13927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 14027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 14127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::Init() { 14227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org CriticalSectionScoped lock(&_critSect); 14327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 14427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_initialized) 14527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 14627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 14727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 14827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 14927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recWarning = 0; 15027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recError = 0; 15127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 15227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Init Java member variables 15327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // and set up JNI interface to 15427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // AudioDeviceAndroid java class 15527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (InitJavaResources() != 0) 15627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 15727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 15827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Failed to init Java resources", __FUNCTION__); 15927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 16027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 16127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 16227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Check the sample rate to be used for playback and recording 16327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // and the max playout volume 16427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (InitSampleRate() != 0) 16527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 16627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 16727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Failed to init samplerate", __FUNCTION__); 16827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 16927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 17027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 17127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org const char* threadName = "jni_audio_capture_thread"; 17227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrThreadRec = ThreadWrapper::CreateThread(RecThreadFunc, this, 17327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org kRealtimePriority, threadName); 17427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_ptrThreadRec == NULL) 17527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 17627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, 17727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " failed to create the rec audio thread"); 17827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 17927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 18027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 18127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org unsigned int threadID(0); 18227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_ptrThreadRec->Start(threadID)) 18327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 18427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, _id, 18527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " failed to start the rec audio thread"); 18627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org delete _ptrThreadRec; 18727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrThreadRec = NULL; 18827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 18927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 19027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recThreadID = threadID; 19127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _initialized = true; 19227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 19327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 19427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 19527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 19627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::Terminate() { 19727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org CriticalSectionScoped lock(&_critSect); 19827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 19927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_initialized) 20027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 20127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 20227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 20327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 20427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org StopRecording(); 20527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _shutdownRecThread = true; 20627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _timeEventRec.Set(); // Release rec thread from waiting state 20727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_ptrThreadRec) 20827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 20927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // First, the thread must detach itself from Java VM 21027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _critSect.Leave(); 21127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (kEventSignaled != _recStartStopEvent.Wait(5000)) 21227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 21327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE( 21427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org kTraceError, 21527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org kTraceAudioDevice, 21627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _id, 21727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Recording thread shutdown timed out, cannot " 21827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "terminate thread", 21927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org __FUNCTION__); 22027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // If we close thread anyway, the app will crash 22127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 22227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 22327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recStartStopEvent.Reset(); 22427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _critSect.Enter(); 22527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 22627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Close down rec thread 22727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org ThreadWrapper* tmpThread = _ptrThreadRec; 22827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrThreadRec = NULL; 22927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _critSect.Leave(); 23027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org tmpThread->SetNotAlive(); 23127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Release again, we might have returned to waiting state 23227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _timeEventRec.Set(); 23327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (tmpThread->Stop()) 23427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 23527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org delete tmpThread; 23627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _jniEnvRec = NULL; 23727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 23827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org else 23927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 24027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 24127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " failed to close down the rec audio thread"); 24227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 24327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _critSect.Enter(); 24427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 24527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recThreadIsInitialized = false; 24627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 24727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _micIsInitialized = false; 24827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recordingDeviceIsSpecified = false; 24927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 25027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 25127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org JNIEnv *env; 25227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool isAttached = false; 25327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 25427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 25527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) 25627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 25727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // try to attach the thread and get the env 25827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Attach this thread to JVM 25927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = _javaVM->AttachCurrentThread(&env, NULL); 26027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if ((res < 0) || !env) 26127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 26227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 26327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Could not attach thread to JVM (%d, %p)", 26427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org __FUNCTION__, res, env); 26527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 26627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 26727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org isAttached = true; 26827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 26927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 27027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Make method IDs and buffer pointers unusable 27127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaMidRecAudio = 0; 27227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaDirectRecBuffer = NULL; 27327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 27427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Delete the references to the java buffers, this allows the 27527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // garbage collector to delete them 27627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org env->DeleteGlobalRef(_javaRecBuffer); 27727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaRecBuffer = 0; 27827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 27927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Delete the references to the java object and class, this allows the 28027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // garbage collector to delete them 28127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org env->DeleteGlobalRef(_javaScObj); 28227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaScObj = 0; 28327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaScClass = 0; 28427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 28527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Detach this thread if it was attached 28627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (isAttached) 28727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 28827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->DetachCurrentThread() < 0) 28927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 29027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 29127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Could not detach thread from JVM", __FUNCTION__); 29227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 29327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 29427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 29527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _initialized = false; 29627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 29727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 29827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 29927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 30027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::RecordingDeviceName(uint16_t index, 30127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org char name[kAdmMaxDeviceNameSize], 30227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org char guid[kAdmMaxGuidSize]) { 30327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (0 != index) 30427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 30527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 30627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Device index is out of range [0,0]"); 30727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 30827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 30927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 31027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Return empty string 31127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org memset(name, 0, kAdmMaxDeviceNameSize); 31227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 31327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (guid) 31427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 31527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org memset(guid, 0, kAdmMaxGuidSize); 31627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 31727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 31827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 31927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 32027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 32127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::SetRecordingDevice(uint16_t index) { 32227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_recIsInitialized) 32327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 32427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 32527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Recording already initialized"); 32627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 32727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 32827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 32927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Recording device index will be used for specifying recording 33027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // audio source, allow any value 33127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recAudioSource = index; 33227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recordingDeviceIsSpecified = true; 33327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 33427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 33527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 33627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 33727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::SetRecordingDevice( 33827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org AudioDeviceModule::WindowsDeviceType device) { 33927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 34027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " API call not supported on this platform"); 34127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 34227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 34327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 34427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::RecordingIsAvailable(bool& available) { // NOLINT 34527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org available = false; 34627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 34727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Try to initialize the playout side 34827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int32_t res = InitRecording(); 34927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 35027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Cancel effect of initialization 35127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org StopRecording(); 35227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 35327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (res != -1) 35427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 35527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org available = true; 35627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 35727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 35827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return res; 35927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 36027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 36127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::InitRecording() { 36227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org CriticalSectionScoped lock(&_critSect); 36327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 36427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_initialized) 36527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 36627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 36727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Not initialized"); 36827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 36927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 37027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 37127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_recording) 37227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 37327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 37427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Recording already started"); 37527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 37627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 37727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 37827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_recordingDeviceIsSpecified) 37927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 38027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 38127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Recording device is not specified"); 38227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 38327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 38427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 38527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_recIsInitialized) 38627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 38727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 38827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Recording already initialized"); 38927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 39027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 39127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 39227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Initialize the microphone 39327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (InitMicrophone() == -1) 39427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 39527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 39627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " InitMicrophone() failed"); 39727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 39827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 39927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 40027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org JNIEnv *env; 40127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool isAttached = false; 40227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 40327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 40427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) 40527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 40627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // try to attach the thread and get the env 40727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Attach this thread to JVM 40827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = _javaVM->AttachCurrentThread(&env, NULL); 40927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if ((res < 0) || !env) 41027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 41127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 41227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Could not attach thread to JVM (%d, %p)", res, env); 41327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 41427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 41527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org isAttached = true; 41627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 41727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 41827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the method ID 41927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jmethodID initRecordingID = env->GetMethodID(_javaScClass, "InitRecording", 42027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "(II)I"); 42127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 42227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int samplingFreq = 44100; 42327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_samplingFreqIn != 44) 42427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 42527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org samplingFreq = _samplingFreqIn * 1000; 42627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 42727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 42827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int retVal = -1; 42927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 43027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // call java sc object method 43127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = env->CallIntMethod(_javaScObj, initRecordingID, _recAudioSource, 43227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org samplingFreq); 43327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (res < 0) 43427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 43527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 43627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "InitRecording failed (%d)", res); 43727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 43827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org else 43927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 44027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Set the audio device buffer sampling rate 44127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrAudioBuffer->SetRecordingSampleRate(_samplingFreqIn * 1000); 44227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 44327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // the init rec function returns a fixed delay 44427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _delayRecording = res / _samplingFreqIn; 44527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 44627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recIsInitialized = true; 44727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org retVal = 0; 44827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 44927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 45027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Detach this thread if it was attached 45127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (isAttached) 45227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 45327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->DetachCurrentThread() < 0) 45427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 45527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 45627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Could not detach thread from JVM"); 45727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 45827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 45927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 46027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return retVal; 46127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 46227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 46327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::StartRecording() { 46427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org CriticalSectionScoped lock(&_critSect); 46527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 46627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_recIsInitialized) 46727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 46827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 46927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Recording not initialized"); 47027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 47127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 47227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 47327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_recording) 47427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 47527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 47627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Recording already started"); 47727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 47827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 47927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 48027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 48127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org JNIEnv *env; 48227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool isAttached = false; 48327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 48427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 48527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) 48627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 48727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // try to attach the thread and get the env 48827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Attach this thread to JVM 48927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = _javaVM->AttachCurrentThread(&env, NULL); 49027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if ((res < 0) || !env) 49127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 49227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 49327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Could not attach thread to JVM (%d, %p)", res, env); 49427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 49527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 49627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org isAttached = true; 49727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 49827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 49927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the method ID 50027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jmethodID startRecordingID = env->GetMethodID(_javaScClass, 50127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "StartRecording", "()I"); 50227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 50327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Call java sc object method 50427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = env->CallIntMethod(_javaScObj, startRecordingID); 50527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (res < 0) 50627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 50727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 50827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "StartRecording failed (%d)", res); 50927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 51027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 51127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 51227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recWarning = 0; 51327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recError = 0; 51427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 51527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Signal to recording thread that we want to start 51627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _startRec = true; 51727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _timeEventRec.Set(); // Release thread from waiting state 51827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _critSect.Leave(); 51927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Wait for thread to init 52027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (kEventSignaled != _recStartStopEvent.Wait(5000)) 52127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 52227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 52327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Timeout or error starting"); 52427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 52527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recStartStopEvent.Reset(); 52627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _critSect.Enter(); 52727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 52827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Detach this thread if it was attached 52927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (isAttached) 53027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 53127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->DetachCurrentThread() < 0) 53227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 53327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 53427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Could not detach thread from JVM"); 53527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 53627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 53727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 53827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 53927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 54027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 54127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 54227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::StopRecording() { 54327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org CriticalSectionScoped lock(&_critSect); 54427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 54527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_recIsInitialized) 54627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 54727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 54827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Recording is not initialized"); 54927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 55027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 55127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 55227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // make sure we don't start recording (it's asynchronous), 55327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // assuming that we are under lock 55427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _startRec = false; 55527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 55627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 55727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org JNIEnv *env; 55827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool isAttached = false; 55927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 56027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 56127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) 56227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 56327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // try to attach the thread and get the env 56427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Attach this thread to JVM 56527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = _javaVM->AttachCurrentThread(&env, NULL); 56627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if ((res < 0) || !env) 56727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 56827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 56927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Could not attach thread to JVM (%d, %p)", res, env); 57027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 57127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 57227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org isAttached = true; 57327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 57427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 57527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the method ID 57627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jmethodID stopRecordingID = env->GetMethodID(_javaScClass, "StopRecording", 57727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "()I"); 57827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 57927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Call java sc object method 58027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = env->CallIntMethod(_javaScObj, stopRecordingID); 58127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (res < 0) 58227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 58327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 58427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "StopRecording failed (%d)", res); 58527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 58627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 58727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recIsInitialized = false; 58827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recording = false; 58927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recWarning = 0; 59027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recError = 0; 59127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 59227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Detach this thread if it was attached 59327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (isAttached) 59427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 59527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->DetachCurrentThread() < 0) 59627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 59727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 59827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Could not detach thread from JVM"); 59927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 60027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 60127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 60227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 60327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 60427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 60527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 60627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::SetAGC(bool enable) { 60727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _AGC = enable; 60827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 60927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 61027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 61127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::InitMicrophone() { 61227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org CriticalSectionScoped lock(&_critSect); 61327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 61427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_recording) 61527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 61627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 61727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Recording already started"); 61827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 61927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 62027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 62127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_recordingDeviceIsSpecified) 62227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 62327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 62427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Recording device is not specified"); 62527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 62627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 62727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 62827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Nothing needs to be done here, we use a flag to have consistent 62927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // behavior with other platforms 63027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _micIsInitialized = true; 63127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 63227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 63327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 63427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 63527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::MicrophoneVolumeIsAvailable( 63627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool& available) { // NOLINT 63727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org available = false; // Mic volume not supported on Android 63827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 63927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 64027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 64127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::SetMicrophoneVolume( uint32_t /*volume*/) { 64227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 64327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 64427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " API call not supported on this platform"); 64527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 64627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 64727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 64827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::MicrophoneVolume(uint32_t& volume) const { // NOLINT 64927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 65027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " API call not supported on this platform"); 65127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 65227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 65327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 65427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::MaxMicrophoneVolume( 65527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint32_t& maxVolume) const { // NOLINT 65627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 65727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " API call not supported on this platform"); 65827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 65927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 66027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 66127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::MinMicrophoneVolume( 66227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint32_t& minVolume) const { // NOLINT 66327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 66427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " API call not supported on this platform"); 66527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 66627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 66727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 66827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::MicrophoneVolumeStepSize( 66927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint16_t& stepSize) const { 67027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 67127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " API call not supported on this platform"); 67227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 67327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 67427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 67527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::MicrophoneMuteIsAvailable(bool& available) { // NOLINT 67627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org available = false; // Mic mute not supported on Android 67727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 67827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 67927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 68027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::SetMicrophoneMute(bool enable) { 68127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 68227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " API call not supported on this platform"); 68327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 68427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 68527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 68627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::MicrophoneMute(bool& enabled) const { // NOLINT 68727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 68827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " API call not supported on this platform"); 68927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 69027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 69127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 69227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::MicrophoneBoostIsAvailable(bool& available) { // NOLINT 69327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org available = false; // Mic boost not supported on Android 69427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 69527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 69627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 69727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::SetMicrophoneBoost(bool enable) { 69827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_micIsInitialized) 69927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 70027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 70127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Microphone not initialized"); 70227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 70327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 70427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 70527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (enable) 70627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 70727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 70827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Enabling not available"); 70927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 71027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 71127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 71227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 71327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 71427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 71527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::MicrophoneBoost(bool& enabled) const { // NOLINT 71627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_micIsInitialized) 71727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 71827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 71927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Microphone not initialized"); 72027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 72127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 72227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 72327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org enabled = false; 72427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 72527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 72627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 72727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 72827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::StereoRecordingIsAvailable(bool& available) { // NOLINT 72927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org available = false; // Stereo recording not supported on Android 73027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 73127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 73227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 73327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::SetStereoRecording(bool enable) { 73427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (enable) 73527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 73627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 73727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Enabling not available"); 73827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 73927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 74027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 74127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 74227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 74327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 74427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::StereoRecording(bool& enabled) const { // NOLINT 74527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org enabled = false; 74627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 74727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 74827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 74927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::RecordingDelay(uint16_t& delayMS) const { // NOLINT 75027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org delayMS = _delayRecording; 75127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 75227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 75327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 75427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgbool AudioRecordJni::RecordingWarning() const { 75527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return (_recWarning > 0); 75627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 75727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 75827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgbool AudioRecordJni::RecordingError() const { 75927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return (_recError > 0); 76027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 76127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 76227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgvoid AudioRecordJni::ClearRecordingWarning() { 76327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recWarning = 0; 76427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 76527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 76627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgvoid AudioRecordJni::ClearRecordingError() { 76727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recError = 0; 76827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 76927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 77027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgvoid AudioRecordJni::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) { 77127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org CriticalSectionScoped lock(&_critSect); 77227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrAudioBuffer = audioBuffer; 77327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // inform the AudioBuffer about default settings for this implementation 77427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrAudioBuffer->SetRecordingSampleRate(N_REC_SAMPLES_PER_SEC); 77527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrAudioBuffer->SetRecordingChannels(N_REC_CHANNELS); 77627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 77727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 77827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::SetRecordingSampleRate(const uint32_t samplesPerSec) { 77927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (samplesPerSec > 48000 || samplesPerSec < 8000) 78027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 78127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 78227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Invalid sample rate"); 78327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 78427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 78527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 78627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // set the recording sample rate to use 78727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (samplesPerSec == 44100) 78827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 78927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _samplingFreqIn = 44; 79027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 79127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org else 79227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 79327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _samplingFreqIn = samplesPerSec / 1000; 79427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 79527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 79627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Update the AudioDeviceBuffer 79727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrAudioBuffer->SetRecordingSampleRate(samplesPerSec); 79827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 79927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 80027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 80127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 80227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::InitJavaResources() { 80327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // todo: Check if we already have created the java object 80427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaVM = globalJvm; 80527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaScClass = globalScClass; 80627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 80727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // use the jvm that has been set 80827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_javaVM) 80927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 81027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 81127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Not a valid Java VM pointer", __FUNCTION__); 81227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 81327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 81427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 81527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 81627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org JNIEnv *env; 81727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool isAttached = false; 81827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 81927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 82027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) 82127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 82227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // try to attach the thread and get the env 82327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Attach this thread to JVM 82427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = _javaVM->AttachCurrentThread(&env, NULL); 82527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if ((res < 0) || !env) 82627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 82727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 82827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Could not attach thread to JVM (%d, %p)", 82927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org __FUNCTION__, res, env); 83027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 83127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 83227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org isAttached = true; 83327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 83427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 83527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, 83627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "get method id"); 83727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 83827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the method ID for the void(void) constructor 83927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jmethodID cid = env->GetMethodID(_javaScClass, "<init>", "()V"); 84027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (cid == NULL) 84127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 84227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 84327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not get constructor ID", __FUNCTION__); 84427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; /* exception thrown */ 84527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 84627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 84727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, 84827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "construct object", __FUNCTION__); 84927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 85027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // construct the object 85127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jobject javaScObjLocal = env->NewObject(_javaScClass, cid); 85227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!javaScObjLocal) 85327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 85427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 85527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not create Java sc object", __FUNCTION__); 85627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 85727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 85827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 85927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Create a reference to the object (to tell JNI that we are referencing it 86027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // after this function has returned). 86127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaScObj = env->NewGlobalRef(javaScObjLocal); 86227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_javaScObj) 86327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 86427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 86527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not create Java sc object reference", 86627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org __FUNCTION__); 86727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 86827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 86927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 87027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Delete local object ref, we only use the global ref. 87127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org env->DeleteLocalRef(javaScObjLocal); 87227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 87327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org ////////////////////// 87427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // AUDIO MANAGEMENT 87527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 87627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // This is not mandatory functionality 87727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (globalContext) { 87827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jfieldID context_id = env->GetFieldID(globalScClass, 87927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "_context", 88027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "Landroid/content/Context;"); 88127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!context_id) { 88227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 88327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not get _context id", __FUNCTION__); 88427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 88527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 88627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 88727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org env->SetObjectField(_javaScObj, context_id, globalContext); 88827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jobject javaContext = env->GetObjectField(_javaScObj, context_id); 88927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!javaContext) { 89027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 89127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not set or get _context", __FUNCTION__); 89227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 89327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 89427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 89527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org else { 89627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 89727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: did not set Context - some functionality is not " 89827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "supported", 89927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org __FUNCTION__); 90027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 90127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 90227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Get rec buffer field ID. 90327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jfieldID fidRecBuffer = env->GetFieldID(_javaScClass, "_recBuffer", 90427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "Ljava/nio/ByteBuffer;"); 90527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!fidRecBuffer) 90627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 90727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 90827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not get rec buffer fid", __FUNCTION__); 90927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 91027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 91127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 91227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Get rec buffer object. 91327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jobject javaRecBufferLocal = env->GetObjectField(_javaScObj, fidRecBuffer); 91427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!javaRecBufferLocal) 91527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 91627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 91727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not get rec buffer", __FUNCTION__); 91827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 91927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 92027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 92127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Create a global reference to the object (to tell JNI that we are 92227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // referencing it after this function has returned) 92327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // NOTE: we are referencing it only through the direct buffer (see below). 92427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaRecBuffer = env->NewGlobalRef(javaRecBufferLocal); 92527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_javaRecBuffer) 92627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 92727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 92827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not get rec buffer reference", __FUNCTION__); 92927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 93027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 93127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 93227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Delete local object ref, we only use the global ref. 93327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org env->DeleteLocalRef(javaRecBufferLocal); 93427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 93527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Get direct buffer. 93627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaDirectRecBuffer = env->GetDirectBufferAddress(_javaRecBuffer); 93727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_javaDirectRecBuffer) 93827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 93927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 94027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not get direct rec buffer", __FUNCTION__); 94127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 94227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 94327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 94427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Get the rec audio method ID. 94527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaMidRecAudio = env->GetMethodID(_javaScClass, "RecordAudio", "(I)I"); 94627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_javaMidRecAudio) 94727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 94827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 94927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: could not get rec audio mid", __FUNCTION__); 95027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 95127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 95227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 95327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Detach this thread if it was attached. 95427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (isAttached) 95527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 95627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->DetachCurrentThread() < 0) 95727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 95827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 95927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Could not detach thread from JVM", __FUNCTION__); 96027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 96127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 96227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 96327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 96427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 96527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 96627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 96727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgint32_t AudioRecordJni::InitSampleRate() { 96827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org int samplingFreq = 44100; 96927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = 0; 97027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 97127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 97227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org JNIEnv *env; 97327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool isAttached = false; 97427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 97527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the JNI env for this thread 97627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) 97727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 97827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // try to attach the thread and get the env 97927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Attach this thread to JVM 98027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = _javaVM->AttachCurrentThread(&env, NULL); 98127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if ((res < 0) || !env) 98227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 98327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 98427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Could not attach thread to JVM (%d, %p)", 98527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org __FUNCTION__, res, env); 98627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 98727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 98827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org isAttached = true; 98927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 99027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 99127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_samplingFreqIn > 0) 99227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 99327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // read the configured sampling rate 99427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org samplingFreq = 44100; 99527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_samplingFreqIn != 44) 99627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 99727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org samplingFreq = _samplingFreqIn * 1000; 99827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 99927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, _id, 100027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org " Trying configured recording sampling rate %d", 100127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org samplingFreq); 100227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 100327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 100427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the method ID 100527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jmethodID initRecordingID = env->GetMethodID(_javaScClass, "InitRecording", 100627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "(II)I"); 100727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 100827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org bool keepTrying = true; 100927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org while (keepTrying) 101027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 101127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // call java sc object method 101227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org res = env->CallIntMethod(_javaScObj, initRecordingID, _recAudioSource, 101327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org samplingFreq); 101427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (res < 0) 101527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 101627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org switch (samplingFreq) 101727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 101827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org case 44100: 101927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org samplingFreq = 16000; 102027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org break; 102127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org case 16000: 102227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org samplingFreq = 8000; 102327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org break; 102427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org default: // error 102527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, 102627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org kTraceAudioDevice, _id, 102727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: InitRecording failed (%d)", __FUNCTION__, 102827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org res); 102927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return -1; 103027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 103127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 103227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org else 103327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 103427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org keepTrying = false; 103527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 103627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 103727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 103827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // set the recording sample rate to use 103927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (samplingFreq == 44100) 104027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 104127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _samplingFreqIn = 44; 104227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 104327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org else 104427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 104527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _samplingFreqIn = samplingFreq / 1000; 104627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 104727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 104827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, _id, 104927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "Recording sample rate set to (%d)", _samplingFreqIn); 105027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 105127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // get the method ID 105227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jmethodID stopRecordingID = env->GetMethodID(_javaScClass, "StopRecording", 105327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "()I"); 105427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 105527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Call java sc object method 105627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org res = env->CallIntMethod(_javaScObj, stopRecordingID); 105727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (res < 0) 105827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 105927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 106027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "StopRecording failed (%d)", res); 106127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 106227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 106327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Detach this thread if it was attached 106427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (isAttached) 106527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 106627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->DetachCurrentThread() < 0) 106727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 106827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, 106927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "%s: Could not detach thread from JVM", __FUNCTION__); 107027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 107127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 107227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 107327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return 0; 107427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 107527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 107627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgbool AudioRecordJni::RecThreadFunc(void* pThis) 107727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org{ 107827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return (static_cast<AudioRecordJni*> (pThis)->RecThreadProcess()); 107927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 108027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 108127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.orgbool AudioRecordJni::RecThreadProcess() 108227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org{ 108327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_recThreadIsInitialized) 108427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 108527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Do once when thread is started 108627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 108727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Attach this thread to JVM 108827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint res = _javaVM->AttachCurrentThread(&_jniEnvRec, NULL); 108927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 109027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Get the JNI env for this thread 109127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if ((res < 0) || !_jniEnvRec) 109227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 109327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, 109427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _id, "Could not attach rec thread to JVM (%d, %p)", 109527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org res, _jniEnvRec); 109627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return false; // Close down thread 109727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 109827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 109927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recThreadIsInitialized = true; 110027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 110127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 110227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // just sleep if rec has not started 110327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (!_recording) 110427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 110527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org switch (_timeEventRec.Wait(1000)) 110627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 110727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org case kEventSignaled: 110827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, 110927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _id, "Recording thread event signal"); 111027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _timeEventRec.Reset(); 111127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org break; 111227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org case kEventError: 111327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, 111427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _id, "Recording thread event error"); 111527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return true; 111627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org case kEventTimeout: 111727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, 111827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _id, "Recording thread event timeout"); 111927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return true; 112027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 112127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 112227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 112327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org Lock(); 112427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 112527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_startRec) 112627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 112727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, 112827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "_startRec true, performing initial actions"); 112927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _startRec = false; 113027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recording = true; 113127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recWarning = 0; 113227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recError = 0; 113327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recStartStopEvent.Set(); 113427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 113527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 113627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_recording) 113727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 113827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org uint32_t samplesToRec = _samplingFreqIn * 10; 113927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 114027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Call java sc object method to record data to direct buffer 114127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Will block until data has been recorded (see java sc class), 114227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // therefore we must release the lock 114327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org UnLock(); 114427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org jint recDelayInSamples = _jniEnvRec->CallIntMethod(_javaScObj, 114527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _javaMidRecAudio, 114627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 2 * samplesToRec); 114727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (recDelayInSamples < 0) 114827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 114927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, 115027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "RecordAudio failed"); 115127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recWarning = 1; 115227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 115327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org else 115427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 115527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _delayRecording = recDelayInSamples / _samplingFreqIn; 115627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 115727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org Lock(); 115827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 115927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Check again since recording may have stopped during Java call 116027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_recording) 116127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 116227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, 116327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // "total delay is %d", msPlayDelay + _delayRecording); 116427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 116527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Copy data to our direct buffer (held by java sc object) 116627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // todo: Give _javaDirectRecBuffer directly to VoE? 116727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // todo: Check count <= 480 ? 116827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org memcpy(_recBuffer, _javaDirectRecBuffer, 2 * samplesToRec); 116927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 117027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // store the recorded buffer (no action will be taken if the 117127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // #recorded samples is not a full buffer) 117227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrAudioBuffer->SetRecordedBuffer(_recBuffer, samplesToRec); 117327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 117427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // store vqe delay values 117527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrAudioBuffer->SetVQEData(_delay_provider->PlayoutDelayMs(), 117627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _delayRecording, 0); 117727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 117827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // deliver recorded samples at specified sample rate, mic level 117927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // etc. to the observer using callback 118027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org UnLock(); 118127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _ptrAudioBuffer->DeliverRecordedData(); 118227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org Lock(); 118327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 118427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 118527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } // _recording 118627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 118727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_shutdownRecThread) 118827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 118927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, 119027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "Detaching rec thread from Java VM"); 119127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 119227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // Detach thread from Java VM 119327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org if (_javaVM->DetachCurrentThread() < 0) 119427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 119527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceCritical, kTraceAudioDevice, 119627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _id, "Could not detach recording thread from JVM"); 119727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _shutdownRecThread = false; 119827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // If we say OK (i.e. set event) and close thread anyway, 119927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org // app will crash 120027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 120127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org else 120227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org { 120327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _jniEnvRec = NULL; 120427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _shutdownRecThread = false; 120527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org _recStartStopEvent.Set(); // Signal to Terminate() that we are done 120627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 120727f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, 120827f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org "Sent signal rec"); 120927f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 121027f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org } 121127f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 121227f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org UnLock(); 121327f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org return true; 121427f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} 121527f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org 121627f08414780932bbd4bd0fa2bbf759787b9c2e03henrike@webrtc.org} // namespace webrtc 1217