• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <android/log.h>
18 #include "sles.h"
19 #include "jni_sles.h"
20 #include <stdio.h>
21 
22 
Java_org_drrickorang_loopback_NativeAudioThread_slesInit(JNIEnv * env,jobject obj __unused,jint samplingRate,jint frameCount,jint micSource,jint performanceMode,jint testType,jdouble frequency1,jobject byteBuffer,jshortArray loopbackTone,jint maxRecordedLateCallbacks,jint ignoreFirstFrames)23 JNIEXPORT jlong JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesInit
24   (JNIEnv *env, jobject obj __unused, jint samplingRate, jint frameCount, jint micSource,
25    jint performanceMode,
26    jint testType, jdouble frequency1, jobject byteBuffer, jshortArray loopbackTone,
27    jint maxRecordedLateCallbacks, jint ignoreFirstFrames) {
28 
29     sles_data * pSles = NULL;
30 
31     char* byteBufferPtr = (*env)->GetDirectBufferAddress(env, byteBuffer);
32     int byteBufferLength = (*env)->GetDirectBufferCapacity(env, byteBuffer);
33 
34     short* loopbackToneArray = (*env)->GetShortArrayElements(env, loopbackTone, 0);
35 
36     if (slesInit(&pSles, samplingRate, frameCount, micSource,
37                  performanceMode,
38                  testType, frequency1, byteBufferPtr, byteBufferLength,
39                  loopbackToneArray, maxRecordedLateCallbacks, ignoreFirstFrames) != SLES_FAIL) {
40         return (long) pSles;
41     }
42 
43     // FIXME This should be stored as a (long) field in the object,
44     // so that incorrect Java code could not synthesize a bad sles pointer.
45     return 0;
46 }
47 
48 
Java_org_drrickorang_loopback_NativeAudioThread_slesProcessNext(JNIEnv * env __unused,jobject obj __unused,jlong sles,jdoubleArray samplesArray,jlong offset)49 JNIEXPORT jint JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesProcessNext
50 (JNIEnv *env __unused, jobject obj __unused, jlong sles, jdoubleArray samplesArray, jlong offset) {
51     sles_data * pSles = (sles_data*) (size_t) sles;
52 
53     long maxSamples = (*env)->GetArrayLength(env, samplesArray);
54     double *pSamples = (*env)->GetDoubleArrayElements(env, samplesArray, 0);
55 
56     long availableSamples = maxSamples-offset;
57     double *pCurrentSample = pSamples+offset;
58 
59     SLES_PRINTF("jni slesProcessNext pSles:%p, currentSample %p, availableSamples %ld ",
60                 pSles, pCurrentSample, availableSamples);
61 
62     int samplesRead = slesProcessNext(pSles, pCurrentSample, availableSamples);
63     return samplesRead;
64 }
65 
66 
Java_org_drrickorang_loopback_NativeAudioThread_slesDestroy(JNIEnv * env __unused,jobject obj __unused,jlong sles)67 JNIEXPORT jint JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesDestroy
68   (JNIEnv *env __unused, jobject obj __unused, jlong sles) {
69     sles_data * pSles = (sles_data*) (size_t) sles;
70     int status = slesDestroy(&pSles);
71     return status;
72 }
73 
74 
75 JNIEXPORT jintArray JNICALL
Java_org_drrickorang_loopback_NativeAudioThread_slesGetRecorderBufferPeriod(JNIEnv * env,jobject obj __unused,jlong sles)76         Java_org_drrickorang_loopback_NativeAudioThread_slesGetRecorderBufferPeriod
77   (JNIEnv *env, jobject obj __unused, jlong sles) {
78     sles_data * pSles = (sles_data*) (size_t) sles;
79     int* recorderBufferPeriod = slesGetRecorderBufferPeriod(pSles);
80 
81     // get the length = RANGE
82     jintArray result = (*env)->NewIntArray(env, RANGE);
83     (*env)->SetIntArrayRegion(env, result, 0, RANGE, recorderBufferPeriod);
84 
85     return result;
86 }
87 
88 
89 JNIEXPORT jint JNICALL
Java_org_drrickorang_loopback_NativeAudioThread_slesGetRecorderMaxBufferPeriod(JNIEnv * env __unused,jobject obj __unused,jlong sles)90         Java_org_drrickorang_loopback_NativeAudioThread_slesGetRecorderMaxBufferPeriod
91   (JNIEnv *env __unused, jobject obj __unused, jlong sles) {
92     sles_data * pSles = (sles_data*) (size_t) sles;
93     int recorderMaxBufferPeriod = slesGetRecorderMaxBufferPeriod(pSles);
94 
95     return recorderMaxBufferPeriod;
96 }
97 
98 
99 JNIEXPORT jdouble JNICALL
Java_org_drrickorang_loopback_NativeAudioThread_slesGetRecorderVarianceBufferPeriod(JNIEnv * env __unused,jobject obj __unused,jlong sles)100         Java_org_drrickorang_loopback_NativeAudioThread_slesGetRecorderVarianceBufferPeriod
101         (JNIEnv *env __unused, jobject obj __unused, jlong sles) {
102     sles_data *pSles = (sles_data *) (size_t) sles;
103     int64_t result = slesGetRecorderVarianceBufferPeriod(pSles);
104     // variance has units ns^2 so we have to square the conversion factor
105     double scaled = (double) result / ((double) NANOS_PER_MILLI * (double) NANOS_PER_MILLI);
106     return scaled;
107 }
108 
109 
110 JNIEXPORT jintArray
Java_org_drrickorang_loopback_NativeAudioThread_slesGetPlayerBufferPeriod(JNIEnv * env __unused,jobject obj __unused,jlong sles)111 JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesGetPlayerBufferPeriod
112   (JNIEnv *env __unused, jobject obj __unused, jlong sles) {
113     sles_data * pSles = (sles_data*) (size_t) sles;
114     int* playerBufferPeriod = slesGetPlayerBufferPeriod(pSles);
115 
116     jintArray result = (*env)->NewIntArray(env, RANGE);
117     (*env)->SetIntArrayRegion(env, result, 0, RANGE, playerBufferPeriod);
118 
119     return result;
120 }
121 
122 
123 JNIEXPORT jint JNICALL
Java_org_drrickorang_loopback_NativeAudioThread_slesGetPlayerMaxBufferPeriod(JNIEnv * env __unused,jobject obj __unused,jlong sles)124         Java_org_drrickorang_loopback_NativeAudioThread_slesGetPlayerMaxBufferPeriod
125   (JNIEnv *env __unused, jobject obj __unused, jlong sles) {
126     sles_data * pSles = (sles_data*) (size_t) sles;
127     int playerMaxBufferPeriod = slesGetPlayerMaxBufferPeriod(pSles);
128 
129     return playerMaxBufferPeriod;
130 }
131 
132 
133 JNIEXPORT jdouble JNICALL
Java_org_drrickorang_loopback_NativeAudioThread_slesGetPlayerVarianceBufferPeriod(JNIEnv * env __unused,jobject obj __unused,jlong sles)134 Java_org_drrickorang_loopback_NativeAudioThread_slesGetPlayerVarianceBufferPeriod
135         (JNIEnv *env __unused, jobject obj __unused, jlong sles) {
136     sles_data *pSles = (sles_data *) (size_t) sles;
137     int64_t result = slesGetPlayerVarianceBufferPeriod(pSles);
138     // variance has units ns^2 so we have to square the conversion factor
139     double scaled = (double) result / ((double) NANOS_PER_MILLI * (double) NANOS_PER_MILLI);
140     return scaled;
141 }
142 
143 
getCallbackTimes(JNIEnv * env,callbackTimeStamps * callbacks,short expectedBufferPeriod)144 jobject getCallbackTimes(JNIEnv *env, callbackTimeStamps *callbacks, short expectedBufferPeriod){
145     jintArray timeStamps = (*env)->NewIntArray(env, callbacks->index);
146     (*env)->SetIntArrayRegion(env, timeStamps, 0, callbacks->index, callbacks->timeStampsMs);
147 
148     jshortArray callbackLengths = (*env)->NewShortArray(env, callbacks->index);
149     (*env)->SetShortArrayRegion(env, callbackLengths, 0, callbacks->index,
150                                 callbacks->callbackDurations);
151 
152     jclass cls = (*env)->FindClass(env, "org/drrickorang/loopback/BufferCallbackTimes");
153     jmethodID methodID = (*env)->GetMethodID(env, cls, "<init>", "([I[SZS)V");
154     jobject callbackTimes=(*env)->NewObject(env,cls, methodID, timeStamps, callbackLengths,
155                                             callbacks->exceededCapacity, expectedBufferPeriod);
156     return callbackTimes;
157 }
158 
159 JNIEXPORT jobject
Java_org_drrickorang_loopback_NativeAudioThread_slesGetPlayerCallbackTimeStamps(JNIEnv * env,jobject obj __unused,jlong sles)160 JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesGetPlayerCallbackTimeStamps
161         (JNIEnv *env, jobject obj __unused, jlong sles) {
162     sles_data * pSles = (sles_data*) (size_t) sles;
163     return getCallbackTimes(env, &(pSles->playerTimeStamps), pSles->expectedBufferPeriod);
164 }
165 
166 JNIEXPORT jobject
Java_org_drrickorang_loopback_NativeAudioThread_slesGetRecorderCallbackTimeStamps(JNIEnv * env,jobject obj __unused,jlong sles)167 JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesGetRecorderCallbackTimeStamps
168         (JNIEnv *env, jobject obj __unused, jlong sles) {
169     sles_data * pSles = (sles_data*) (size_t) sles;
170     return getCallbackTimes(env, &(pSles->recorderTimeStamps), pSles->expectedBufferPeriod);
171 }
172 
173 JNIEXPORT jint
Java_org_drrickorang_loopback_NativeAudioThread_slesGetCaptureRank(JNIEnv * env __unused,jobject obj __unused,jlong sles)174 JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesGetCaptureRank
175         (JNIEnv *env __unused, jobject obj __unused, jlong sles) {
176     sles_data * pSles = (sles_data*) (size_t) sles;
177     return slesGetCaptureRank(pSles);
178 }
179