Home | History | Annotate | Download | only in jni
      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