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