11c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten/* 21c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 31c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * 41c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 51c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * you may not use this file except in compliance with the License. 61c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * You may obtain a copy of the License at 71c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * 81c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 91c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * 101c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * Unless required by applicable law or agreed to in writing, software 111c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 121c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * See the License for the specific language governing permissions and 141c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten * limitations under the License. 151c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten */ 161c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 171c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// multiplay is a command-line test app that plays multiple files randomly 181c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 19c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h> 201c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#include <assert.h> 211c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#include <string.h> 221c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#include <stdlib.h> 231c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#include <stdio.h> 24c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten#include <unistd.h> 251c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 261c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Describes the state of one player 271c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 281c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastentypedef struct { 291c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLObjectItf mPlayerObject; 301c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLPlayItf mPlayerPlay; 311c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLSeekItf mPlayerSeek; 32d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten SLPrefetchStatusItf mPlayerPrefetchStatus; 331c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLVolumeItf mPlayerVolume; 341c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLmillisecond mPlayerDuration; 35d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten SLboolean mPlayerErrorInCallback; 36d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten SLboolean mPlayerErrorReported; 371c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten} Player; 381c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 391c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Strings corresponding to result codes; FIXME should move to a common test library 401c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 411c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastenstatic const char *result_strings[] = { 421c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "SUCCESS", 431c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "PRECONDITIONS_VIOLATED", 441c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "PARAMETER_INVALID", 451c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "MEMORY_FAILURE", 461c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "RESOURCE_ERROR", 471c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "RESOURCE_LOST", 481c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "IO_ERROR", 491c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "BUFFER_INSUFFICIENT", 501c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "CONTENT_CORRUPTED", 511c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "CONTENT_UNSUPPORTED", 521c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "CONTENT_NOT_FOUND", 531c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "PERMISSION_DENIED", 541c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "FEATURE_UNSUPPORTED", 551c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "INTERNAL_ERROR", 561c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "UNKNOWN_ERROR", 571c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "OPERATION_ABORTED", 581c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten "CONTROL_LOST" 591c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten}; 601c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 611c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Convert result to string; FIXME should move to common test library 621c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 631c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastenstatic const char *result_to_string(SLresult result) 641c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten{ 651c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten static char buffer[32]; 661c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten if ( /* result >= 0 && */ result < sizeof(result_strings) / sizeof(result_strings[0])) 671c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten return result_strings[result]; 684b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten sprintf(buffer, "%d", (int) result); 691c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten return buffer; 701c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten} 711c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 721c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Compare result against expected and exit suddenly if wrong 731c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 741c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastenvoid check2(SLresult result, int line) 751c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten{ 761c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten if (SL_RESULT_SUCCESS != result) { 771c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten fprintf(stderr, "error %s at line %d\n", result_to_string(result), line); 781c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten exit(EXIT_FAILURE); 791c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten } 801c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten} 811c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 821c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Same as above but automatically adds the source code line number 831c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 841c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#define check(result) check2(result, __LINE__) 851c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 86d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten// Prefetch status callback 87d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten 88d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten#define PREFETCHEVENT_ERROR_CANDIDATE \ 89d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE) 90d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten 91d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kastenvoid prefetch_callback(SLPrefetchStatusItf caller, void *context, SLuint32 event) 92d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten{ 93d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten SLresult result; 94d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten assert(context != NULL); 95d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten Player *p = (Player *) context; 96d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten assert(p->mPlayerPrefetchStatus == caller); 97d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten SLpermille level; 98d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten result = (*caller)->GetFillLevel(caller, &level); 99d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten check(result); 100d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten SLuint32 status; 101d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten result = (*caller)->GetPrefetchStatus(caller, &status); 102d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten check(result); 103d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten //fprintf(stderr, "PrefetchEventCallback: received event %u, level %u, status %u\n", 104d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten // event, level, status); 105d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE)) 106d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) { 107d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten p->mPlayerErrorInCallback = SL_BOOLEAN_TRUE; 108d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten } 109d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten} 110d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten 1111c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Main program 1121c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 1131c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastenint main(int argc, char **argv) 1141c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten{ 1151c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten int i; 1161c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten const char *arg; 1171c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten int numPlayers = 0; 1180a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten int playTimeInMilliseconds = 0; // default to run forever 1191c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLmillibel mixVolumeLevel = 0; 1201c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten for (i = 1; i < argc; ++i) { 1211c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten arg = argv[i]; 1221c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten if (arg[0] != '-') 1231c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten break; 1241c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten if (!strncmp(arg, "-n", 2)) 1251c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten numPlayers = atoi(&arg[2]); 1261c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten else if (!strncmp(arg, "-v", 2)) 1271c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten mixVolumeLevel = atoi(&arg[2]); 1280a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten else if (!strncmp(arg, "-t", 2)) 1290a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten playTimeInMilliseconds = atoi(&arg[2]) * 1000; 1301c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten else 1311c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten fprintf(stderr, "unknown option: %s\n", arg); 1321c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten } 1331c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten int numPathnames = argc - i; 1341c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten if (numPathnames <= 0) { 1351c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten fprintf(stderr, "usage: %s file.wav ...\n", argv[0]); 1361c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten return EXIT_FAILURE; 1371c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten } 138d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten if (numPlayers <= 0) { 1391c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten numPlayers = numPathnames; 140d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten } 141d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten Player *players = (Player *) calloc(numPlayers, sizeof(Player)); 1421c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten assert(NULL != players); 1431c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten char **pathnames = &argv[i]; 1441c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLresult result; 1451c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 1461c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten // engine 1471c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten const SLInterfaceID engine_ids[] = {SL_IID_ENGINE}; 1481c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten const SLboolean engine_req[] = {SL_BOOLEAN_TRUE}; 1491c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLObjectItf engineObject; 1501c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = slCreateEngine(&engineObject, 0, NULL, 1, engine_ids, engine_req); 1511c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 1521c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 1531c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 1541c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLEngineItf engineEngine; 1551c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 1561c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 1571c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 1581c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten // mixer 1591c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten const SLInterfaceID mix_ids[] = {SL_IID_VOLUME}; 1601c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten const SLboolean mix_req[] = {SL_BOOLEAN_TRUE}; 1611c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLObjectItf mixObject; 162c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, 0, mix_ids, mix_req); 1631c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 1641c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE); 1651c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 166c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten#if 0 1671c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLVolumeItf mixVolume; 1681c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*mixObject)->GetInterface(mixObject, SL_IID_VOLUME, &mixVolume); 1691c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 1701c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLmillibel mixVolumeLevelDefault; 1711c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*mixVolume)->GetVolumeLevel(mixVolume, &mixVolumeLevelDefault); 1721c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 1731c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten printf("default mix volume level = %d\n", mixVolumeLevelDefault); 174c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten#endif 1751c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 1761c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten printf("numPathnames=%d\n", numPathnames); 1771c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten printf("numPlayers=%d\n", numPlayers); 1781c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten Player *p; 1791c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 1801c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten // create all the players 1811c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten for (i = 0; i < numPlayers; ++i) { 182d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten const SLInterfaceID player_ids[] = 183d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten {SL_IID_PLAY, SL_IID_VOLUME, SL_IID_SEEK, SL_IID_PREFETCHSTATUS}; 184d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten const SLboolean player_req[] = 185d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; 1861c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten p = &players[i]; 1871c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, (SLchar *) pathnames[i % numPathnames]}; 1881c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; 1891c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLDataSource audioSrc = {&locURI, &dfMIME}; 1901c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, mixObject}; 1911c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLDataSink audioSnk = {&locOutputMix, NULL}; 192ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = (*engineEngine)->CreateAudioPlayer(engineEngine, &p->mPlayerObject, &audioSrc, 193d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten &audioSnk, sizeof(player_ids)/sizeof(player_ids[0]), player_ids, player_req); 1941c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 1951c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*p->mPlayerObject)->Realize(p->mPlayerObject, SL_BOOLEAN_FALSE); 1961c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 1971c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_PLAY, &p->mPlayerPlay); 1981c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 199ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_VOLUME, 200ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten &p->mPlayerVolume); 2011c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 2021c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_SEEK, &p->mPlayerSeek); 2031c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 204d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_PREFETCHSTATUS, 205d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten &p->mPlayerPrefetchStatus); 206d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten check(result); 207d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten result = (*p->mPlayerPrefetchStatus)->RegisterCallback(p->mPlayerPrefetchStatus, 208d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten prefetch_callback, p); 209d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten check(result); 210d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten result = (*p->mPlayerPrefetchStatus)->SetCallbackEventsMask(p->mPlayerPrefetchStatus, 211d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE); 2121c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 2131c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten } 2141c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 2151c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten // now loop randomly doing things to the players 2161c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten for (;;) { 2171c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLmillisecond delay = 100 + (rand() & 1023); 2184b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten printf("sleep %u\n", (unsigned) delay); 2191c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten usleep(delay * 1000); 2201c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten i = (rand() & 0x7FFFFFFF) % numPlayers; 2211c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten p = &players[i]; 222d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten if (p->mPlayerErrorReported) 223d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten continue; 224d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten printf("player %d (%s): ", i, pathnames[i]); 225d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten if (p->mPlayerErrorInCallback && !p->mPlayerErrorReported) { 226d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten printf("error, "); 227d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten p->mPlayerErrorReported = SL_BOOLEAN_TRUE; 228d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten } 229d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten result = (*p->mPlayerPlay)->GetDuration(p->mPlayerPlay, &p->mPlayerDuration); 230d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten check(result); 231d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten if (p->mPlayerDuration == SL_TIME_UNKNOWN) { 232d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten printf("duration unknown, "); 233d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten } else { 234d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten printf("duration %d ms, ", (int) p->mPlayerDuration); 235d91db4c34bdffa3b6d3f9234c8f4f8506bc0aa2eGlenn Kasten } 2361c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLuint32 state; 2371c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*p->mPlayerPlay)->GetPlayState(p->mPlayerPlay, &state); 2381c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 2391c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten printf("state = "); 2401c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten switch (state) { 2411c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten case SL_PLAYSTATE_STOPPED: 2421c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten printf("STOPPED"); 2431c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten break; 2441c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten case SL_PLAYSTATE_PAUSED: 2451c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten printf("PAUSED"); 2461c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten break; 2471c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten case SL_PLAYSTATE_PLAYING: 2481c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten printf("PLAYING"); 2491c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten break; 2501c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten default: 2514b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten printf("%u", (unsigned) state); 2521c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten break; 2531c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten } 2544b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten printf("\n"); 2551c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten if (state == SL_PLAYSTATE_STOPPED || state == SL_PLAYSTATE_PAUSED) { 2561c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLmillibel volumeLevel = -((rand() & 0x7FFFFFFF) % ((SL_MILLIBEL_MIN + 1) / 10)); 2574b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten printf("volume %d\n", volumeLevel); 2581c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*p->mPlayerVolume)->SetVolumeLevel(p->mPlayerVolume, volumeLevel); 2591c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 2601c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*p->mPlayerVolume)->EnableStereoPosition(p->mPlayerVolume, SL_BOOLEAN_TRUE); 2611c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 2621c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten SLpermille stereoPosition = ((rand() & 0x7FFFFFFF) % 2001) - 1000; 2634b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten printf("position %d\n", stereoPosition); 2641c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*p->mPlayerVolume)->SetStereoPosition(p->mPlayerVolume, stereoPosition); 2651c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 2661c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten if (state != SL_PLAYSTATE_STOPPED) { 2671c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*p->mPlayerSeek)->SetPosition(p->mPlayerSeek, 0, SL_SEEKMODE_FAST); 2681c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 2691c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten } 2701c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten result = (*p->mPlayerPlay)->SetPlayState(p->mPlayerPlay, SL_PLAYSTATE_PLAYING); 2711c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten check(result); 2721c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten } 2730a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten if ((playTimeInMilliseconds > 0) && ((playTimeInMilliseconds -= delay) < 0)) 2740a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten break; 2751c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten } 2761c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 2770a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten for (i = 0; i < numPlayers; ++i) { 2780a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten SLObjectItf playerObject = players[i].mPlayerObject; 2790a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten (*playerObject)->Destroy(playerObject); 2800a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten } 2810a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten (*mixObject)->Destroy(mixObject); 2820a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten (*engineObject)->Destroy(engineObject); 2831c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten 2840a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten return EXIT_SUCCESS; 2851c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten} 286