1*bebae9c0SAndroid Build Coastguard Worker /*
2*bebae9c0SAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*bebae9c0SAndroid Build Coastguard Worker *
4*bebae9c0SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*bebae9c0SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*bebae9c0SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*bebae9c0SAndroid Build Coastguard Worker *
8*bebae9c0SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*bebae9c0SAndroid Build Coastguard Worker *
10*bebae9c0SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*bebae9c0SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*bebae9c0SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*bebae9c0SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*bebae9c0SAndroid Build Coastguard Worker * limitations under the License.
15*bebae9c0SAndroid Build Coastguard Worker */
16*bebae9c0SAndroid Build Coastguard Worker
17*bebae9c0SAndroid Build Coastguard Worker /* Audio Record Test
18*bebae9c0SAndroid Build Coastguard Worker
19*bebae9c0SAndroid Build Coastguard Worker First run the program from shell:
20*bebae9c0SAndroid Build Coastguard Worker % adb shell slesTest_recBuffQueue /sdcard/myrec.wav
21*bebae9c0SAndroid Build Coastguard Worker
22*bebae9c0SAndroid Build Coastguard Worker These use adb on host to retrive the file:
23*bebae9c0SAndroid Build Coastguard Worker % adb pull /sdcard/myrec.wav
24*bebae9c0SAndroid Build Coastguard Worker
25*bebae9c0SAndroid Build Coastguard Worker */
26*bebae9c0SAndroid Build Coastguard Worker
27*bebae9c0SAndroid Build Coastguard Worker
28*bebae9c0SAndroid Build Coastguard Worker #include <stdlib.h>
29*bebae9c0SAndroid Build Coastguard Worker #include <stdio.h>
30*bebae9c0SAndroid Build Coastguard Worker #include <string.h>
31*bebae9c0SAndroid Build Coastguard Worker #include <unistd.h>
32*bebae9c0SAndroid Build Coastguard Worker #include <sys/time.h>
33*bebae9c0SAndroid Build Coastguard Worker #include <fcntl.h>
34*bebae9c0SAndroid Build Coastguard Worker #include <system/audio.h>
35*bebae9c0SAndroid Build Coastguard Worker #include <audio_utils/primitives.h>
36*bebae9c0SAndroid Build Coastguard Worker #include <audio_utils/sndfile.h>
37*bebae9c0SAndroid Build Coastguard Worker
38*bebae9c0SAndroid Build Coastguard Worker #include <SLES/OpenSLES.h>
39*bebae9c0SAndroid Build Coastguard Worker #include <SLES/OpenSLES_Android.h>
40*bebae9c0SAndroid Build Coastguard Worker
41*bebae9c0SAndroid Build Coastguard Worker audio_format_t transferFormat = AUDIO_FORMAT_DEFAULT;
42*bebae9c0SAndroid Build Coastguard Worker uint32_t sampleRate = 48000;
43*bebae9c0SAndroid Build Coastguard Worker int channelCount = 1;
44*bebae9c0SAndroid Build Coastguard Worker bool useIndexChannelMask = false;
45*bebae9c0SAndroid Build Coastguard Worker size_t frameSize;
46*bebae9c0SAndroid Build Coastguard Worker uint32_t performanceMode = SL_ANDROID_PERFORMANCE_LATENCY;
47*bebae9c0SAndroid Build Coastguard Worker bool aec = false;
48*bebae9c0SAndroid Build Coastguard Worker bool agc = false;
49*bebae9c0SAndroid Build Coastguard Worker bool ns = false;
50*bebae9c0SAndroid Build Coastguard Worker
51*bebae9c0SAndroid Build Coastguard Worker /* Preset number to use for recording */
52*bebae9c0SAndroid Build Coastguard Worker SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_NONE;
53*bebae9c0SAndroid Build Coastguard Worker
54*bebae9c0SAndroid Build Coastguard Worker /* Explicitly requesting SL_IID_ANDROIDSIMPLEBUFFERQUEUE and SL_IID_ANDROIDCONFIGURATION
55*bebae9c0SAndroid Build Coastguard Worker * on the AudioRecorder object */
56*bebae9c0SAndroid Build Coastguard Worker #define NUM_EXPLICIT_INTERFACES_FOR_RECORDER 2
57*bebae9c0SAndroid Build Coastguard Worker
58*bebae9c0SAndroid Build Coastguard Worker /* Size of the recording buffer queue */
59*bebae9c0SAndroid Build Coastguard Worker #define NB_BUFFERS_IN_QUEUE 1
60*bebae9c0SAndroid Build Coastguard Worker /* Size of each buffer in the queue */
61*bebae9c0SAndroid Build Coastguard Worker #define BUFFER_SIZE_IN_BYTES 2048
62*bebae9c0SAndroid Build Coastguard Worker
63*bebae9c0SAndroid Build Coastguard Worker /* Local storage for Audio data */
64*bebae9c0SAndroid Build Coastguard Worker int8_t pcmData[NB_BUFFERS_IN_QUEUE * BUFFER_SIZE_IN_BYTES];
65*bebae9c0SAndroid Build Coastguard Worker
66*bebae9c0SAndroid Build Coastguard Worker /* destination for recorded data */
67*bebae9c0SAndroid Build Coastguard Worker SNDFILE *sndfile;
68*bebae9c0SAndroid Build Coastguard Worker
69*bebae9c0SAndroid Build Coastguard Worker //-----------------------------------------------------------------
70*bebae9c0SAndroid Build Coastguard Worker /* Exits the application if an error is encountered */
71*bebae9c0SAndroid Build Coastguard Worker #define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
72*bebae9c0SAndroid Build Coastguard Worker
ExitOnErrorFunc(SLresult result,int line)73*bebae9c0SAndroid Build Coastguard Worker void ExitOnErrorFunc( SLresult result , int line)
74*bebae9c0SAndroid Build Coastguard Worker {
75*bebae9c0SAndroid Build Coastguard Worker if (SL_RESULT_SUCCESS != result) {
76*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line);
77*bebae9c0SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
78*bebae9c0SAndroid Build Coastguard Worker }
79*bebae9c0SAndroid Build Coastguard Worker }
80*bebae9c0SAndroid Build Coastguard Worker
81*bebae9c0SAndroid Build Coastguard Worker //-----------------------------------------------------------------
82*bebae9c0SAndroid Build Coastguard Worker /* Structure for passing information to callback function */
83*bebae9c0SAndroid Build Coastguard Worker typedef struct CallbackCntxt_ {
84*bebae9c0SAndroid Build Coastguard Worker SLPlayItf playItf;
85*bebae9c0SAndroid Build Coastguard Worker SLuint32 size;
86*bebae9c0SAndroid Build Coastguard Worker SLint8* pDataBase; // Base address of local audio data storage
87*bebae9c0SAndroid Build Coastguard Worker SLint8* pData; // Current address of local audio data storage
88*bebae9c0SAndroid Build Coastguard Worker } CallbackCntxt;
89*bebae9c0SAndroid Build Coastguard Worker
90*bebae9c0SAndroid Build Coastguard Worker
91*bebae9c0SAndroid Build Coastguard Worker //-----------------------------------------------------------------
92*bebae9c0SAndroid Build Coastguard Worker /* Callback for recording buffer queue events */
RecCallback(SLRecordItf caller,void * pContext __unused,SLuint32 event)93*bebae9c0SAndroid Build Coastguard Worker void RecCallback(
94*bebae9c0SAndroid Build Coastguard Worker SLRecordItf caller,
95*bebae9c0SAndroid Build Coastguard Worker void *pContext __unused,
96*bebae9c0SAndroid Build Coastguard Worker SLuint32 event)
97*bebae9c0SAndroid Build Coastguard Worker {
98*bebae9c0SAndroid Build Coastguard Worker if (SL_RECORDEVENT_HEADATNEWPOS & event) {
99*bebae9c0SAndroid Build Coastguard Worker SLmillisecond pMsec = 0;
100*bebae9c0SAndroid Build Coastguard Worker (*caller)->GetPosition(caller, &pMsec);
101*bebae9c0SAndroid Build Coastguard Worker printf("SL_RECORDEVENT_HEADATNEWPOS current position=%ums\n", pMsec);
102*bebae9c0SAndroid Build Coastguard Worker }
103*bebae9c0SAndroid Build Coastguard Worker
104*bebae9c0SAndroid Build Coastguard Worker if (SL_RECORDEVENT_HEADATMARKER & event) {
105*bebae9c0SAndroid Build Coastguard Worker SLmillisecond pMsec = 0;
106*bebae9c0SAndroid Build Coastguard Worker (*caller)->GetPosition(caller, &pMsec);
107*bebae9c0SAndroid Build Coastguard Worker printf("SL_RECORDEVENT_HEADATMARKER current position=%ums\n", pMsec);
108*bebae9c0SAndroid Build Coastguard Worker }
109*bebae9c0SAndroid Build Coastguard Worker }
110*bebae9c0SAndroid Build Coastguard Worker
111*bebae9c0SAndroid Build Coastguard Worker //-----------------------------------------------------------------
112*bebae9c0SAndroid Build Coastguard Worker /* Callback for recording buffer queue events */
RecBufferQueueCallback(SLAndroidSimpleBufferQueueItf queueItf,void * pContext)113*bebae9c0SAndroid Build Coastguard Worker void RecBufferQueueCallback(
114*bebae9c0SAndroid Build Coastguard Worker SLAndroidSimpleBufferQueueItf queueItf,
115*bebae9c0SAndroid Build Coastguard Worker void *pContext)
116*bebae9c0SAndroid Build Coastguard Worker {
117*bebae9c0SAndroid Build Coastguard Worker //printf("RecBufferQueueCallback called\n");
118*bebae9c0SAndroid Build Coastguard Worker
119*bebae9c0SAndroid Build Coastguard Worker CallbackCntxt *pCntxt = (CallbackCntxt*)pContext;
120*bebae9c0SAndroid Build Coastguard Worker
121*bebae9c0SAndroid Build Coastguard Worker /* Save the recorded data */
122*bebae9c0SAndroid Build Coastguard Worker sf_count_t frameCount = BUFFER_SIZE_IN_BYTES / frameSize;
123*bebae9c0SAndroid Build Coastguard Worker switch (transferFormat) {
124*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_BIT: {
125*bebae9c0SAndroid Build Coastguard Worker short temp[BUFFER_SIZE_IN_BYTES];
126*bebae9c0SAndroid Build Coastguard Worker memcpy_to_i16_from_u8(temp, (const unsigned char *) pCntxt->pDataBase,
127*bebae9c0SAndroid Build Coastguard Worker BUFFER_SIZE_IN_BYTES);
128*bebae9c0SAndroid Build Coastguard Worker (void) sf_writef_short(sndfile, (const short *) temp, frameCount);
129*bebae9c0SAndroid Build Coastguard Worker } break;
130*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_16_BIT:
131*bebae9c0SAndroid Build Coastguard Worker (void) sf_writef_short(sndfile, (const short *) pCntxt->pDataBase, frameCount);
132*bebae9c0SAndroid Build Coastguard Worker break;
133*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_32_BIT:
134*bebae9c0SAndroid Build Coastguard Worker (void) sf_writef_int(sndfile, (const int *) pCntxt->pDataBase, frameCount);
135*bebae9c0SAndroid Build Coastguard Worker break;
136*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_FLOAT:
137*bebae9c0SAndroid Build Coastguard Worker (void) sf_writef_float(sndfile, (const float *) pCntxt->pDataBase, frameCount);
138*bebae9c0SAndroid Build Coastguard Worker break;
139*bebae9c0SAndroid Build Coastguard Worker default:
140*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "Unsupported transfer format %d\n", transferFormat);
141*bebae9c0SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
142*bebae9c0SAndroid Build Coastguard Worker }
143*bebae9c0SAndroid Build Coastguard Worker
144*bebae9c0SAndroid Build Coastguard Worker /* Increase data pointer by buffer size */
145*bebae9c0SAndroid Build Coastguard Worker pCntxt->pData += BUFFER_SIZE_IN_BYTES;
146*bebae9c0SAndroid Build Coastguard Worker
147*bebae9c0SAndroid Build Coastguard Worker if (pCntxt->pData >= pCntxt->pDataBase + (NB_BUFFERS_IN_QUEUE * BUFFER_SIZE_IN_BYTES)) {
148*bebae9c0SAndroid Build Coastguard Worker pCntxt->pData = pCntxt->pDataBase;
149*bebae9c0SAndroid Build Coastguard Worker }
150*bebae9c0SAndroid Build Coastguard Worker
151*bebae9c0SAndroid Build Coastguard Worker ExitOnError( (*queueItf)->Enqueue(queueItf, pCntxt->pDataBase, BUFFER_SIZE_IN_BYTES) );
152*bebae9c0SAndroid Build Coastguard Worker
153*bebae9c0SAndroid Build Coastguard Worker SLAndroidSimpleBufferQueueState recQueueState;
154*bebae9c0SAndroid Build Coastguard Worker ExitOnError( (*queueItf)->GetState(queueItf, &recQueueState) );
155*bebae9c0SAndroid Build Coastguard Worker
156*bebae9c0SAndroid Build Coastguard Worker /*fprintf(stderr, "\tRecBufferQueueCallback now has pCntxt->pData=%p queue: "
157*bebae9c0SAndroid Build Coastguard Worker "count=%u playIndex=%u\n",
158*bebae9c0SAndroid Build Coastguard Worker pCntxt->pData, recQueueState.count, recQueueState.index);*/
159*bebae9c0SAndroid Build Coastguard Worker //printf("RecBufferQueueCallback returned\n");
160*bebae9c0SAndroid Build Coastguard Worker }
161*bebae9c0SAndroid Build Coastguard Worker
162*bebae9c0SAndroid Build Coastguard Worker //-----------------------------------------------------------------
163*bebae9c0SAndroid Build Coastguard Worker
164*bebae9c0SAndroid Build Coastguard Worker /* Record to an audio path by opening a file descriptor on that path */
TestRecToBuffQueue(SLObjectItf sl,const char * path,SLAint64 durationInSeconds)165*bebae9c0SAndroid Build Coastguard Worker void TestRecToBuffQueue( SLObjectItf sl, const char* path, SLAint64 durationInSeconds)
166*bebae9c0SAndroid Build Coastguard Worker {
167*bebae9c0SAndroid Build Coastguard Worker SF_INFO info;
168*bebae9c0SAndroid Build Coastguard Worker info.frames = 0;
169*bebae9c0SAndroid Build Coastguard Worker info.samplerate = sampleRate;
170*bebae9c0SAndroid Build Coastguard Worker info.channels = channelCount;
171*bebae9c0SAndroid Build Coastguard Worker switch (transferFormat) {
172*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_BIT:
173*bebae9c0SAndroid Build Coastguard Worker info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_U8;
174*bebae9c0SAndroid Build Coastguard Worker break;
175*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_16_BIT:
176*bebae9c0SAndroid Build Coastguard Worker info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
177*bebae9c0SAndroid Build Coastguard Worker break;
178*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_32_BIT:
179*bebae9c0SAndroid Build Coastguard Worker info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_32;
180*bebae9c0SAndroid Build Coastguard Worker break;
181*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_FLOAT:
182*bebae9c0SAndroid Build Coastguard Worker info.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
183*bebae9c0SAndroid Build Coastguard Worker break;
184*bebae9c0SAndroid Build Coastguard Worker default:
185*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "Unsupported transfer format %d\n", transferFormat);
186*bebae9c0SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
187*bebae9c0SAndroid Build Coastguard Worker }
188*bebae9c0SAndroid Build Coastguard Worker sndfile = sf_open(path, SFM_WRITE, &info);
189*bebae9c0SAndroid Build Coastguard Worker if (sndfile == NULL) {
190*bebae9c0SAndroid Build Coastguard Worker ExitOnError(SL_RESULT_RESOURCE_ERROR);
191*bebae9c0SAndroid Build Coastguard Worker }
192*bebae9c0SAndroid Build Coastguard Worker
193*bebae9c0SAndroid Build Coastguard Worker SLresult result;
194*bebae9c0SAndroid Build Coastguard Worker SLEngineItf EngineItf;
195*bebae9c0SAndroid Build Coastguard Worker
196*bebae9c0SAndroid Build Coastguard Worker /* Objects this application uses: one audio recorder */
197*bebae9c0SAndroid Build Coastguard Worker SLObjectItf recorder;
198*bebae9c0SAndroid Build Coastguard Worker
199*bebae9c0SAndroid Build Coastguard Worker /* Interfaces for the audio recorder */
200*bebae9c0SAndroid Build Coastguard Worker SLAndroidSimpleBufferQueueItf recBuffQueueItf;
201*bebae9c0SAndroid Build Coastguard Worker SLRecordItf recordItf;
202*bebae9c0SAndroid Build Coastguard Worker SLAndroidConfigurationItf configItf;
203*bebae9c0SAndroid Build Coastguard Worker
204*bebae9c0SAndroid Build Coastguard Worker /* Source of audio data for the recording */
205*bebae9c0SAndroid Build Coastguard Worker SLDataSource recSource;
206*bebae9c0SAndroid Build Coastguard Worker SLDataLocator_IODevice ioDevice;
207*bebae9c0SAndroid Build Coastguard Worker
208*bebae9c0SAndroid Build Coastguard Worker /* Data sink for recorded audio */
209*bebae9c0SAndroid Build Coastguard Worker SLDataSink recDest;
210*bebae9c0SAndroid Build Coastguard Worker SLDataLocator_AndroidSimpleBufferQueue recBuffQueue;
211*bebae9c0SAndroid Build Coastguard Worker /* As mentioned in the Android extension API documentation this is identical to
212*bebae9c0SAndroid Build Coastguard Worker * OpenSL ES 1.1 SLDataFormat_PCM_EX, and can be used for an instance of SLDataFormat_PCM.
213*bebae9c0SAndroid Build Coastguard Worker */
214*bebae9c0SAndroid Build Coastguard Worker SLAndroidDataFormat_PCM_EX pcm;
215*bebae9c0SAndroid Build Coastguard Worker
216*bebae9c0SAndroid Build Coastguard Worker int numInterfaces = NUM_EXPLICIT_INTERFACES_FOR_RECORDER;
217*bebae9c0SAndroid Build Coastguard Worker if (aec) numInterfaces++;
218*bebae9c0SAndroid Build Coastguard Worker if (agc) numInterfaces++;
219*bebae9c0SAndroid Build Coastguard Worker if (ns) numInterfaces++;
220*bebae9c0SAndroid Build Coastguard Worker
221*bebae9c0SAndroid Build Coastguard Worker SLboolean required[numInterfaces];
222*bebae9c0SAndroid Build Coastguard Worker SLInterfaceID iidArray[numInterfaces];
223*bebae9c0SAndroid Build Coastguard Worker
224*bebae9c0SAndroid Build Coastguard Worker /* Get the SL Engine Interface which is implicit */
225*bebae9c0SAndroid Build Coastguard Worker result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
226*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
227*bebae9c0SAndroid Build Coastguard Worker
228*bebae9c0SAndroid Build Coastguard Worker /* Initialize arrays required[] and iidArray[] */
229*bebae9c0SAndroid Build Coastguard Worker for (int i=0 ; i < numInterfaces ; i++) {
230*bebae9c0SAndroid Build Coastguard Worker required[i] = SL_BOOLEAN_FALSE;
231*bebae9c0SAndroid Build Coastguard Worker iidArray[i] = SL_IID_NULL;
232*bebae9c0SAndroid Build Coastguard Worker }
233*bebae9c0SAndroid Build Coastguard Worker
234*bebae9c0SAndroid Build Coastguard Worker
235*bebae9c0SAndroid Build Coastguard Worker /* ------------------------------------------------------ */
236*bebae9c0SAndroid Build Coastguard Worker /* Configuration of the recorder */
237*bebae9c0SAndroid Build Coastguard Worker
238*bebae9c0SAndroid Build Coastguard Worker /* Request the AndroidSimpleBufferQueue and AndroidConfiguration interfaces */
239*bebae9c0SAndroid Build Coastguard Worker int index = 0;
240*bebae9c0SAndroid Build Coastguard Worker required[index] = SL_BOOLEAN_TRUE;
241*bebae9c0SAndroid Build Coastguard Worker iidArray[index++] = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
242*bebae9c0SAndroid Build Coastguard Worker required[index] = SL_BOOLEAN_TRUE;
243*bebae9c0SAndroid Build Coastguard Worker iidArray[index++] = SL_IID_ANDROIDCONFIGURATION;
244*bebae9c0SAndroid Build Coastguard Worker if (aec) {
245*bebae9c0SAndroid Build Coastguard Worker iidArray[index++] = SL_IID_ANDROIDACOUSTICECHOCANCELLATION;
246*bebae9c0SAndroid Build Coastguard Worker }
247*bebae9c0SAndroid Build Coastguard Worker if (agc) {
248*bebae9c0SAndroid Build Coastguard Worker iidArray[index++] = SL_IID_ANDROIDAUTOMATICGAINCONTROL;
249*bebae9c0SAndroid Build Coastguard Worker }
250*bebae9c0SAndroid Build Coastguard Worker if (ns) {
251*bebae9c0SAndroid Build Coastguard Worker iidArray[index++] = SL_IID_ANDROIDNOISESUPPRESSION;
252*bebae9c0SAndroid Build Coastguard Worker }
253*bebae9c0SAndroid Build Coastguard Worker
254*bebae9c0SAndroid Build Coastguard Worker /* Setup the data source */
255*bebae9c0SAndroid Build Coastguard Worker ioDevice.locatorType = SL_DATALOCATOR_IODEVICE;
256*bebae9c0SAndroid Build Coastguard Worker ioDevice.deviceType = SL_IODEVICE_AUDIOINPUT;
257*bebae9c0SAndroid Build Coastguard Worker ioDevice.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
258*bebae9c0SAndroid Build Coastguard Worker ioDevice.device = NULL;
259*bebae9c0SAndroid Build Coastguard Worker recSource.pLocator = (void *) &ioDevice;
260*bebae9c0SAndroid Build Coastguard Worker recSource.pFormat = NULL;
261*bebae9c0SAndroid Build Coastguard Worker
262*bebae9c0SAndroid Build Coastguard Worker /* Setup the data sink */
263*bebae9c0SAndroid Build Coastguard Worker recBuffQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
264*bebae9c0SAndroid Build Coastguard Worker recBuffQueue.numBuffers = NB_BUFFERS_IN_QUEUE;
265*bebae9c0SAndroid Build Coastguard Worker /* set up the format of the data in the buffer queue */
266*bebae9c0SAndroid Build Coastguard Worker pcm.formatType = transferFormat == AUDIO_FORMAT_PCM_FLOAT ||
267*bebae9c0SAndroid Build Coastguard Worker transferFormat == AUDIO_FORMAT_PCM_8_BIT ?
268*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_DATAFORMAT_PCM_EX : SL_DATAFORMAT_PCM;
269*bebae9c0SAndroid Build Coastguard Worker pcm.numChannels = channelCount;
270*bebae9c0SAndroid Build Coastguard Worker pcm.sampleRate = sampleRate * 1000; // milliHz
271*bebae9c0SAndroid Build Coastguard Worker pcm.representation = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
272*bebae9c0SAndroid Build Coastguard Worker switch (transferFormat) {
273*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_16_BIT:
274*bebae9c0SAndroid Build Coastguard Worker pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
275*bebae9c0SAndroid Build Coastguard Worker pcm.containerSize = 16;
276*bebae9c0SAndroid Build Coastguard Worker break;
277*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_32_BIT:
278*bebae9c0SAndroid Build Coastguard Worker pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32;
279*bebae9c0SAndroid Build Coastguard Worker pcm.containerSize = 32;
280*bebae9c0SAndroid Build Coastguard Worker break;
281*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_BIT:
282*bebae9c0SAndroid Build Coastguard Worker pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_8;
283*bebae9c0SAndroid Build Coastguard Worker pcm.containerSize = 8;
284*bebae9c0SAndroid Build Coastguard Worker pcm.representation = SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT;
285*bebae9c0SAndroid Build Coastguard Worker break;
286*bebae9c0SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_FLOAT:
287*bebae9c0SAndroid Build Coastguard Worker pcm.bitsPerSample = 32;
288*bebae9c0SAndroid Build Coastguard Worker pcm.containerSize = 32;
289*bebae9c0SAndroid Build Coastguard Worker pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
290*bebae9c0SAndroid Build Coastguard Worker break;
291*bebae9c0SAndroid Build Coastguard Worker default:
292*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "Unsupported transfer format %d\n", transferFormat);
293*bebae9c0SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
294*bebae9c0SAndroid Build Coastguard Worker }
295*bebae9c0SAndroid Build Coastguard Worker if (useIndexChannelMask) {
296*bebae9c0SAndroid Build Coastguard Worker pcm.channelMask = (1 << channelCount) - 1;
297*bebae9c0SAndroid Build Coastguard Worker } else {
298*bebae9c0SAndroid Build Coastguard Worker switch (channelCount) {
299*bebae9c0SAndroid Build Coastguard Worker case 1:
300*bebae9c0SAndroid Build Coastguard Worker pcm.channelMask = SL_SPEAKER_FRONT_LEFT;
301*bebae9c0SAndroid Build Coastguard Worker break;
302*bebae9c0SAndroid Build Coastguard Worker case 2:
303*bebae9c0SAndroid Build Coastguard Worker pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
304*bebae9c0SAndroid Build Coastguard Worker break;
305*bebae9c0SAndroid Build Coastguard Worker default:
306*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "Unsupported channel count %d\n", channelCount);
307*bebae9c0SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
308*bebae9c0SAndroid Build Coastguard Worker }
309*bebae9c0SAndroid Build Coastguard Worker }
310*bebae9c0SAndroid Build Coastguard Worker pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
311*bebae9c0SAndroid Build Coastguard Worker
312*bebae9c0SAndroid Build Coastguard Worker recDest.pLocator = (void *) &recBuffQueue;
313*bebae9c0SAndroid Build Coastguard Worker recDest.pFormat = (void * ) &pcm;
314*bebae9c0SAndroid Build Coastguard Worker
315*bebae9c0SAndroid Build Coastguard Worker /* Create the audio recorder */
316*bebae9c0SAndroid Build Coastguard Worker result = (*EngineItf)->CreateAudioRecorder(EngineItf, &recorder, &recSource, &recDest,
317*bebae9c0SAndroid Build Coastguard Worker numInterfaces, iidArray, required);
318*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
319*bebae9c0SAndroid Build Coastguard Worker printf("Recorder created\n");
320*bebae9c0SAndroid Build Coastguard Worker
321*bebae9c0SAndroid Build Coastguard Worker /* Get the Android configuration interface which is explicit */
322*bebae9c0SAndroid Build Coastguard Worker result = (*recorder)->GetInterface(recorder, SL_IID_ANDROIDCONFIGURATION, (void*)&configItf);
323*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
324*bebae9c0SAndroid Build Coastguard Worker
325*bebae9c0SAndroid Build Coastguard Worker /* Use the configuration interface to configure the recorder before it's realized */
326*bebae9c0SAndroid Build Coastguard Worker if (presetValue != SL_ANDROID_RECORDING_PRESET_NONE) {
327*bebae9c0SAndroid Build Coastguard Worker result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_RECORDING_PRESET,
328*bebae9c0SAndroid Build Coastguard Worker &presetValue, sizeof(SLuint32));
329*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
330*bebae9c0SAndroid Build Coastguard Worker printf("Recorder configured with preset %u\n", presetValue);
331*bebae9c0SAndroid Build Coastguard Worker } else {
332*bebae9c0SAndroid Build Coastguard Worker printf("Using default record preset\n");
333*bebae9c0SAndroid Build Coastguard Worker }
334*bebae9c0SAndroid Build Coastguard Worker
335*bebae9c0SAndroid Build Coastguard Worker if (performanceMode != SL_ANDROID_PERFORMANCE_LATENCY) {
336*bebae9c0SAndroid Build Coastguard Worker result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_PERFORMANCE_MODE,
337*bebae9c0SAndroid Build Coastguard Worker &performanceMode, sizeof(SLuint32));
338*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
339*bebae9c0SAndroid Build Coastguard Worker printf("Recorder configured with performance mode %u\n", performanceMode);
340*bebae9c0SAndroid Build Coastguard Worker } else {
341*bebae9c0SAndroid Build Coastguard Worker printf("Using default performance mode\n");
342*bebae9c0SAndroid Build Coastguard Worker }
343*bebae9c0SAndroid Build Coastguard Worker
344*bebae9c0SAndroid Build Coastguard Worker SLuint32 presetRetrieved = SL_ANDROID_RECORDING_PRESET_NONE;
345*bebae9c0SAndroid Build Coastguard Worker SLuint32 presetSize = 2*sizeof(SLuint32); // intentionally too big
346*bebae9c0SAndroid Build Coastguard Worker result = (*configItf)->GetConfiguration(configItf, SL_ANDROID_KEY_RECORDING_PRESET,
347*bebae9c0SAndroid Build Coastguard Worker &presetSize, (void*)&presetRetrieved);
348*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
349*bebae9c0SAndroid Build Coastguard Worker if (presetValue == SL_ANDROID_RECORDING_PRESET_NONE) {
350*bebae9c0SAndroid Build Coastguard Worker printf("The default record preset appears to be %u\n", presetRetrieved);
351*bebae9c0SAndroid Build Coastguard Worker } else if (presetValue != presetRetrieved) {
352*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "Error retrieving recording preset as %u instead of %u\n", presetRetrieved,
353*bebae9c0SAndroid Build Coastguard Worker presetValue);
354*bebae9c0SAndroid Build Coastguard Worker ExitOnError(SL_RESULT_INTERNAL_ERROR);
355*bebae9c0SAndroid Build Coastguard Worker }
356*bebae9c0SAndroid Build Coastguard Worker
357*bebae9c0SAndroid Build Coastguard Worker /* Realize the recorder in synchronous mode. */
358*bebae9c0SAndroid Build Coastguard Worker result = (*recorder)->Realize(recorder, SL_BOOLEAN_FALSE);
359*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
360*bebae9c0SAndroid Build Coastguard Worker printf("Recorder realized\n");
361*bebae9c0SAndroid Build Coastguard Worker
362*bebae9c0SAndroid Build Coastguard Worker /* Check actual performance mode granted*/
363*bebae9c0SAndroid Build Coastguard Worker SLuint32 modeRetrieved = SL_ANDROID_PERFORMANCE_NONE;
364*bebae9c0SAndroid Build Coastguard Worker SLuint32 modeSize = sizeof(SLuint32);
365*bebae9c0SAndroid Build Coastguard Worker result = (*configItf)->GetConfiguration(configItf, SL_ANDROID_KEY_PERFORMANCE_MODE,
366*bebae9c0SAndroid Build Coastguard Worker &modeSize, (void*)&modeRetrieved);
367*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
368*bebae9c0SAndroid Build Coastguard Worker printf("Actual performance mode is %u\n", modeRetrieved);
369*bebae9c0SAndroid Build Coastguard Worker
370*bebae9c0SAndroid Build Coastguard Worker /* Get the record interface which is implicit */
371*bebae9c0SAndroid Build Coastguard Worker result = (*recorder)->GetInterface(recorder, SL_IID_RECORD, (void*)&recordItf);
372*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
373*bebae9c0SAndroid Build Coastguard Worker
374*bebae9c0SAndroid Build Coastguard Worker /* Set up the recorder callback to get events during the recording */
375*bebae9c0SAndroid Build Coastguard Worker result = (*recordItf)->SetMarkerPosition(recordItf, 2000);
376*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
377*bebae9c0SAndroid Build Coastguard Worker result = (*recordItf)->SetPositionUpdatePeriod(recordItf, 500);
378*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
379*bebae9c0SAndroid Build Coastguard Worker result = (*recordItf)->SetCallbackEventsMask(recordItf,
380*bebae9c0SAndroid Build Coastguard Worker SL_RECORDEVENT_HEADATMARKER | SL_RECORDEVENT_HEADATNEWPOS);
381*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
382*bebae9c0SAndroid Build Coastguard Worker result = (*recordItf)->RegisterCallback(recordItf, RecCallback, NULL);
383*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
384*bebae9c0SAndroid Build Coastguard Worker printf("Recorder callback registered\n");
385*bebae9c0SAndroid Build Coastguard Worker
386*bebae9c0SAndroid Build Coastguard Worker /* Enable AEC if requested */
387*bebae9c0SAndroid Build Coastguard Worker if (aec) {
388*bebae9c0SAndroid Build Coastguard Worker SLAndroidAcousticEchoCancellationItf aecItf;
389*bebae9c0SAndroid Build Coastguard Worker result = (*recorder)->GetInterface(
390*bebae9c0SAndroid Build Coastguard Worker recorder, SL_IID_ANDROIDACOUSTICECHOCANCELLATION, (void*)&aecItf);
391*bebae9c0SAndroid Build Coastguard Worker printf("AEC is %savailable\n", SL_RESULT_SUCCESS == result ? "" : "not ");
392*bebae9c0SAndroid Build Coastguard Worker if (SL_RESULT_SUCCESS == result) {
393*bebae9c0SAndroid Build Coastguard Worker result = (*aecItf)->SetEnabled(aecItf, true);
394*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
395*bebae9c0SAndroid Build Coastguard Worker SLboolean enabled;
396*bebae9c0SAndroid Build Coastguard Worker result = (*aecItf)->IsEnabled(aecItf, &enabled);
397*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
398*bebae9c0SAndroid Build Coastguard Worker printf("AEC is %s\n", enabled ? "enabled" : "not enabled");
399*bebae9c0SAndroid Build Coastguard Worker }
400*bebae9c0SAndroid Build Coastguard Worker }
401*bebae9c0SAndroid Build Coastguard Worker
402*bebae9c0SAndroid Build Coastguard Worker /* Enable AGC if requested */
403*bebae9c0SAndroid Build Coastguard Worker if (agc) {
404*bebae9c0SAndroid Build Coastguard Worker SLAndroidAutomaticGainControlItf agcItf;
405*bebae9c0SAndroid Build Coastguard Worker result = (*recorder)->GetInterface(
406*bebae9c0SAndroid Build Coastguard Worker recorder, SL_IID_ANDROIDAUTOMATICGAINCONTROL, (void*)&agcItf);
407*bebae9c0SAndroid Build Coastguard Worker printf("AGC is %savailable\n", SL_RESULT_SUCCESS == result ? "" : "not ");
408*bebae9c0SAndroid Build Coastguard Worker if (SL_RESULT_SUCCESS == result) {
409*bebae9c0SAndroid Build Coastguard Worker result = (*agcItf)->SetEnabled(agcItf, true);
410*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
411*bebae9c0SAndroid Build Coastguard Worker SLboolean enabled;
412*bebae9c0SAndroid Build Coastguard Worker result = (*agcItf)->IsEnabled(agcItf, &enabled);
413*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
414*bebae9c0SAndroid Build Coastguard Worker printf("AGC is %s\n", enabled ? "enabled" : "not enabled");
415*bebae9c0SAndroid Build Coastguard Worker }
416*bebae9c0SAndroid Build Coastguard Worker }
417*bebae9c0SAndroid Build Coastguard Worker
418*bebae9c0SAndroid Build Coastguard Worker /* Enable NS if requested */
419*bebae9c0SAndroid Build Coastguard Worker if (ns) {
420*bebae9c0SAndroid Build Coastguard Worker SLAndroidNoiseSuppressionItf nsItf;
421*bebae9c0SAndroid Build Coastguard Worker result = (*recorder)->GetInterface(
422*bebae9c0SAndroid Build Coastguard Worker recorder, SL_IID_ANDROIDNOISESUPPRESSION, (void*)&nsItf);
423*bebae9c0SAndroid Build Coastguard Worker printf("NS is %savailable\n", SL_RESULT_SUCCESS == result ? "" : "not ");
424*bebae9c0SAndroid Build Coastguard Worker if (SL_RESULT_SUCCESS == result) {
425*bebae9c0SAndroid Build Coastguard Worker result = (*nsItf)->SetEnabled(nsItf, true);
426*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
427*bebae9c0SAndroid Build Coastguard Worker SLboolean enabled;
428*bebae9c0SAndroid Build Coastguard Worker result = (*nsItf)->IsEnabled(nsItf, &enabled);
429*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
430*bebae9c0SAndroid Build Coastguard Worker printf("NS is %s\n", enabled ? "enabled" : "not enabled");
431*bebae9c0SAndroid Build Coastguard Worker }
432*bebae9c0SAndroid Build Coastguard Worker }
433*bebae9c0SAndroid Build Coastguard Worker
434*bebae9c0SAndroid Build Coastguard Worker /* Get the buffer queue interface which was explicitly requested */
435*bebae9c0SAndroid Build Coastguard Worker result = (*recorder)->GetInterface(recorder, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
436*bebae9c0SAndroid Build Coastguard Worker (void*)&recBuffQueueItf);
437*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
438*bebae9c0SAndroid Build Coastguard Worker
439*bebae9c0SAndroid Build Coastguard Worker /* ------------------------------------------------------ */
440*bebae9c0SAndroid Build Coastguard Worker /* Initialize the callback and its context for the recording buffer queue */
441*bebae9c0SAndroid Build Coastguard Worker CallbackCntxt cntxt;
442*bebae9c0SAndroid Build Coastguard Worker cntxt.pDataBase = (int8_t*)&pcmData;
443*bebae9c0SAndroid Build Coastguard Worker cntxt.pData = cntxt.pDataBase;
444*bebae9c0SAndroid Build Coastguard Worker cntxt.size = sizeof(pcmData);
445*bebae9c0SAndroid Build Coastguard Worker result = (*recBuffQueueItf)->RegisterCallback(recBuffQueueItf, RecBufferQueueCallback, &cntxt);
446*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
447*bebae9c0SAndroid Build Coastguard Worker
448*bebae9c0SAndroid Build Coastguard Worker /* Enqueue buffers to map the region of memory allocated to store the recorded data */
449*bebae9c0SAndroid Build Coastguard Worker printf("Enqueueing buffer ");
450*bebae9c0SAndroid Build Coastguard Worker for(int i = 0 ; i < NB_BUFFERS_IN_QUEUE ; i++) {
451*bebae9c0SAndroid Build Coastguard Worker printf("%d ", i);
452*bebae9c0SAndroid Build Coastguard Worker result = (*recBuffQueueItf)->Enqueue(recBuffQueueItf, cntxt.pData, BUFFER_SIZE_IN_BYTES);
453*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
454*bebae9c0SAndroid Build Coastguard Worker cntxt.pData += BUFFER_SIZE_IN_BYTES;
455*bebae9c0SAndroid Build Coastguard Worker }
456*bebae9c0SAndroid Build Coastguard Worker printf("\n");
457*bebae9c0SAndroid Build Coastguard Worker cntxt.pData = cntxt.pDataBase;
458*bebae9c0SAndroid Build Coastguard Worker
459*bebae9c0SAndroid Build Coastguard Worker /* ------------------------------------------------------ */
460*bebae9c0SAndroid Build Coastguard Worker /* Start recording */
461*bebae9c0SAndroid Build Coastguard Worker result = (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_RECORDING);
462*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
463*bebae9c0SAndroid Build Coastguard Worker printf("Starting to record\n");
464*bebae9c0SAndroid Build Coastguard Worker
465*bebae9c0SAndroid Build Coastguard Worker /* Record for at least a second */
466*bebae9c0SAndroid Build Coastguard Worker if (durationInSeconds < 1) {
467*bebae9c0SAndroid Build Coastguard Worker durationInSeconds = 1;
468*bebae9c0SAndroid Build Coastguard Worker }
469*bebae9c0SAndroid Build Coastguard Worker usleep(durationInSeconds * 1000 * 1000);
470*bebae9c0SAndroid Build Coastguard Worker
471*bebae9c0SAndroid Build Coastguard Worker /* ------------------------------------------------------ */
472*bebae9c0SAndroid Build Coastguard Worker /* End of recording */
473*bebae9c0SAndroid Build Coastguard Worker
474*bebae9c0SAndroid Build Coastguard Worker /* Stop recording */
475*bebae9c0SAndroid Build Coastguard Worker result = (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_STOPPED);
476*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
477*bebae9c0SAndroid Build Coastguard Worker printf("Stopped recording\n");
478*bebae9c0SAndroid Build Coastguard Worker
479*bebae9c0SAndroid Build Coastguard Worker /* Destroy the AudioRecorder object */
480*bebae9c0SAndroid Build Coastguard Worker (*recorder)->Destroy(recorder);
481*bebae9c0SAndroid Build Coastguard Worker
482*bebae9c0SAndroid Build Coastguard Worker sf_close(sndfile);
483*bebae9c0SAndroid Build Coastguard Worker }
484*bebae9c0SAndroid Build Coastguard Worker
485*bebae9c0SAndroid Build Coastguard Worker //-----------------------------------------------------------------
main(int argc,char * const argv[])486*bebae9c0SAndroid Build Coastguard Worker int main(int argc, char* const argv[])
487*bebae9c0SAndroid Build Coastguard Worker {
488*bebae9c0SAndroid Build Coastguard Worker int durationInSeconds = 10;
489*bebae9c0SAndroid Build Coastguard Worker SLresult result;
490*bebae9c0SAndroid Build Coastguard Worker SLObjectItf sl;
491*bebae9c0SAndroid Build Coastguard Worker
492*bebae9c0SAndroid Build Coastguard Worker const char *prog = argv[0];
493*bebae9c0SAndroid Build Coastguard Worker printf("OpenSL ES test %s: exercises SLRecordItf and SLAndroidSimpleBufferQueueItf ",
494*bebae9c0SAndroid Build Coastguard Worker prog);
495*bebae9c0SAndroid Build Coastguard Worker printf("on an AudioRecorder object\n");
496*bebae9c0SAndroid Build Coastguard Worker
497*bebae9c0SAndroid Build Coastguard Worker int i;
498*bebae9c0SAndroid Build Coastguard Worker for (i = 1; i < argc; ++i) {
499*bebae9c0SAndroid Build Coastguard Worker const char *arg = argv[i];
500*bebae9c0SAndroid Build Coastguard Worker if (arg[0] != '-') {
501*bebae9c0SAndroid Build Coastguard Worker break;
502*bebae9c0SAndroid Build Coastguard Worker }
503*bebae9c0SAndroid Build Coastguard Worker switch (arg[1]) {
504*bebae9c0SAndroid Build Coastguard Worker case 'c': // channel count
505*bebae9c0SAndroid Build Coastguard Worker channelCount = atoi(&arg[2]);
506*bebae9c0SAndroid Build Coastguard Worker break;
507*bebae9c0SAndroid Build Coastguard Worker case 'd': // duration in seconds
508*bebae9c0SAndroid Build Coastguard Worker durationInSeconds = atoi(&arg[2]);
509*bebae9c0SAndroid Build Coastguard Worker break;
510*bebae9c0SAndroid Build Coastguard Worker case 'f':
511*bebae9c0SAndroid Build Coastguard Worker transferFormat = AUDIO_FORMAT_PCM_FLOAT;
512*bebae9c0SAndroid Build Coastguard Worker break;
513*bebae9c0SAndroid Build Coastguard Worker case 'i':
514*bebae9c0SAndroid Build Coastguard Worker useIndexChannelMask = true;
515*bebae9c0SAndroid Build Coastguard Worker break;
516*bebae9c0SAndroid Build Coastguard Worker case 'p': // preset number
517*bebae9c0SAndroid Build Coastguard Worker presetValue = atoi(&arg[2]);
518*bebae9c0SAndroid Build Coastguard Worker break;
519*bebae9c0SAndroid Build Coastguard Worker case 'r':
520*bebae9c0SAndroid Build Coastguard Worker sampleRate = atoi(&arg[2]);
521*bebae9c0SAndroid Build Coastguard Worker break;
522*bebae9c0SAndroid Build Coastguard Worker case '1':
523*bebae9c0SAndroid Build Coastguard Worker transferFormat = AUDIO_FORMAT_PCM_8_BIT;
524*bebae9c0SAndroid Build Coastguard Worker break;
525*bebae9c0SAndroid Build Coastguard Worker case '2':
526*bebae9c0SAndroid Build Coastguard Worker transferFormat = AUDIO_FORMAT_PCM_16_BIT;
527*bebae9c0SAndroid Build Coastguard Worker break;
528*bebae9c0SAndroid Build Coastguard Worker case '4':
529*bebae9c0SAndroid Build Coastguard Worker transferFormat = AUDIO_FORMAT_PCM_32_BIT;
530*bebae9c0SAndroid Build Coastguard Worker break;
531*bebae9c0SAndroid Build Coastguard Worker case 'm':
532*bebae9c0SAndroid Build Coastguard Worker performanceMode = atoi(&arg[2]);
533*bebae9c0SAndroid Build Coastguard Worker break;
534*bebae9c0SAndroid Build Coastguard Worker case 'x':
535*bebae9c0SAndroid Build Coastguard Worker if (strstr(arg, "e") != NULL) {
536*bebae9c0SAndroid Build Coastguard Worker aec = true;
537*bebae9c0SAndroid Build Coastguard Worker }
538*bebae9c0SAndroid Build Coastguard Worker if (strstr(arg, "a") != NULL) {
539*bebae9c0SAndroid Build Coastguard Worker agc = true;
540*bebae9c0SAndroid Build Coastguard Worker }
541*bebae9c0SAndroid Build Coastguard Worker if (strstr(arg, "n") != NULL) {
542*bebae9c0SAndroid Build Coastguard Worker ns = true;
543*bebae9c0SAndroid Build Coastguard Worker }
544*bebae9c0SAndroid Build Coastguard Worker break;
545*bebae9c0SAndroid Build Coastguard Worker default:
546*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "%s: unknown option %s\n", prog, arg);
547*bebae9c0SAndroid Build Coastguard Worker break;
548*bebae9c0SAndroid Build Coastguard Worker }
549*bebae9c0SAndroid Build Coastguard Worker }
550*bebae9c0SAndroid Build Coastguard Worker
551*bebae9c0SAndroid Build Coastguard Worker if (transferFormat == AUDIO_FORMAT_DEFAULT) {
552*bebae9c0SAndroid Build Coastguard Worker transferFormat = AUDIO_FORMAT_PCM_16_BIT;
553*bebae9c0SAndroid Build Coastguard Worker }
554*bebae9c0SAndroid Build Coastguard Worker frameSize = audio_bytes_per_sample(transferFormat) * channelCount;
555*bebae9c0SAndroid Build Coastguard Worker
556*bebae9c0SAndroid Build Coastguard Worker if (argc-i != 1) {
557*bebae9c0SAndroid Build Coastguard Worker printf("Usage: \t%s [-c#] [-d#] [-i] [-p#] [-r#] [-1/2/4/f] destination_file\n", prog);
558*bebae9c0SAndroid Build Coastguard Worker printf(" -c# channel count, defaults to 1\n");
559*bebae9c0SAndroid Build Coastguard Worker printf(" -d# duration in seconds, default to 10\n");
560*bebae9c0SAndroid Build Coastguard Worker printf(" -i index channel mask, not yet implemented\n");
561*bebae9c0SAndroid Build Coastguard Worker printf(" -p# is the preset value which defaults to SL_ANDROID_RECORDING_PRESET_NONE\n");
562*bebae9c0SAndroid Build Coastguard Worker printf(" possible values are:\n");
563*bebae9c0SAndroid Build Coastguard Worker printf(" -p%d SL_ANDROID_RECORDING_PRESET_NONE\n",
564*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_RECORDING_PRESET_NONE);
565*bebae9c0SAndroid Build Coastguard Worker printf(" -p%d SL_ANDROID_RECORDING_PRESET_GENERIC\n",
566*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_RECORDING_PRESET_GENERIC);
567*bebae9c0SAndroid Build Coastguard Worker printf(" -p%d SL_ANDROID_RECORDING_PRESET_CAMCORDER\n",
568*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_RECORDING_PRESET_CAMCORDER);
569*bebae9c0SAndroid Build Coastguard Worker printf(" -p%d SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION\n",
570*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION);
571*bebae9c0SAndroid Build Coastguard Worker printf(" -p%d SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION\n",
572*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION);
573*bebae9c0SAndroid Build Coastguard Worker printf(" -r# sample rate in Hz, defaults to 48000\n");
574*bebae9c0SAndroid Build Coastguard Worker printf(" -[1/2/4/f] sample format: 8-bit unsigned, 16-bit signed, 32-bit signed, float, "
575*bebae9c0SAndroid Build Coastguard Worker "defaults to 16-bit signed\n");
576*bebae9c0SAndroid Build Coastguard Worker printf(" -m# is the performance mode value which defaults to"
577*bebae9c0SAndroid Build Coastguard Worker " SL_ANDROID_PERFORMANCE_LATENCY\n");
578*bebae9c0SAndroid Build Coastguard Worker printf(" possible values are:\n");
579*bebae9c0SAndroid Build Coastguard Worker printf(" -m%d SL_ANDROID_PERFORMANCE_NONE\n",
580*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_PERFORMANCE_NONE);
581*bebae9c0SAndroid Build Coastguard Worker printf(" -m%d SL_ANDROID_PERFORMANCE_LATENCY\n",
582*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_PERFORMANCE_LATENCY);
583*bebae9c0SAndroid Build Coastguard Worker printf(" -m%d SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS\n",
584*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS);
585*bebae9c0SAndroid Build Coastguard Worker printf(" -m%d SL_ANDROID_PERFORMANCE_POWER_SAVING\n",
586*bebae9c0SAndroid Build Coastguard Worker SL_ANDROID_PERFORMANCE_POWER_SAVING);
587*bebae9c0SAndroid Build Coastguard Worker printf(" -x[e][a][n] for pre processing:\n"
588*bebae9c0SAndroid Build Coastguard Worker " - e: Echo canceler\n"
589*bebae9c0SAndroid Build Coastguard Worker " - a: Automatic Gain Control\n"
590*bebae9c0SAndroid Build Coastguard Worker " - n: Noise Suppression\n");
591*bebae9c0SAndroid Build Coastguard Worker printf("Example: \"%s /sdcard/myrec.wav\" \n", prog);
592*bebae9c0SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
593*bebae9c0SAndroid Build Coastguard Worker }
594*bebae9c0SAndroid Build Coastguard Worker
595*bebae9c0SAndroid Build Coastguard Worker SLEngineOption EngineOption[] = {
596*bebae9c0SAndroid Build Coastguard Worker {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
597*bebae9c0SAndroid Build Coastguard Worker };
598*bebae9c0SAndroid Build Coastguard Worker
599*bebae9c0SAndroid Build Coastguard Worker result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
600*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
601*bebae9c0SAndroid Build Coastguard Worker
602*bebae9c0SAndroid Build Coastguard Worker /* Realizing the SL Engine in synchronous mode. */
603*bebae9c0SAndroid Build Coastguard Worker result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
604*bebae9c0SAndroid Build Coastguard Worker ExitOnError(result);
605*bebae9c0SAndroid Build Coastguard Worker
606*bebae9c0SAndroid Build Coastguard Worker TestRecToBuffQueue(sl, argv[i], durationInSeconds);
607*bebae9c0SAndroid Build Coastguard Worker
608*bebae9c0SAndroid Build Coastguard Worker /* Shutdown OpenSL ES */
609*bebae9c0SAndroid Build Coastguard Worker (*sl)->Destroy(sl);
610*bebae9c0SAndroid Build Coastguard Worker
611*bebae9c0SAndroid Build Coastguard Worker return EXIT_SUCCESS;
612*bebae9c0SAndroid Build Coastguard Worker }
613