• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <sys/time.h>
22 
23 #include <SLES/OpenSLES.h>
24 
25 
26 #define MAX_NUMBER_INTERFACES 2
27 
28 #define TEST_MUTE 0
29 #define TEST_SOLO 1
30 
31 static int testMode;
32 //-----------------------------------------------------------------
33 /* Exits the application if an error is encountered */
34 #define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
35 
ExitOnErrorFunc(SLresult result,int line)36 void ExitOnErrorFunc( SLresult result , int line)
37 {
38     if (SL_RESULT_SUCCESS != result) {
39         fprintf(stdout, "%u error code encountered at line %d, exiting\n", result, line);
40         exit(EXIT_FAILURE);
41     }
42 }
43 
44 
45 //-----------------------------------------------------------------
46 
47 /* Play an audio URIs, play, pause, stop  */
TestPlayUri(SLObjectItf sl,const char * path)48 void TestPlayUri( SLObjectItf sl, const char* path)
49 {
50     SLresult  result;
51     SLEngineItf EngineItf;
52 
53     /* Objects this application uses: one player and an ouput mix */
54     SLObjectItf  player, outputMix;
55 
56     /* Source of audio data to play */
57     SLDataSource      audioSource;
58     SLDataLocator_URI uri;
59     SLDataFormat_MIME mime;
60 
61     /* Data sinks for the audio player */
62     SLDataSink               audioSink;
63     SLDataLocator_OutputMix  locator_outputmix;
64 
65     /* Play, Volume and PrefetchStatus interfaces for the audio player */
66     SLPlayItf           playItf;
67     SLMuteSoloItf       muteSoloItf;
68     SLPrefetchStatusItf prefetchItf;
69 
70     SLboolean required[MAX_NUMBER_INTERFACES];
71     SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
72 
73     /* Get the SL Engine Interface which is implicit */
74     result = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
75     ExitOnError(result);
76 
77     /* Initialize arrays required[] and iidArray[] */
78     for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
79         required[i] = SL_BOOLEAN_FALSE;
80         iidArray[i] = SL_IID_NULL;
81     }
82 
83     /* ------------------------------------------------------ */
84     /* Configuration of the output mix  */
85 
86     /* Create Output Mix object to be used by the player */
87      result = (*EngineItf)->CreateOutputMix(EngineItf, &outputMix, 0, iidArray, required);
88      ExitOnError(result);
89 
90     /* Realize the Output Mix object in synchronous mode */
91     result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE);
92     ExitOnError(result);
93 
94     /* Setup the data sink structure */
95     locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
96     locator_outputmix.outputMix   = outputMix;
97     audioSink.pLocator            = (void*)&locator_outputmix;
98     audioSink.pFormat             = NULL;
99 
100     /* ------------------------------------------------------ */
101     /* Configuration of the player  */
102 
103     /* Set arrays required[] and iidArray[] for SLMuteSoloItf and SLPrefetchStatusItf interfaces */
104     /*  (SLPlayItf is implicit) */
105     required[0] = SL_BOOLEAN_TRUE;
106     iidArray[0] = SL_IID_MUTESOLO;
107     required[1] = SL_BOOLEAN_TRUE;
108     iidArray[1] = SL_IID_PREFETCHSTATUS;
109 
110     /* Setup the data source structure for the URI */
111     uri.locatorType = SL_DATALOCATOR_URI;
112     uri.URI         =  (SLchar*) path;
113     mime.formatType = SL_DATAFORMAT_MIME;
114     /*     this is how ignored mime information is specified, according to OpenSL ES spec
115      *     in 9.1.6 SLDataFormat_MIME and 8.23 SLMetadataTraversalItf GetChildInfo */
116     mime.mimeType      = (SLchar*)NULL;
117     mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;
118 
119     audioSource.pFormat  = (void*)&mime;
120     audioSource.pLocator = (void*)&uri;
121 
122     /* Create the audio player */
123     result = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink,
124             MAX_NUMBER_INTERFACES, iidArray, required);
125     ExitOnError(result);
126 
127     /* Realize the player in synchronous mode. */
128     result = (*player)->Realize(player, SL_BOOLEAN_FALSE); ExitOnError(result);
129     fprintf(stdout, "URI example: after Realize\n");
130 
131     /* Get the SLPlayItf, SLPrefetchStatusItf and SLMuteSoloItf interfaces for the player */
132     result = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
133     ExitOnError(result);
134 
135     result = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
136     ExitOnError(result);
137 
138     result = (*player)->GetInterface(player, SL_IID_MUTESOLO, (void*)&muteSoloItf);
139     ExitOnError(result);
140 
141 
142     fprintf(stdout, "Player configured\n");
143 
144     /* ------------------------------------------------------ */
145     /* Playback and test */
146 
147     /* Start the data prefetching by setting the player to the paused state */
148     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
149     ExitOnError(result);
150 
151     /* Wait until there's data to play */
152     SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
153     while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) {
154         usleep(100 * 1000);
155         (*prefetchItf)->GetPrefetchStatus(prefetchItf, &prefetchStatus);
156     }
157 
158 
159     /* Testing play states */
160     /* let it play for 2s */
161     fprintf(stdout, "----- Playing\n");
162     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
163     ExitOnError(result);
164     usleep(2 * 1000 * 1000);
165 
166     /* pause for 1s*/
167     fprintf(stdout, "----- Pausing (1s)\n");
168     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED );
169     ExitOnError(result);
170     usleep(2 * 1000 * 1000);
171 
172     /* resume */
173     fprintf(stdout, "----- Playing (2s, should have resumed where it paused)\n");
174     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
175     ExitOnError(result);
176     usleep(2 * 1000 * 1000);
177 
178     /* stop */
179     fprintf(stdout, "----- Stopping\n");
180     result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
181     ExitOnError(result);
182 
183     /* play for 2s */
184     fprintf(stdout, "----- Playing (2s, should have started from the beginning\n");
185     result = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
186     ExitOnError(result);
187     usleep(2 * 1000 * 1000);
188 
189     /* stop */
190     fprintf(stdout, "----- Stopping\n");
191     result = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
192     ExitOnError(result);
193 
194 destroyKillKill:
195 
196     /* Destroy the players */
197     (*player)->Destroy(player);
198 
199     /* Destroy Output Mix object */
200     (*outputMix)->Destroy(outputMix);
201 }
202 
203 //-----------------------------------------------------------------
main(int argc,char * const argv[])204 int main(int argc, char* const argv[])
205 {
206     SLresult    result;
207     SLObjectItf sl;
208 
209     fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLVolumeItf, SLMuteSoloItf\n",
210             argv[0]);
211     fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
212     fprintf(stdout, "Plays a sound and alternates the muting of the channels (for 5s).\n");
213     fprintf(stdout, " and then alternates the solo\'ing of the channels (for 5s).\n");
214     fprintf(stdout, "Stops after 10s\n");
215 
216     if (argc == 1) {
217         fprintf(stdout, "Usage: \t%s url\n", argv[0]);
218         fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"\n", argv[0]);
219         exit(EXIT_FAILURE);
220     }
221 
222     SLEngineOption EngineOption[] = {
223             {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
224     };
225 
226     result = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
227     ExitOnError(result);
228 
229     /* Realizing the SL Engine in synchronous mode. */
230     result = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
231     ExitOnError(result);
232 
233     if (argc > 1) {
234         TestPlayUri(sl, argv[1]);
235     }
236 
237     /* Shutdown OpenSL ES */
238     (*sl)->Destroy(sl);
239 
240     return EXIT_SUCCESS;
241 }
242