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 <SLES/OpenSLES.h> 18 #include <SLES/OpenSLES_Android.h> 19 #include <pthread.h> 20 #include <android/log.h> 21 #include <jni.h> 22 #include <stdbool.h> 23 24 #ifndef _Included_org_drrickorang_loopback_sles 25 #define _Included_org_drrickorang_loopback_sles 26 27 //struct audio_utils_fifo; 28 #define SLES_PRINTF(...) __android_log_print(ANDROID_LOG_INFO, "sles_jni", __VA_ARGS__); 29 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 #include <audio_utils/fifo.h> 35 36 typedef struct { 37 int* timeStampsMs; // Array of milliseconds since first callback 38 short* callbackDurations; // Array of milliseconds between callback and previous callback 39 short index; // Current write position 40 struct timespec startTime; // Time of first callback {seconds,nanoseconds} 41 int capacity; // Total number of callback times/lengths that can be recorded 42 bool exceededCapacity; // Set only if late callbacks come after array is full 43 } callbackTimeStamps; 44 45 typedef struct { 46 int* buffer_period; 47 struct timespec previous_time; 48 struct timespec current_time; 49 int buffer_count; 50 int max_buffer_period; 51 52 volatile int32_t captureRank; // Set > 0 when the callback requests a systrace/bug report 53 54 int measurement_count; // number of measurements which were actually recorded 55 int64_t SDM; // sum of squares of deviations from the expected mean 56 int64_t var; // variance in nanoseconds^2 57 } bufferStats; 58 59 //TODO fix this 60 typedef struct { 61 SLuint32 rxBufCount; // -r# 62 SLuint32 txBufCount; // -t# 63 SLuint32 bufSizeInFrames; // -f# 64 SLuint32 channels; // -c# 65 SLuint32 sampleRate; // -s# 66 SLuint32 exitAfterSeconds; // -e# 67 SLuint32 freeBufCount; // calculated 68 SLuint32 bufSizeInBytes; // calculated 69 int injectImpulse; // -i#i 70 size_t totalDiscardedInputFrames; // total number of input frames discarded 71 int ignoreFirstFrames; 72 73 // Storage area for the buffer queues 74 char **rxBuffers; 75 char **txBuffers; 76 char **freeBuffers; 77 78 // Buffer indices 79 SLuint32 rxFront; // oldest recording 80 SLuint32 rxRear; // next to be recorded 81 SLuint32 txFront; // oldest playing 82 SLuint32 txRear; // next to be played 83 SLuint32 freeFront; // oldest free 84 SLuint32 freeRear; // next to be freed 85 86 struct audio_utils_fifo fifo; // jitter buffer between recorder and player callbacks, 87 // to mitigate unpredictable phase difference between these, 88 // or even concurrent callbacks on two CPU cores 89 struct audio_utils_fifo fifo2; // For sending data to java code (to plot it) 90 short *fifo2Buffer; 91 short *fifoBuffer; 92 SLAndroidSimpleBufferQueueItf recorderBufferQueue; 93 SLBufferQueueItf playerBufferQueue; 94 95 //other things that belong here 96 SLObjectItf playerObject; 97 SLObjectItf recorderObject; 98 SLObjectItf outputmixObject; 99 SLObjectItf engineObject; 100 101 bufferStats recorderBufferStats; 102 bufferStats playerBufferStats; 103 104 int testType; 105 double frequency1; 106 double bufferTestPhase1; 107 int count; 108 char* byteBufferPtr; 109 int byteBufferLength; 110 111 short* loopbackTone; 112 113 callbackTimeStamps recorderTimeStamps; 114 callbackTimeStamps playerTimeStamps; 115 short expectedBufferPeriod; 116 } sles_data; 117 118 #define NANOS_PER_SECOND 1000000000 119 #define NANOS_PER_MILLI 1000000 120 #define MILLIS_PER_SECOND 1000 121 122 // how late in ms a callback must be to trigger a systrace/bugreport 123 #define LATE_CALLBACK_CAPTURE_THRESHOLD 4 124 #define LATE_CALLBACK_OUTLIER_THRESHOLD 1 125 #define BUFFER_PERIOD_DISCARD 10 126 #define BUFFER_PERIOD_DISCARD_FULL_DUPLEX_PARTNER 2 127 128 enum { 129 SLES_SUCCESS = 0, 130 SLES_FAIL = 1, 131 RANGE = 1002, 132 TEST_TYPE_LATENCY = 222, 133 TEST_TYPE_BUFFER_PERIOD = 223 134 } SLES_STATUS_ENUM; 135 136 int slesInit(sles_data ** ppSles, int samplingRate, int frameCount, int micSource, 137 int performanceMode, 138 int testType, double frequency1, char* byteBufferPtr, int byteBufferLength, 139 short* loopbackTone, int maxRecordedLateCallbacks, int ignoreFirstFrames); 140 141 //note the double pointer to properly free the memory of the structure 142 int slesDestroy(sles_data ** ppSles); 143 144 145 ///full 146 int slesFull(sles_data *pSles); 147 148 int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount, int micSource, 149 int performanceMode, 150 int testType, double frequency1, char* byteBufferPtr, int byteBufferLength, 151 short* loopbackTone, int maxRecordedLateCallbacks, int ignoreFirstFrames); 152 int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples); 153 int slesDestroyServer(sles_data *pSles); 154 int* slesGetRecorderBufferPeriod(sles_data *pSles); 155 int slesGetRecorderMaxBufferPeriod(sles_data *pSles); 156 int64_t slesGetRecorderVarianceBufferPeriod(sles_data *pSles); 157 int* slesGetPlayerBufferPeriod(sles_data *pSles); 158 int slesGetPlayerMaxBufferPeriod(sles_data *pSles); 159 int64_t slesGetPlayerVarianceBufferPeriod(sles_data *pSles); 160 int slesGetCaptureRank(sles_data *pSles); 161 162 void initBufferStats(bufferStats *stats); 163 void collectBufferPeriod(bufferStats *stats, bufferStats *fdpStats, callbackTimeStamps *timeStamps, 164 short expectedBufferPeriod); 165 bool updateBufferStats(bufferStats *stats, int64_t diff_in_nano, int expectedBufferPeriod); 166 void recordTimeStamp(callbackTimeStamps *timeStamps, 167 int64_t callbackDuration, int64_t timeStamp); 168 169 ssize_t byteBuffer_write(sles_data *pSles, char *buffer, size_t count); 170 171 #ifdef __cplusplus 172 } 173 #endif 174 #endif //_Included_org_drrickorang_loopback_sles 175