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
main(int argc,char ** argv)24 int 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