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 // Test various buffer queue configurations
18 
19 #include <assert.h>
20 #include <math.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 
25 #include <SLES/OpenSLES.h>
26 
27 typedef struct {
28     SLuint8 numChannels;
29     SLuint32 milliHz;
30     SLuint8 bitsPerSample;
31 } PCM;
32 
33 PCM formats[] = {
34     {1, SL_SAMPLINGRATE_8,      8},
35     {2, SL_SAMPLINGRATE_8,      8},
36     {1, SL_SAMPLINGRATE_8,      16},
37     {2, SL_SAMPLINGRATE_8,      16},
38     {1, SL_SAMPLINGRATE_11_025, 8},
39     {2, SL_SAMPLINGRATE_11_025, 8},
40     {1, SL_SAMPLINGRATE_11_025, 16},
41     {2, SL_SAMPLINGRATE_11_025, 16},
42     {1, SL_SAMPLINGRATE_12,     8},
43     {2, SL_SAMPLINGRATE_12,     8},
44     {1, SL_SAMPLINGRATE_12,     16},
45     {2, SL_SAMPLINGRATE_12,     16},
46     {1, SL_SAMPLINGRATE_16,     8},
47     {2, SL_SAMPLINGRATE_16,     8},
48     {1, SL_SAMPLINGRATE_16,     16},
49     {2, SL_SAMPLINGRATE_16,     16},
50     {1, SL_SAMPLINGRATE_22_05,  8},
51     {2, SL_SAMPLINGRATE_22_05,  8},
52     {1, SL_SAMPLINGRATE_22_05,  16},
53     {2, SL_SAMPLINGRATE_22_05,  16},
54     {1, SL_SAMPLINGRATE_24,     8},
55     {2, SL_SAMPLINGRATE_24,     8},
56     {1, SL_SAMPLINGRATE_24,     16},
57     {2, SL_SAMPLINGRATE_24,     16},
58     {1, SL_SAMPLINGRATE_32,     8},
59     {2, SL_SAMPLINGRATE_32,     8},
60     {1, SL_SAMPLINGRATE_32,     16},
61     {2, SL_SAMPLINGRATE_32,     16},
62     {1, SL_SAMPLINGRATE_44_1,   8},
63     {2, SL_SAMPLINGRATE_44_1,   8},
64     {1, SL_SAMPLINGRATE_44_1,   16},
65     {2, SL_SAMPLINGRATE_44_1,   16},
66     {1, SL_SAMPLINGRATE_48,     8},
67     {2, SL_SAMPLINGRATE_48,     8},
68     {1, SL_SAMPLINGRATE_48,     16},
69     {2, SL_SAMPLINGRATE_48,     16},
70     {0, 0,                      0}
71 };
72 
main(int argc __unused,char ** argv __unused)73 int main(int argc __unused, char **argv __unused)
74 {
75     SLresult result;
76     SLObjectItf engineObject;
77 
78     // create engine
79     result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
80     assert(SL_RESULT_SUCCESS == result);
81     SLEngineItf engineEngine;
82     result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
83     assert(SL_RESULT_SUCCESS == result);
84     result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
85     assert(SL_RESULT_SUCCESS == result);
86 
87     // create output mix
88     SLObjectItf outputMixObject;
89     result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
90     assert(SL_RESULT_SUCCESS == result);
91     result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
92     assert(SL_RESULT_SUCCESS == result);
93 
94     // loop over all formats
95     PCM *format;
96     float hzLeft = 440.0;   // A440 (Concert A)
97     float hzRight = 440.0;
98     for (format = formats; format->numChannels; ++format) {
99 
100         printf("Channels: %d, sample rate: %u, bits: %u\n", format->numChannels,
101                 format->milliHz / 1000, format->bitsPerSample);
102 
103         // configure audio source
104         SLDataLocator_BufferQueue loc_bufq;
105         loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
106         loc_bufq.numBuffers = 1;
107         SLDataFormat_PCM format_pcm;
108         format_pcm.formatType = SL_DATAFORMAT_PCM;
109         format_pcm.numChannels = format->numChannels;
110         format_pcm.samplesPerSec = format->milliHz;
111         format_pcm.bitsPerSample = format->bitsPerSample;
112         format_pcm.containerSize = format->bitsPerSample;
113         format_pcm.channelMask = 0;
114         format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
115         SLDataSource audioSrc;
116         audioSrc.pLocator = &loc_bufq;
117         audioSrc.pFormat = &format_pcm;
118 
119         // configure audio sink
120         SLDataLocator_OutputMix loc_outmix;
121         loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
122         loc_outmix.outputMix = outputMixObject;
123         SLDataSink audioSnk;
124         audioSnk.pLocator = &loc_outmix;
125         audioSnk.pFormat = NULL;
126 
127         // create audio player
128         SLuint32 numInterfaces = 1;
129         SLInterfaceID ids[1];
130         SLboolean req[1];
131         ids[0] = SL_IID_BUFFERQUEUE;
132         req[0] = SL_BOOLEAN_TRUE;
133         SLObjectItf playerObject;
134         result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
135                 &audioSnk, numInterfaces, ids, req);
136         if (SL_RESULT_SUCCESS != result) {
137             printf("failed %u\n", result);
138             continue;
139         }
140 
141         // realize the player
142         result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
143         assert(SL_RESULT_SUCCESS == result);
144 
145         // generate a sine wave buffer, ascending in half-steps for each format
146 #define N (44100*4)
147         static unsigned char buffer[N];
148         unsigned i;
149         for (i = 0; i < N; ) {
150             float seconds = (((i * 8) / (format->bitsPerSample * format->numChannels)) * 1000.0) /
151                     format->milliHz;
152             short sampleLeft = sin(seconds * M_PI_2 * hzLeft) * 32767.0;
153             short sampleRight = sin(seconds * M_PI_2 * hzRight) * 32767.0;
154             if (2 == format->numChannels) {
155                 if (8 == format->bitsPerSample) {
156                     buffer[i++] = (sampleLeft + 32768) >> 8;
157                     buffer[i++] = (sampleRight + 32768) >> 8;
158                 } else {
159                     assert(16 == format->bitsPerSample);
160                     buffer[i++] = sampleLeft & 0xFF;
161                     buffer[i++] = sampleLeft >> 8;
162                     buffer[i++] = sampleRight & 0xFF;
163                     buffer[i++] = sampleRight >> 8;
164                 }
165             } else {
166                 assert(1 == format->numChannels);
167                 // cast to int and divide by 2 are needed to prevent overflow
168                 short sampleMono = ((int) sampleLeft + (int) sampleRight) / 2;
169                 if (8 == format->bitsPerSample) {
170                     buffer[i++] = (sampleMono + 32768) >> 8;
171                 } else {
172                     assert(16 == format->bitsPerSample);
173                     buffer[i++] = sampleMono & 0xFF;
174                     buffer[i++] = sampleMono >> 8;
175                 }
176             }
177             if (seconds >= 1.0f)
178                 break;
179         }
180 
181         // get the buffer queue interface and enqueue a buffer
182         SLBufferQueueItf playerBufferQueue;
183         result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE,
184                 &playerBufferQueue);
185         assert(SL_RESULT_SUCCESS == result);
186         result = (*playerBufferQueue)->Enqueue(playerBufferQueue, buffer, i);
187         assert(SL_RESULT_SUCCESS == result);
188 
189         // get the play interface
190         SLPlayItf playerPlay;
191         result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
192         assert(SL_RESULT_SUCCESS == result);
193 
194         // set the player's state to playing
195         result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
196         assert(SL_RESULT_SUCCESS == result);
197 
198         // wait for the buffer to be played
199         for (;;) {
200             SLBufferQueueState state;
201             result = (*playerBufferQueue)->GetState(playerBufferQueue, &state);
202             assert(SL_RESULT_SUCCESS == result);
203             if (state.count == 0)
204                 break;
205             usleep(20000);
206         }
207 
208         // destroy audio player
209         (*playerObject)->Destroy(playerObject);
210 
211         //usleep(1000000);
212         hzLeft *= 1.05946309; // twelfth root of 2
213         hzRight /= 1.05946309;
214     }
215 
216     // destroy output mix
217     (*outputMixObject)->Destroy(outputMixObject);
218 
219     // destroy engine
220     (*engineObject)->Destroy(engineObject);
221 
222     return EXIT_SUCCESS;
223 }
224