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