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 32extern "C" { 33#endif 34#include <audio_utils/fifo.h> 35 36typedef 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 45typedef 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 60typedef 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 128enum { 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 136int 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 142int slesDestroy(sles_data ** ppSles); 143 144 145///full 146int slesFull(sles_data *pSles); 147 148int 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); 152int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples); 153int slesDestroyServer(sles_data *pSles); 154int* slesGetRecorderBufferPeriod(sles_data *pSles); 155int slesGetRecorderMaxBufferPeriod(sles_data *pSles); 156int64_t slesGetRecorderVarianceBufferPeriod(sles_data *pSles); 157int* slesGetPlayerBufferPeriod(sles_data *pSles); 158int slesGetPlayerMaxBufferPeriod(sles_data *pSles); 159int64_t slesGetPlayerVarianceBufferPeriod(sles_data *pSles); 160int slesGetCaptureRank(sles_data *pSles); 161 162void initBufferStats(bufferStats *stats); 163void collectBufferPeriod(bufferStats *stats, bufferStats *fdpStats, callbackTimeStamps *timeStamps, 164 short expectedBufferPeriod); 165bool updateBufferStats(bufferStats *stats, int64_t diff_in_nano, int expectedBufferPeriod); 166void recordTimeStamp(callbackTimeStamps *timeStamps, 167 int64_t callbackDuration, int64_t timeStamp); 168 169ssize_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