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