• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 // Play an audio file using buffer queue
18 
19 #include <assert.h>
20 #include <math.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25 #include <unistd.h>
26 
27 #include <SLES/OpenSLES.h>
28 #ifdef ANDROID
29 #include "sndfile.h"
30 #else
31 #include <sndfile.h>
32 #endif
33 
34 #define max(a, b) ((a) > (b) ? (a) : (b))
35 #define min(a, b) ((a) < (b) ? (a) : (b))
36 
37 unsigned numBuffers = 2;
38 int framesPerBuffer = 512;
39 SNDFILE *sndfile;
40 SF_INFO sfinfo;
41 unsigned which; // which buffer to use next
42 SLboolean eof;  // whether we have hit EOF on input yet
43 short *buffers;
44 SLuint32 byteOrder; // desired to use for PCM buffers
45 SLuint32 nativeByteOrder;   // of platform
46 SLuint32 bitsPerSample = 16;
47 
48 // swap adjacent bytes; this would normally be in <unistd.h> but is missing here
swab(const void * from,void * to,ssize_t n)49 static void swab(const void *from, void *to, ssize_t n)
50 {
51     // from and to as char pointers
52     const char *from_ch = (const char *) from;
53     char *to_ch = (char *) to;
54     // note that we don't swap the last odd byte
55     while (n >= 2) {
56         to_ch[0] = from_ch[1];
57         to_ch[1] = from_ch[0];
58         to_ch += 2;
59         from_ch += 2;
60         n -= 2;
61     }
62 }
63 
64 // squeeze 16-bit signed PCM samples down to 8-bit unsigned PCM samples by truncation; no dithering
squeeze(const short * from,unsigned char * to,ssize_t n)65 static void squeeze(const short *from, unsigned char *to, ssize_t n)
66 {
67     // note that we don't squeeze the last odd byte
68     while (n >= 2) {
69         *to++ = (*from++ + 32768) >> 8;
70         n -= 2;
71     }
72 }
73 
74 // This callback is called each time a buffer finishes playing
75 
callback(SLBufferQueueItf bufq,void * param)76 static void callback(SLBufferQueueItf bufq, void *param)
77 {
78     assert(NULL == param);
79     if (!eof) {
80         short *buffer = &buffers[framesPerBuffer * sfinfo.channels * which];
81         sf_count_t count;
82         count = sf_readf_short(sndfile, buffer, (sf_count_t) framesPerBuffer);
83         if (0 >= count) {
84             eof = SL_BOOLEAN_TRUE;
85         } else {
86             SLuint32 nbytes = count * sfinfo.channels * sizeof(short);
87             if (byteOrder != nativeByteOrder) {
88                 swab(buffer, buffer, nbytes);
89             }
90             if (bitsPerSample == 8) {
91                 squeeze(buffer, (unsigned char *) buffer, nbytes);
92                 nbytes /= 2;
93             }
94             SLresult result = (*bufq)->Enqueue(bufq, buffer, nbytes);
95             assert(SL_RESULT_SUCCESS == result);
96             if (++which >= numBuffers)
97                 which = 0;
98         }
99     }
100 }
101 
main(int argc,char ** argv)102 int main(int argc, char **argv)
103 {
104     // Determine the native byte order (SL_BYTEORDER_NATIVE not available until 1.1)
105     union {
106         short s;
107         char c[2];
108     } u;
109     u.s = 0x1234;
110     if (u.c[0] == 0x34) {
111         nativeByteOrder = SL_BYTEORDER_LITTLEENDIAN;
112     } else if (u.c[0] == 0x12) {
113         nativeByteOrder = SL_BYTEORDER_BIGENDIAN;
114     } else {
115         fprintf(stderr, "Unable to determine native byte order\n");
116         return EXIT_FAILURE;
117     }
118     byteOrder = nativeByteOrder;
119 
120     SLboolean enableReverb = SL_BOOLEAN_FALSE;
121     SLpermille initialRate = 0;
122     SLpermille finalRate = 0;
123     SLpermille deltaRate = 1;
124     SLmillisecond deltaRateMs = 0;
125 
126     // process command-line options
127     int i;
128     for (i = 1; i < argc; ++i) {
129         char *arg = argv[i];
130         if (arg[0] != '-') {
131             break;
132         }
133         if (!strcmp(arg, "-b")) {
134             byteOrder = SL_BYTEORDER_BIGENDIAN;
135         } else if (!strcmp(arg, "-l")) {
136             byteOrder = SL_BYTEORDER_LITTLEENDIAN;
137         } else if (!strcmp(arg, "-8")) {
138             bitsPerSample = 8;
139         } else if (!strncmp(arg, "-f", 2)) {
140             framesPerBuffer = atoi(&arg[2]);
141         } else if (!strncmp(arg, "-n", 2)) {
142             numBuffers = atoi(&arg[2]);
143         } else if (!strncmp(arg, "-p", 2)) {
144             initialRate = atoi(&arg[2]);
145         } else if (!strncmp(arg, "-P", 2)) {
146             finalRate = atoi(&arg[2]);
147         } else if (!strncmp(arg, "-q", 2)) {
148             deltaRate = atoi(&arg[2]);
149             // deltaRate is a magnitude, so take absolute value
150             if (deltaRate < 0) {
151                 deltaRate = -deltaRate;
152             }
153         } else if (!strncmp(arg, "-Q", 2)) {
154             deltaRateMs = atoi(&arg[2]);
155         } else if (!strcmp(arg, "-r")) {
156             enableReverb = SL_BOOLEAN_TRUE;
157         } else {
158             fprintf(stderr, "option %s ignored\n", arg);
159         }
160     }
161 
162     if (argc - i != 1) {
163         fprintf(stderr, "usage: [-b/l] [-8] [-f#] [-n#] [-p#] [-r] %s filename\n", argv[0]);
164         fprintf(stderr, "    -b  force big-endian byte order (default is native byte order)\n");
165         fprintf(stderr, "    -l  force little-endian byte order (default is native byte order)\n");
166         fprintf(stderr, "    -8  output 8-bits per sample (default is 16-bits per sample)\n");
167         fprintf(stderr, "    -f# frames per buffer (default 512)\n");
168         fprintf(stderr, "    -n# number of buffers (default 2)\n");
169         fprintf(stderr, "    -p# initial playback rate in per mille (default 1000)\n");
170         fprintf(stderr, "    -P# final playback rate in per mille (default same as -p#)\n");
171         fprintf(stderr, "    -q# magnitude of playback rate changes in per mille (default 1)\n");
172         fprintf(stderr, "    -Q# period between playback rate changes in ms (default 50)\n");
173         fprintf(stderr, "    -r  enable reverb (default disabled)\n");
174         return EXIT_FAILURE;
175     }
176 
177     const char *filename = argv[i];
178     //memset(&sfinfo, 0, sizeof(SF_INFO));
179     sfinfo.format = 0;
180     sndfile = sf_open(filename, SFM_READ, &sfinfo);
181     if (NULL == sndfile) {
182         perror(filename);
183         return EXIT_FAILURE;
184     }
185 
186     // verify the file format
187     switch (sfinfo.channels) {
188     case 1:
189     case 2:
190         break;
191     default:
192         fprintf(stderr, "unsupported channel count %d\n", sfinfo.channels);
193         goto close_sndfile;
194     }
195 
196     switch (sfinfo.samplerate) {
197     case  8000:
198     case 11025:
199     case 12000:
200     case 16000:
201     case 22050:
202     case 24000:
203     case 32000:
204     case 44100:
205     case 48000:
206         break;
207     default:
208         fprintf(stderr, "unsupported sample rate %d\n", sfinfo.samplerate);
209         goto close_sndfile;
210     }
211 
212     switch (sfinfo.format & SF_FORMAT_TYPEMASK) {
213     case SF_FORMAT_WAV:
214         break;
215     default:
216         fprintf(stderr, "unsupported format type 0x%x\n", sfinfo.format & SF_FORMAT_TYPEMASK);
217         goto close_sndfile;
218     }
219 
220     switch (sfinfo.format & SF_FORMAT_SUBMASK) {
221     case SF_FORMAT_PCM_16:
222     case SF_FORMAT_PCM_U8:
223     case SF_FORMAT_ULAW:
224     case SF_FORMAT_ALAW:
225     case SF_FORMAT_IMA_ADPCM:
226         break;
227     default:
228         fprintf(stderr, "unsupported sub-format 0x%x\n", sfinfo.format & SF_FORMAT_SUBMASK);
229         goto close_sndfile;
230     }
231 
232     buffers = (short *) malloc(framesPerBuffer * sfinfo.channels * sizeof(short) * numBuffers);
233 
234     // create engine
235     SLresult result;
236     SLObjectItf engineObject;
237     result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
238     assert(SL_RESULT_SUCCESS == result);
239     SLEngineItf engineEngine;
240     result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
241     assert(SL_RESULT_SUCCESS == result);
242     result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
243     assert(SL_RESULT_SUCCESS == result);
244 
245     // create output mix
246     SLObjectItf outputMixObject;
247     SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
248     SLboolean req[1] = {SL_BOOLEAN_TRUE};
249     result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, enableReverb ? 1 : 0,
250             ids, req);
251     assert(SL_RESULT_SUCCESS == result);
252     result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
253     assert(SL_RESULT_SUCCESS == result);
254 
255     // configure environmental reverb on output mix
256     SLEnvironmentalReverbItf mixEnvironmentalReverb = NULL;
257     if (enableReverb) {
258         result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
259                 &mixEnvironmentalReverb);
260         assert(SL_RESULT_SUCCESS == result);
261         SLEnvironmentalReverbSettings settings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;
262         result = (*mixEnvironmentalReverb)->SetEnvironmentalReverbProperties(mixEnvironmentalReverb,
263                 &settings);
264         assert(SL_RESULT_SUCCESS == result);
265     }
266 
267     // configure audio source
268     SLDataLocator_BufferQueue loc_bufq;
269     loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
270     loc_bufq.numBuffers = numBuffers;
271     SLDataFormat_PCM format_pcm;
272     format_pcm.formatType = SL_DATAFORMAT_PCM;
273     format_pcm.numChannels = sfinfo.channels;
274     format_pcm.samplesPerSec = sfinfo.samplerate * 1000;
275     format_pcm.bitsPerSample = bitsPerSample;
276     format_pcm.containerSize = format_pcm.bitsPerSample;
277     format_pcm.channelMask = 1 == format_pcm.numChannels ? SL_SPEAKER_FRONT_CENTER :
278             SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
279     format_pcm.endianness = byteOrder;
280     SLDataSource audioSrc;
281     audioSrc.pLocator = &loc_bufq;
282     audioSrc.pFormat = &format_pcm;
283 
284     // configure audio sink
285     SLDataLocator_OutputMix loc_outmix;
286     loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
287     loc_outmix.outputMix = outputMixObject;
288     SLDataSink audioSnk;
289     audioSnk.pLocator = &loc_outmix;
290     audioSnk.pFormat = NULL;
291 
292     // create audio player
293     SLInterfaceID ids2[3] = {SL_IID_BUFFERQUEUE, SL_IID_PLAYBACKRATE, SL_IID_EFFECTSEND};
294     SLboolean req2[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
295     SLObjectItf playerObject;
296     result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
297             &audioSnk, enableReverb ? 3 : 2, ids2, req2);
298     if (SL_RESULT_SUCCESS != result) {
299         fprintf(stderr, "can't create audio player\n");
300         goto no_player;
301     }
302 
303     // realize the player
304     result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
305     assert(SL_RESULT_SUCCESS == result);
306 
307     // get the effect send interface and enable effect send reverb for this player
308     if (enableReverb) {
309         SLEffectSendItf playerEffectSend;
310         result = (*playerObject)->GetInterface(playerObject, SL_IID_EFFECTSEND, &playerEffectSend);
311         assert(SL_RESULT_SUCCESS == result);
312         result = (*playerEffectSend)->EnableEffectSend(playerEffectSend, mixEnvironmentalReverb,
313                 SL_BOOLEAN_TRUE, (SLmillibel) 0);
314         assert(SL_RESULT_SUCCESS == result);
315     }
316 
317     // get the playback rate interface and configure the rate
318     SLPlaybackRateItf playerPlaybackRate;
319     result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAYBACKRATE, &playerPlaybackRate);
320     assert(SL_RESULT_SUCCESS == result);
321     SLpermille defaultRate;
322     result = (*playerPlaybackRate)->GetRate(playerPlaybackRate, &defaultRate);
323     assert(SL_RESULT_SUCCESS == result);
324     SLuint32 defaultProperties;
325     result = (*playerPlaybackRate)->GetProperties(playerPlaybackRate, &defaultProperties);
326     assert(SL_RESULT_SUCCESS == result);
327     printf("default playback rate %d per mille, properties 0x%x\n", defaultRate, defaultProperties);
328     if (initialRate <= 0) {
329         initialRate = defaultRate;
330     }
331     if (finalRate <= 0) {
332         finalRate = initialRate;
333     }
334     SLpermille currentRate = defaultRate;
335     if (finalRate == initialRate) {
336         deltaRate = 0;
337     } else if (finalRate < initialRate) {
338         deltaRate = -deltaRate;
339     }
340     if (initialRate != defaultRate) {
341         result = (*playerPlaybackRate)->SetRate(playerPlaybackRate, initialRate);
342         if (SL_RESULT_FEATURE_UNSUPPORTED == result) {
343             fprintf(stderr, "initial playback rate %d is unsupported\n", initialRate);
344             deltaRate = 0;
345         } else if (SL_RESULT_PARAMETER_INVALID == result) {
346             fprintf(stderr, "initial playback rate %d is invalid\n", initialRate);
347             deltaRate = 0;
348         } else {
349             assert(SL_RESULT_SUCCESS == result);
350             currentRate = initialRate;
351         }
352     }
353 
354     // get the play interface
355     SLPlayItf playerPlay;
356     result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
357     assert(SL_RESULT_SUCCESS == result);
358 
359     // get the buffer queue interface
360     SLBufferQueueItf playerBufferQueue;
361     result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE,
362             &playerBufferQueue);
363     assert(SL_RESULT_SUCCESS == result);
364 
365     // loop until EOF or no more buffers
366     for (which = 0; which < numBuffers; ++which) {
367         short *buffer = &buffers[framesPerBuffer * sfinfo.channels * which];
368         sf_count_t frames = framesPerBuffer;
369         sf_count_t count;
370         count = sf_readf_short(sndfile, buffer, frames);
371         if (0 >= count) {
372             eof = SL_BOOLEAN_TRUE;
373             break;
374         }
375 
376         // enqueue a buffer
377         SLuint32 nbytes = count * sfinfo.channels * sizeof(short);
378         if (byteOrder != nativeByteOrder) {
379             swab(buffer, buffer, nbytes);
380         }
381         if (bitsPerSample == 8) {
382             squeeze(buffer, (unsigned char *) buffer, nbytes);
383             nbytes /= 2;
384         }
385         result = (*playerBufferQueue)->Enqueue(playerBufferQueue, buffer, nbytes);
386         assert(SL_RESULT_SUCCESS == result);
387     }
388     if (which >= numBuffers) {
389         which = 0;
390     }
391 
392     // register a callback on the buffer queue
393     result = (*playerBufferQueue)->RegisterCallback(playerBufferQueue, callback, NULL);
394     assert(SL_RESULT_SUCCESS == result);
395 
396     // set the player's state to playing
397     result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
398     assert(SL_RESULT_SUCCESS == result);
399 
400     // get the initial time
401     struct timespec prevTs;
402     clock_gettime(CLOCK_MONOTONIC, &prevTs);
403     long elapsedNs = 0;
404     long deltaRateNs = deltaRateMs * 1000000;
405 
406     // wait until the buffer queue is empty
407     SLBufferQueueState bufqstate;
408     for (;;) {
409         result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufqstate);
410         assert(SL_RESULT_SUCCESS == result);
411         if (0 >= bufqstate.count) {
412             break;
413         }
414         if (deltaRate == 0) {
415             sleep(1);
416         } else {
417             struct timespec curTs;
418             clock_gettime(CLOCK_MONOTONIC, &curTs);
419             elapsedNs += (curTs.tv_sec - prevTs.tv_sec) * 1000000000 +
420                     // this term can be negative
421                     (curTs.tv_nsec - prevTs.tv_nsec);
422             prevTs = curTs;
423             if (elapsedNs < deltaRateNs) {
424                 usleep((deltaRateNs - elapsedNs) / 1000);
425                 continue;
426             }
427             elapsedNs -= deltaRateNs;
428             SLpermille nextRate = currentRate + deltaRate;
429             result = (*playerPlaybackRate)->SetRate(playerPlaybackRate, nextRate);
430             if (SL_RESULT_SUCCESS != result) {
431                 fprintf(stderr, "next playback rate %d is unsupported\n", nextRate);
432             } else if (SL_RESULT_PARAMETER_INVALID == result) {
433                 fprintf(stderr, "next playback rate %d is invalid\n", nextRate);
434             } else {
435                 assert(SL_RESULT_SUCCESS == result);
436             }
437             currentRate = nextRate;
438             if (currentRate >= max(initialRate, finalRate)) {
439                 currentRate = max(initialRate, finalRate);
440                 deltaRate = -abs(deltaRate);
441             } else if (currentRate <= min(initialRate, finalRate)) {
442                 currentRate = min(initialRate, finalRate);
443                 deltaRate = abs(deltaRate);
444             }
445         }
446     }
447 
448     // destroy audio player
449     (*playerObject)->Destroy(playerObject);
450 
451 no_player:
452 
453     // destroy output mix
454     (*outputMixObject)->Destroy(outputMixObject);
455 
456     // destroy engine
457     (*engineObject)->Destroy(engineObject);
458 
459 close_sndfile:
460 
461     (void) sf_close(sndfile);
462 
463     return EXIT_SUCCESS;
464 }
465