srcsink.c revision c6853892c94800e72c0bd676d5d2136d48cea76e
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 combinations of data sources and sinks
18
19#include <assert.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <SLES/OpenSLES.h>
23
24int main(int argc, char **argv)
25{
26    SLresult result;
27    SLObjectItf engineObject;
28
29    // create engine
30    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
31    assert(SL_RESULT_SUCCESS == result);
32    SLEngineItf engineEngine;
33    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
34    assert(SL_RESULT_SUCCESS == result);
35    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
36    assert(SL_RESULT_SUCCESS == result);
37
38    // configure a typical audio source of 44.1 kHz stereo 16-bit little endian
39    SLDataLocator_BufferQueue loc_bufq;
40    loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
41    loc_bufq.numBuffers = 1;
42    SLDataFormat_PCM format_pcm;
43    format_pcm.formatType = SL_DATAFORMAT_PCM;
44    format_pcm.numChannels = 2;
45    format_pcm.samplesPerSec = SL_SAMPLINGRATE_44_1;
46    format_pcm.bitsPerSample = 16;
47    format_pcm.containerSize = 16;
48    format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
49    format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
50    SLDataSource audioSrc;
51    audioSrc.pLocator = &loc_bufq;
52    audioSrc.pFormat = &format_pcm;
53
54    // configure audio sink
55    SLDataLocator_OutputMix loc_outmix;
56    loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
57    loc_outmix.outputMix = NULL;
58    SLDataSink audioSnk;
59    audioSnk.pLocator = &loc_outmix;
60    audioSnk.pFormat = NULL;
61
62    // create audio player using a NULL output mix
63    SLInterfaceID ids[1] = {SL_IID_BUFFERQUEUE};
64    SLboolean req[1] = {SL_BOOLEAN_TRUE};
65    SLObjectItf playerObject;
66    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
67            &audioSnk, 1, ids, req);
68    assert(SL_RESULT_PARAMETER_INVALID == result);
69    assert(NULL == playerObject);
70
71    // create audio player using an engine as the output mix
72    loc_outmix.outputMix = engineObject;
73    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
74            &audioSnk, 1, ids, req);
75    assert(SL_RESULT_PARAMETER_INVALID == result);
76    assert(NULL == playerObject);
77
78    // create output mix but don't realize it yet
79    SLObjectItf outputMixObject;
80    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
81    assert(SL_RESULT_SUCCESS == result);
82
83    // create audio player using the unrealized output mix
84    loc_outmix.outputMix = outputMixObject;
85    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
86            &audioSnk, 1, ids, req);
87    assert(SL_RESULT_PRECONDITIONS_VIOLATED == result);
88    assert(NULL == playerObject);
89
90    // now realize the output mix
91    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
92    assert(SL_RESULT_SUCCESS == result);
93
94    // create audio player using the realized output mix
95    // and a bogus data format for the sink (ignored per spec)
96    audioSnk.pFormat = (void *) 0xDEADBEEF;
97    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
98            &audioSnk, 1, ids, req);
99    assert(SL_RESULT_SUCCESS == result);
100    assert(NULL != playerObject);
101    audioSnk.pFormat = NULL;
102
103    // destroy player
104    (*playerObject)->Destroy(playerObject);
105
106    // now try to create audio player using various unusual parameters
107
108    // number of channels
109    format_pcm.numChannels = 0;
110    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
111            &audioSnk, 1, ids, req);
112    assert(SL_RESULT_PARAMETER_INVALID == result);
113    assert(NULL == playerObject);
114    format_pcm.numChannels = 3;
115    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
116            &audioSnk, 1, ids, req);
117    assert(SL_RESULT_CONTENT_UNSUPPORTED == result);
118    assert(NULL == playerObject);
119    format_pcm.numChannels = 2;
120
121    // sample rate
122    format_pcm.samplesPerSec = 0;
123    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
124            &audioSnk, 1, ids, req);
125    assert(SL_RESULT_PARAMETER_INVALID == result);
126    assert(NULL == playerObject);
127    format_pcm.samplesPerSec = 1000;
128    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
129            &audioSnk, 1, ids, req);
130    assert(SL_RESULT_CONTENT_UNSUPPORTED == result);
131    assert(NULL == playerObject);
132    format_pcm.samplesPerSec = SL_SAMPLINGRATE_44_1;
133
134    // bits per sample
135    format_pcm.bitsPerSample = 17;
136    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
137            &audioSnk, 1, ids, req);
138    assert(SL_RESULT_PARAMETER_INVALID == result);
139    assert(NULL == playerObject);
140    format_pcm.bitsPerSample = 24;
141    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
142            &audioSnk, 1, ids, req);
143    assert(SL_RESULT_CONTENT_UNSUPPORTED == result);
144    assert(NULL == playerObject);
145    format_pcm.bitsPerSample = 16;
146
147    // container size
148    format_pcm.containerSize = 8;
149    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
150            &audioSnk, 1, ids, req);
151    assert(SL_RESULT_PARAMETER_INVALID == result);
152    assert(NULL == playerObject);
153    format_pcm.containerSize = 32;
154    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
155            &audioSnk, 1, ids, req);
156    assert(SL_RESULT_CONTENT_UNSUPPORTED == result);
157    assert(NULL == playerObject);
158    format_pcm.containerSize = 16;
159
160    // channel mask
161    format_pcm.channelMask = 0;
162    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
163            &audioSnk, 1, ids, req);
164    assert(SL_RESULT_SUCCESS == result);
165    assert(NULL != playerObject);
166    (*playerObject)->Destroy(playerObject);
167    format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
168    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
169            &audioSnk, 1, ids, req);
170    assert(SL_RESULT_PARAMETER_INVALID == result);
171    assert(NULL == playerObject);
172    format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
173            SL_SPEAKER_FRONT_CENTER;
174    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
175            &audioSnk, 1, ids, req);
176    assert(SL_RESULT_PARAMETER_INVALID == result);
177    assert(NULL == playerObject);
178    format_pcm.numChannels = 1;
179    format_pcm.channelMask = 0;
180    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
181            &audioSnk, 1, ids, req);
182    assert(SL_RESULT_SUCCESS == result);
183    assert(NULL != playerObject);
184    (*playerObject)->Destroy(playerObject);
185    format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
186    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
187            &audioSnk, 1, ids, req);
188    assert(SL_RESULT_PARAMETER_INVALID == result);
189    assert(NULL == playerObject);
190    format_pcm.numChannels = 2;
191
192    // endianness
193    format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
194    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
195            &audioSnk, 1, ids, req);
196#ifdef ANDROID // known bug on SDL
197    assert(SL_RESULT_CONTENT_UNSUPPORTED == result);
198    assert(NULL == playerObject);
199#else
200    if (SL_RESULT_CONTENT_UNSUPPORTED != result) {
201        printf("ERROR: expected SL_RESULT_CONTENT_UNSUPPORTED\n");
202        if (NULL != playerObject)
203            (*playerObject)->Destroy(playerObject);
204    }
205#endif
206    format_pcm.endianness = 0;
207    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
208            &audioSnk, 1, ids, req);
209    assert(SL_RESULT_PARAMETER_INVALID == result);
210    assert(NULL == playerObject);
211    format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
212
213    // destroy output mix
214    (*outputMixObject)->Destroy(outputMixObject);
215
216    // destroy engine
217    (*engineObject)->Destroy(engineObject);
218
219    return EXIT_SUCCESS;
220}
221