• 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 <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