/*
|
* Copyright (C) 2018 The Android Open Source Project
|
*
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* you may not use this file except in compliance with the License.
|
* You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing, software
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* See the License for the specific language governing permissions and
|
* limitations under the License.
|
*/
|
|
#include "android_media_MicrophoneInfo.h"
|
#include "android_media_AudioErrors.h"
|
#include "core_jni_helpers.h"
|
|
using namespace android;
|
|
static jclass gArrayListClass;
|
static jmethodID gArrayListCstor;
|
static struct {
|
jmethodID add;
|
} gArrayListMethods;
|
|
static jclass gFloatClass;
|
static jmethodID gFloatCstor;
|
|
static jclass gFloatArrayClass;
|
|
static jclass gIntegerClass;
|
static jmethodID gIntegerCstor;
|
|
static jclass gMicrophoneInfoClass;
|
static jmethodID gMicrophoneInfoCstor;
|
|
static jclass gMicrophoneInfoCoordinateClass;
|
static jmethodID gMicrophoneInfoCoordinateCstor;
|
|
static jclass gPairClass;
|
static jmethodID gPairCstor;
|
|
namespace android {
|
|
jint convertMicrophoneInfoFromNative(JNIEnv *env, jobject *jMicrophoneInfo,
|
const media::MicrophoneInfo *microphoneInfo)
|
{
|
jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
|
jstring jDeviceId = NULL;
|
jstring jAddress = NULL;
|
jobject jGeometricLocation = NULL;
|
jobject jOrientation = NULL;
|
jobject jFrequencyResponses = NULL;
|
jobject jChannelMappings = NULL;
|
|
jDeviceId = env->NewStringUTF(String8(microphoneInfo->getDeviceId()).string());
|
jAddress = env->NewStringUTF(String8(microphoneInfo->getAddress()).string());
|
if (microphoneInfo->getGeometricLocation().size() != 3 ||
|
microphoneInfo->getOrientation().size() != 3) {
|
jStatus = nativeToJavaStatus(BAD_VALUE);
|
goto exit;
|
}
|
jGeometricLocation = env->NewObject(gMicrophoneInfoCoordinateClass,
|
gMicrophoneInfoCoordinateCstor,
|
microphoneInfo->getGeometricLocation()[0],
|
microphoneInfo->getGeometricLocation()[1],
|
microphoneInfo->getGeometricLocation()[2]);
|
jOrientation = env->NewObject(gMicrophoneInfoCoordinateClass,
|
gMicrophoneInfoCoordinateCstor,
|
microphoneInfo->getOrientation()[0],
|
microphoneInfo->getOrientation()[1],
|
microphoneInfo->getOrientation()[2]);
|
// Create a list of Pair for frequency response.
|
if (microphoneInfo->getFrequencyResponses().size() != 2 ||
|
microphoneInfo->getFrequencyResponses()[0].size() !=
|
microphoneInfo->getFrequencyResponses()[1].size()) {
|
jStatus = nativeToJavaStatus(BAD_VALUE);
|
goto exit;
|
}
|
jFrequencyResponses = env->NewObject(gArrayListClass, gArrayListCstor);
|
for (size_t i = 0; i < microphoneInfo->getFrequencyResponses()[0].size(); i++) {
|
jobject jFrequency = env->NewObject(gFloatClass, gFloatCstor,
|
microphoneInfo->getFrequencyResponses()[0][i]);
|
jobject jResponse = env->NewObject(gFloatClass, gFloatCstor,
|
microphoneInfo->getFrequencyResponses()[1][i]);
|
jobject jFrequencyResponse = env->NewObject(gPairClass, gPairCstor, jFrequency, jResponse);
|
env->CallBooleanMethod(jFrequencyResponses, gArrayListMethods.add, jFrequencyResponse);
|
env->DeleteLocalRef(jFrequency);
|
env->DeleteLocalRef(jResponse);
|
env->DeleteLocalRef(jFrequencyResponse);
|
}
|
// Create a list of Pair for channel mapping.
|
if (microphoneInfo->getChannelMapping().size() != AUDIO_CHANNEL_COUNT_MAX) {
|
jStatus = nativeToJavaStatus(BAD_VALUE);
|
goto exit;
|
}
|
jChannelMappings = env->NewObject(gArrayListClass, gArrayListCstor);
|
for (size_t i = 0; i < microphoneInfo->getChannelMapping().size(); i++) {
|
int channelMappingType = microphoneInfo->getChannelMapping()[i];
|
if (channelMappingType != AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) {
|
jobject jChannelIndex = env->NewObject(gIntegerClass, gIntegerCstor, i);
|
jobject jChannelMappingType = env->NewObject(gIntegerClass, gIntegerCstor,
|
channelMappingType);
|
jobject jChannelMapping = env->NewObject(gPairClass, gPairCstor,
|
jChannelIndex, jChannelMappingType);
|
env->CallBooleanMethod(jChannelMappings, gArrayListMethods.add, jChannelMapping);
|
env->DeleteLocalRef(jChannelIndex);
|
env->DeleteLocalRef(jChannelMappingType);
|
env->DeleteLocalRef(jChannelMapping);
|
}
|
}
|
*jMicrophoneInfo = env->NewObject(gMicrophoneInfoClass, gMicrophoneInfoCstor, jDeviceId,
|
microphoneInfo->getType(), jAddress,
|
microphoneInfo->getDeviceLocation(),
|
microphoneInfo->getDeviceGroup(),
|
microphoneInfo->getIndexInTheGroup(),
|
jGeometricLocation, jOrientation,
|
jFrequencyResponses, jChannelMappings,
|
microphoneInfo->getSensitivity(),
|
microphoneInfo->getMaxSpl(),
|
microphoneInfo->getMinSpl(),
|
microphoneInfo->getDirectionality());
|
|
exit:
|
if (jDeviceId != NULL) {
|
env->DeleteLocalRef(jDeviceId);
|
}
|
if (jAddress != NULL) {
|
env->DeleteLocalRef(jAddress);
|
}
|
if (jFrequencyResponses != NULL) {
|
env->DeleteLocalRef(jFrequencyResponses);
|
}
|
if (jChannelMappings != NULL) {
|
env->DeleteLocalRef(jChannelMappings);
|
}
|
if (jGeometricLocation != NULL) {
|
env->DeleteLocalRef(jGeometricLocation);
|
}
|
if (jOrientation != NULL) {
|
env->DeleteLocalRef(jOrientation);
|
}
|
return jStatus;
|
}
|
|
}
|
|
int register_android_media_MicrophoneInfo(JNIEnv *env)
|
{
|
jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
|
gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
|
gArrayListCstor = GetMethodIDOrDie(env, arrayListClass, "<init>", "()V");
|
gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
|
|
jclass floatClass = FindClassOrDie(env, "java/lang/Float");
|
gFloatClass = MakeGlobalRefOrDie(env, floatClass);
|
gFloatCstor = GetMethodIDOrDie(env, floatClass, "<init>", "(F)V");
|
|
jclass floatArrayClass = FindClassOrDie(env, "[F");
|
gFloatArrayClass = MakeGlobalRefOrDie(env, floatArrayClass);
|
|
jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
|
gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
|
gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
|
|
jclass microphoneInfoClass = FindClassOrDie(env, "android/media/MicrophoneInfo");
|
gMicrophoneInfoClass = MakeGlobalRefOrDie(env, microphoneInfoClass);
|
gMicrophoneInfoCstor = GetMethodIDOrDie(env, microphoneInfoClass, "<init>",
|
"(Ljava/lang/String;ILjava/lang/String;IIILandroid/media/MicrophoneInfo$Coordinate3F;Landroid/media/MicrophoneInfo$Coordinate3F;Ljava/util/List;Ljava/util/List;FFFI)V");
|
|
jclass microphoneInfoCoordinateClass = FindClassOrDie(
|
env, "android/media/MicrophoneInfo$Coordinate3F");
|
gMicrophoneInfoCoordinateClass = MakeGlobalRefOrDie(env, microphoneInfoCoordinateClass);
|
gMicrophoneInfoCoordinateCstor = GetMethodIDOrDie(env, microphoneInfoCoordinateClass, "<init>",
|
"(FFF)V");
|
|
jclass pairClass = FindClassOrDie(env, "android/util/Pair");
|
gPairClass = MakeGlobalRefOrDie(env, pairClass);
|
gPairCstor = GetMethodIDOrDie(env, pairClass, "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V");
|
|
return 0;
|
}
|