1*bebae9c0SAndroid Build Coastguard Worker /*
2*bebae9c0SAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*bebae9c0SAndroid Build Coastguard Worker *
4*bebae9c0SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*bebae9c0SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*bebae9c0SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*bebae9c0SAndroid Build Coastguard Worker *
8*bebae9c0SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*bebae9c0SAndroid Build Coastguard Worker *
10*bebae9c0SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*bebae9c0SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*bebae9c0SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*bebae9c0SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*bebae9c0SAndroid Build Coastguard Worker * limitations under the License.
15*bebae9c0SAndroid Build Coastguard Worker */
16*bebae9c0SAndroid Build Coastguard Worker
17*bebae9c0SAndroid Build Coastguard Worker // multiplay is a command-line test app that plays multiple files randomly
18*bebae9c0SAndroid Build Coastguard Worker
19*bebae9c0SAndroid Build Coastguard Worker #include <SLES/OpenSLES.h>
20*bebae9c0SAndroid Build Coastguard Worker #include <assert.h>
21*bebae9c0SAndroid Build Coastguard Worker #include <string.h>
22*bebae9c0SAndroid Build Coastguard Worker #include <stdlib.h>
23*bebae9c0SAndroid Build Coastguard Worker #include <stdio.h>
24*bebae9c0SAndroid Build Coastguard Worker #include <unistd.h>
25*bebae9c0SAndroid Build Coastguard Worker
26*bebae9c0SAndroid Build Coastguard Worker // Describes the state of one player
27*bebae9c0SAndroid Build Coastguard Worker
28*bebae9c0SAndroid Build Coastguard Worker typedef struct {
29*bebae9c0SAndroid Build Coastguard Worker SLObjectItf mPlayerObject;
30*bebae9c0SAndroid Build Coastguard Worker SLPlayItf mPlayerPlay;
31*bebae9c0SAndroid Build Coastguard Worker SLSeekItf mPlayerSeek;
32*bebae9c0SAndroid Build Coastguard Worker SLPrefetchStatusItf mPlayerPrefetchStatus;
33*bebae9c0SAndroid Build Coastguard Worker SLVolumeItf mPlayerVolume;
34*bebae9c0SAndroid Build Coastguard Worker SLmillisecond mPlayerDuration;
35*bebae9c0SAndroid Build Coastguard Worker SLboolean mPlayerErrorInCallback;
36*bebae9c0SAndroid Build Coastguard Worker SLboolean mPlayerErrorReported;
37*bebae9c0SAndroid Build Coastguard Worker } Player;
38*bebae9c0SAndroid Build Coastguard Worker
39*bebae9c0SAndroid Build Coastguard Worker // Strings corresponding to result codes; FIXME should move to a common test library
40*bebae9c0SAndroid Build Coastguard Worker
41*bebae9c0SAndroid Build Coastguard Worker static const char *result_strings[] = {
42*bebae9c0SAndroid Build Coastguard Worker "SUCCESS",
43*bebae9c0SAndroid Build Coastguard Worker "PRECONDITIONS_VIOLATED",
44*bebae9c0SAndroid Build Coastguard Worker "PARAMETER_INVALID",
45*bebae9c0SAndroid Build Coastguard Worker "MEMORY_FAILURE",
46*bebae9c0SAndroid Build Coastguard Worker "RESOURCE_ERROR",
47*bebae9c0SAndroid Build Coastguard Worker "RESOURCE_LOST",
48*bebae9c0SAndroid Build Coastguard Worker "IO_ERROR",
49*bebae9c0SAndroid Build Coastguard Worker "BUFFER_INSUFFICIENT",
50*bebae9c0SAndroid Build Coastguard Worker "CONTENT_CORRUPTED",
51*bebae9c0SAndroid Build Coastguard Worker "CONTENT_UNSUPPORTED",
52*bebae9c0SAndroid Build Coastguard Worker "CONTENT_NOT_FOUND",
53*bebae9c0SAndroid Build Coastguard Worker "PERMISSION_DENIED",
54*bebae9c0SAndroid Build Coastguard Worker "FEATURE_UNSUPPORTED",
55*bebae9c0SAndroid Build Coastguard Worker "INTERNAL_ERROR",
56*bebae9c0SAndroid Build Coastguard Worker "UNKNOWN_ERROR",
57*bebae9c0SAndroid Build Coastguard Worker "OPERATION_ABORTED",
58*bebae9c0SAndroid Build Coastguard Worker "CONTROL_LOST"
59*bebae9c0SAndroid Build Coastguard Worker };
60*bebae9c0SAndroid Build Coastguard Worker
61*bebae9c0SAndroid Build Coastguard Worker // Convert result to string; FIXME should move to common test library
62*bebae9c0SAndroid Build Coastguard Worker
result_to_string(SLresult result)63*bebae9c0SAndroid Build Coastguard Worker static const char *result_to_string(SLresult result)
64*bebae9c0SAndroid Build Coastguard Worker {
65*bebae9c0SAndroid Build Coastguard Worker static char buffer[32];
66*bebae9c0SAndroid Build Coastguard Worker if ( /* result >= 0 && */ result < sizeof(result_strings) / sizeof(result_strings[0]))
67*bebae9c0SAndroid Build Coastguard Worker return result_strings[result];
68*bebae9c0SAndroid Build Coastguard Worker sprintf(buffer, "%d", (int) result);
69*bebae9c0SAndroid Build Coastguard Worker return buffer;
70*bebae9c0SAndroid Build Coastguard Worker }
71*bebae9c0SAndroid Build Coastguard Worker
72*bebae9c0SAndroid Build Coastguard Worker // Compare result against expected and exit suddenly if wrong
73*bebae9c0SAndroid Build Coastguard Worker
check2(SLresult result,int line)74*bebae9c0SAndroid Build Coastguard Worker void check2(SLresult result, int line)
75*bebae9c0SAndroid Build Coastguard Worker {
76*bebae9c0SAndroid Build Coastguard Worker if (SL_RESULT_SUCCESS != result) {
77*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "error %s at line %d\n", result_to_string(result), line);
78*bebae9c0SAndroid Build Coastguard Worker exit(EXIT_FAILURE);
79*bebae9c0SAndroid Build Coastguard Worker }
80*bebae9c0SAndroid Build Coastguard Worker }
81*bebae9c0SAndroid Build Coastguard Worker
82*bebae9c0SAndroid Build Coastguard Worker // Same as above but automatically adds the source code line number
83*bebae9c0SAndroid Build Coastguard Worker
84*bebae9c0SAndroid Build Coastguard Worker #define check(result) check2(result, __LINE__)
85*bebae9c0SAndroid Build Coastguard Worker
86*bebae9c0SAndroid Build Coastguard Worker // Prefetch status callback
87*bebae9c0SAndroid Build Coastguard Worker
88*bebae9c0SAndroid Build Coastguard Worker #define PREFETCHEVENT_ERROR_CANDIDATE \
89*bebae9c0SAndroid Build Coastguard Worker (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE)
90*bebae9c0SAndroid Build Coastguard Worker
prefetch_callback(SLPrefetchStatusItf caller,void * context,SLuint32 event)91*bebae9c0SAndroid Build Coastguard Worker void prefetch_callback(SLPrefetchStatusItf caller, void *context, SLuint32 event)
92*bebae9c0SAndroid Build Coastguard Worker {
93*bebae9c0SAndroid Build Coastguard Worker SLresult result;
94*bebae9c0SAndroid Build Coastguard Worker assert(context != NULL);
95*bebae9c0SAndroid Build Coastguard Worker Player *p = (Player *) context;
96*bebae9c0SAndroid Build Coastguard Worker assert(p->mPlayerPrefetchStatus == caller);
97*bebae9c0SAndroid Build Coastguard Worker SLpermille level;
98*bebae9c0SAndroid Build Coastguard Worker result = (*caller)->GetFillLevel(caller, &level);
99*bebae9c0SAndroid Build Coastguard Worker check(result);
100*bebae9c0SAndroid Build Coastguard Worker SLuint32 status;
101*bebae9c0SAndroid Build Coastguard Worker result = (*caller)->GetPrefetchStatus(caller, &status);
102*bebae9c0SAndroid Build Coastguard Worker check(result);
103*bebae9c0SAndroid Build Coastguard Worker //fprintf(stderr, "PrefetchEventCallback: received event %u, level %u, status %u\n",
104*bebae9c0SAndroid Build Coastguard Worker // event, level, status);
105*bebae9c0SAndroid Build Coastguard Worker if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE))
106*bebae9c0SAndroid Build Coastguard Worker && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) {
107*bebae9c0SAndroid Build Coastguard Worker p->mPlayerErrorInCallback = SL_BOOLEAN_TRUE;
108*bebae9c0SAndroid Build Coastguard Worker }
109*bebae9c0SAndroid Build Coastguard Worker }
110*bebae9c0SAndroid Build Coastguard Worker
111*bebae9c0SAndroid Build Coastguard Worker // Main program
112*bebae9c0SAndroid Build Coastguard Worker
main(int argc,char ** argv)113*bebae9c0SAndroid Build Coastguard Worker int main(int argc, char **argv)
114*bebae9c0SAndroid Build Coastguard Worker {
115*bebae9c0SAndroid Build Coastguard Worker int i;
116*bebae9c0SAndroid Build Coastguard Worker const char *arg;
117*bebae9c0SAndroid Build Coastguard Worker int numPlayers = 0;
118*bebae9c0SAndroid Build Coastguard Worker int playTimeInMilliseconds = 0; // default to run forever
119*bebae9c0SAndroid Build Coastguard Worker SLmillibel mixVolumeLevel = 0;
120*bebae9c0SAndroid Build Coastguard Worker for (i = 1; i < argc; ++i) {
121*bebae9c0SAndroid Build Coastguard Worker arg = argv[i];
122*bebae9c0SAndroid Build Coastguard Worker if (arg[0] != '-')
123*bebae9c0SAndroid Build Coastguard Worker break;
124*bebae9c0SAndroid Build Coastguard Worker if (!strncmp(arg, "-n", 2))
125*bebae9c0SAndroid Build Coastguard Worker numPlayers = atoi(&arg[2]);
126*bebae9c0SAndroid Build Coastguard Worker else if (!strncmp(arg, "-v", 2))
127*bebae9c0SAndroid Build Coastguard Worker mixVolumeLevel = atoi(&arg[2]);
128*bebae9c0SAndroid Build Coastguard Worker else if (!strncmp(arg, "-t", 2))
129*bebae9c0SAndroid Build Coastguard Worker playTimeInMilliseconds = atoi(&arg[2]) * 1000;
130*bebae9c0SAndroid Build Coastguard Worker else
131*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "unknown option: %s\n", arg);
132*bebae9c0SAndroid Build Coastguard Worker }
133*bebae9c0SAndroid Build Coastguard Worker int numPathnames = argc - i;
134*bebae9c0SAndroid Build Coastguard Worker if (numPathnames <= 0) {
135*bebae9c0SAndroid Build Coastguard Worker fprintf(stderr, "usage: %s file.wav ...\n", argv[0]);
136*bebae9c0SAndroid Build Coastguard Worker return EXIT_FAILURE;
137*bebae9c0SAndroid Build Coastguard Worker }
138*bebae9c0SAndroid Build Coastguard Worker if (numPlayers <= 0) {
139*bebae9c0SAndroid Build Coastguard Worker numPlayers = numPathnames;
140*bebae9c0SAndroid Build Coastguard Worker }
141*bebae9c0SAndroid Build Coastguard Worker Player *players = (Player *) calloc(numPlayers, sizeof(Player));
142*bebae9c0SAndroid Build Coastguard Worker assert(NULL != players);
143*bebae9c0SAndroid Build Coastguard Worker char **pathnames = &argv[i];
144*bebae9c0SAndroid Build Coastguard Worker SLresult result;
145*bebae9c0SAndroid Build Coastguard Worker
146*bebae9c0SAndroid Build Coastguard Worker // engine
147*bebae9c0SAndroid Build Coastguard Worker const SLInterfaceID engine_ids[] = {SL_IID_ENGINE};
148*bebae9c0SAndroid Build Coastguard Worker const SLboolean engine_req[] = {SL_BOOLEAN_TRUE};
149*bebae9c0SAndroid Build Coastguard Worker SLObjectItf engineObject;
150*bebae9c0SAndroid Build Coastguard Worker result = slCreateEngine(&engineObject, 0, NULL, 1, engine_ids, engine_req);
151*bebae9c0SAndroid Build Coastguard Worker check(result);
152*bebae9c0SAndroid Build Coastguard Worker result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
153*bebae9c0SAndroid Build Coastguard Worker check(result);
154*bebae9c0SAndroid Build Coastguard Worker SLEngineItf engineEngine;
155*bebae9c0SAndroid Build Coastguard Worker result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
156*bebae9c0SAndroid Build Coastguard Worker check(result);
157*bebae9c0SAndroid Build Coastguard Worker
158*bebae9c0SAndroid Build Coastguard Worker // mixer
159*bebae9c0SAndroid Build Coastguard Worker const SLInterfaceID mix_ids[] = {SL_IID_VOLUME};
160*bebae9c0SAndroid Build Coastguard Worker const SLboolean mix_req[] = {SL_BOOLEAN_TRUE};
161*bebae9c0SAndroid Build Coastguard Worker SLObjectItf mixObject;
162*bebae9c0SAndroid Build Coastguard Worker result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, 0, mix_ids, mix_req);
163*bebae9c0SAndroid Build Coastguard Worker check(result);
164*bebae9c0SAndroid Build Coastguard Worker result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE);
165*bebae9c0SAndroid Build Coastguard Worker check(result);
166*bebae9c0SAndroid Build Coastguard Worker #if 0
167*bebae9c0SAndroid Build Coastguard Worker SLVolumeItf mixVolume;
168*bebae9c0SAndroid Build Coastguard Worker result = (*mixObject)->GetInterface(mixObject, SL_IID_VOLUME, &mixVolume);
169*bebae9c0SAndroid Build Coastguard Worker check(result);
170*bebae9c0SAndroid Build Coastguard Worker SLmillibel mixVolumeLevelDefault;
171*bebae9c0SAndroid Build Coastguard Worker result = (*mixVolume)->GetVolumeLevel(mixVolume, &mixVolumeLevelDefault);
172*bebae9c0SAndroid Build Coastguard Worker check(result);
173*bebae9c0SAndroid Build Coastguard Worker printf("default mix volume level = %d\n", mixVolumeLevelDefault);
174*bebae9c0SAndroid Build Coastguard Worker #endif
175*bebae9c0SAndroid Build Coastguard Worker
176*bebae9c0SAndroid Build Coastguard Worker printf("numPathnames=%d\n", numPathnames);
177*bebae9c0SAndroid Build Coastguard Worker printf("numPlayers=%d\n", numPlayers);
178*bebae9c0SAndroid Build Coastguard Worker Player *p;
179*bebae9c0SAndroid Build Coastguard Worker
180*bebae9c0SAndroid Build Coastguard Worker // create all the players
181*bebae9c0SAndroid Build Coastguard Worker for (i = 0; i < numPlayers; ++i) {
182*bebae9c0SAndroid Build Coastguard Worker const SLInterfaceID player_ids[] =
183*bebae9c0SAndroid Build Coastguard Worker {SL_IID_PLAY, SL_IID_VOLUME, SL_IID_SEEK, SL_IID_PREFETCHSTATUS};
184*bebae9c0SAndroid Build Coastguard Worker const SLboolean player_req[] =
185*bebae9c0SAndroid Build Coastguard Worker {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
186*bebae9c0SAndroid Build Coastguard Worker p = &players[i];
187*bebae9c0SAndroid Build Coastguard Worker SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, (SLchar *) pathnames[i % numPathnames]};
188*bebae9c0SAndroid Build Coastguard Worker SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
189*bebae9c0SAndroid Build Coastguard Worker SLDataSource audioSrc = {&locURI, &dfMIME};
190*bebae9c0SAndroid Build Coastguard Worker SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, mixObject};
191*bebae9c0SAndroid Build Coastguard Worker SLDataSink audioSnk = {&locOutputMix, NULL};
192*bebae9c0SAndroid Build Coastguard Worker result = (*engineEngine)->CreateAudioPlayer(engineEngine, &p->mPlayerObject, &audioSrc,
193*bebae9c0SAndroid Build Coastguard Worker &audioSnk, sizeof(player_ids)/sizeof(player_ids[0]), player_ids, player_req);
194*bebae9c0SAndroid Build Coastguard Worker check(result);
195*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerObject)->Realize(p->mPlayerObject, SL_BOOLEAN_FALSE);
196*bebae9c0SAndroid Build Coastguard Worker check(result);
197*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_PLAY, &p->mPlayerPlay);
198*bebae9c0SAndroid Build Coastguard Worker check(result);
199*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_VOLUME,
200*bebae9c0SAndroid Build Coastguard Worker &p->mPlayerVolume);
201*bebae9c0SAndroid Build Coastguard Worker check(result);
202*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_SEEK, &p->mPlayerSeek);
203*bebae9c0SAndroid Build Coastguard Worker check(result);
204*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_PREFETCHSTATUS,
205*bebae9c0SAndroid Build Coastguard Worker &p->mPlayerPrefetchStatus);
206*bebae9c0SAndroid Build Coastguard Worker check(result);
207*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerPrefetchStatus)->RegisterCallback(p->mPlayerPrefetchStatus,
208*bebae9c0SAndroid Build Coastguard Worker prefetch_callback, p);
209*bebae9c0SAndroid Build Coastguard Worker check(result);
210*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerPrefetchStatus)->SetCallbackEventsMask(p->mPlayerPrefetchStatus,
211*bebae9c0SAndroid Build Coastguard Worker SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
212*bebae9c0SAndroid Build Coastguard Worker check(result);
213*bebae9c0SAndroid Build Coastguard Worker }
214*bebae9c0SAndroid Build Coastguard Worker
215*bebae9c0SAndroid Build Coastguard Worker // now loop randomly doing things to the players
216*bebae9c0SAndroid Build Coastguard Worker for (;;) {
217*bebae9c0SAndroid Build Coastguard Worker SLmillisecond delay = 100 + (rand() & 1023);
218*bebae9c0SAndroid Build Coastguard Worker printf("sleep %u\n", (unsigned) delay);
219*bebae9c0SAndroid Build Coastguard Worker usleep(delay * 1000);
220*bebae9c0SAndroid Build Coastguard Worker i = (rand() & 0x7FFFFFFF) % numPlayers;
221*bebae9c0SAndroid Build Coastguard Worker p = &players[i];
222*bebae9c0SAndroid Build Coastguard Worker if (p->mPlayerErrorReported)
223*bebae9c0SAndroid Build Coastguard Worker continue;
224*bebae9c0SAndroid Build Coastguard Worker printf("player %d (%s): ", i, pathnames[i]);
225*bebae9c0SAndroid Build Coastguard Worker if (p->mPlayerErrorInCallback && !p->mPlayerErrorReported) {
226*bebae9c0SAndroid Build Coastguard Worker printf("error, ");
227*bebae9c0SAndroid Build Coastguard Worker p->mPlayerErrorReported = SL_BOOLEAN_TRUE;
228*bebae9c0SAndroid Build Coastguard Worker }
229*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerPlay)->GetDuration(p->mPlayerPlay, &p->mPlayerDuration);
230*bebae9c0SAndroid Build Coastguard Worker check(result);
231*bebae9c0SAndroid Build Coastguard Worker if (p->mPlayerDuration == SL_TIME_UNKNOWN) {
232*bebae9c0SAndroid Build Coastguard Worker printf("duration unknown, ");
233*bebae9c0SAndroid Build Coastguard Worker } else {
234*bebae9c0SAndroid Build Coastguard Worker printf("duration %d ms, ", (int) p->mPlayerDuration);
235*bebae9c0SAndroid Build Coastguard Worker }
236*bebae9c0SAndroid Build Coastguard Worker SLuint32 state;
237*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerPlay)->GetPlayState(p->mPlayerPlay, &state);
238*bebae9c0SAndroid Build Coastguard Worker check(result);
239*bebae9c0SAndroid Build Coastguard Worker printf("state = ");
240*bebae9c0SAndroid Build Coastguard Worker switch (state) {
241*bebae9c0SAndroid Build Coastguard Worker case SL_PLAYSTATE_STOPPED:
242*bebae9c0SAndroid Build Coastguard Worker printf("STOPPED");
243*bebae9c0SAndroid Build Coastguard Worker break;
244*bebae9c0SAndroid Build Coastguard Worker case SL_PLAYSTATE_PAUSED:
245*bebae9c0SAndroid Build Coastguard Worker printf("PAUSED");
246*bebae9c0SAndroid Build Coastguard Worker break;
247*bebae9c0SAndroid Build Coastguard Worker case SL_PLAYSTATE_PLAYING:
248*bebae9c0SAndroid Build Coastguard Worker printf("PLAYING");
249*bebae9c0SAndroid Build Coastguard Worker break;
250*bebae9c0SAndroid Build Coastguard Worker default:
251*bebae9c0SAndroid Build Coastguard Worker printf("%u", (unsigned) state);
252*bebae9c0SAndroid Build Coastguard Worker break;
253*bebae9c0SAndroid Build Coastguard Worker }
254*bebae9c0SAndroid Build Coastguard Worker printf("\n");
255*bebae9c0SAndroid Build Coastguard Worker if (state == SL_PLAYSTATE_STOPPED || state == SL_PLAYSTATE_PAUSED) {
256*bebae9c0SAndroid Build Coastguard Worker SLmillibel volumeLevel = -((rand() & 0x7FFFFFFF) % ((SL_MILLIBEL_MIN + 1) / 10));
257*bebae9c0SAndroid Build Coastguard Worker printf("volume %d\n", volumeLevel);
258*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerVolume)->SetVolumeLevel(p->mPlayerVolume, volumeLevel);
259*bebae9c0SAndroid Build Coastguard Worker check(result);
260*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerVolume)->EnableStereoPosition(p->mPlayerVolume, SL_BOOLEAN_TRUE);
261*bebae9c0SAndroid Build Coastguard Worker check(result);
262*bebae9c0SAndroid Build Coastguard Worker SLpermille stereoPosition = ((rand() & 0x7FFFFFFF) % 2001) - 1000;
263*bebae9c0SAndroid Build Coastguard Worker printf("position %d\n", stereoPosition);
264*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerVolume)->SetStereoPosition(p->mPlayerVolume, stereoPosition);
265*bebae9c0SAndroid Build Coastguard Worker check(result);
266*bebae9c0SAndroid Build Coastguard Worker if (state != SL_PLAYSTATE_STOPPED) {
267*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerSeek)->SetPosition(p->mPlayerSeek, 0, SL_SEEKMODE_FAST);
268*bebae9c0SAndroid Build Coastguard Worker check(result);
269*bebae9c0SAndroid Build Coastguard Worker }
270*bebae9c0SAndroid Build Coastguard Worker result = (*p->mPlayerPlay)->SetPlayState(p->mPlayerPlay, SL_PLAYSTATE_PLAYING);
271*bebae9c0SAndroid Build Coastguard Worker check(result);
272*bebae9c0SAndroid Build Coastguard Worker }
273*bebae9c0SAndroid Build Coastguard Worker if ((playTimeInMilliseconds > 0) && ((playTimeInMilliseconds -= delay) < 0))
274*bebae9c0SAndroid Build Coastguard Worker break;
275*bebae9c0SAndroid Build Coastguard Worker }
276*bebae9c0SAndroid Build Coastguard Worker
277*bebae9c0SAndroid Build Coastguard Worker for (i = 0; i < numPlayers; ++i) {
278*bebae9c0SAndroid Build Coastguard Worker SLObjectItf playerObject = players[i].mPlayerObject;
279*bebae9c0SAndroid Build Coastguard Worker (*playerObject)->Destroy(playerObject);
280*bebae9c0SAndroid Build Coastguard Worker }
281*bebae9c0SAndroid Build Coastguard Worker (*mixObject)->Destroy(mixObject);
282*bebae9c0SAndroid Build Coastguard Worker (*engineObject)->Destroy(engineObject);
283*bebae9c0SAndroid Build Coastguard Worker
284*bebae9c0SAndroid Build Coastguard Worker return EXIT_SUCCESS;
285*bebae9c0SAndroid Build Coastguard Worker }
286