multiplay.c revision ed46c29d6a09112dbbf584c82953f63289596fd6
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
191c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#include "OpenSLES.h"
201c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#include <assert.h>
211c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#include <string.h>
221c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#include <stdlib.h>
231c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#include <stdio.h>
241c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
251c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Describes the state of one player
261c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
271c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastentypedef struct {
281c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLObjectItf mPlayerObject;
291c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLPlayItf mPlayerPlay;
301c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLSeekItf mPlayerSeek;
311c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLVolumeItf mPlayerVolume;
321c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLmillisecond mPlayerDuration;
331c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten} Player;
341c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
351c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Strings corresponding to result codes; FIXME should move to a common test library
361c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
371c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastenstatic const char *result_strings[] = {
381c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "SUCCESS",
391c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "PRECONDITIONS_VIOLATED",
401c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "PARAMETER_INVALID",
411c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "MEMORY_FAILURE",
421c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "RESOURCE_ERROR",
431c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "RESOURCE_LOST",
441c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "IO_ERROR",
451c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "BUFFER_INSUFFICIENT",
461c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "CONTENT_CORRUPTED",
471c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "CONTENT_UNSUPPORTED",
481c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "CONTENT_NOT_FOUND",
491c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "PERMISSION_DENIED",
501c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "FEATURE_UNSUPPORTED",
511c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "INTERNAL_ERROR",
521c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "UNKNOWN_ERROR",
531c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "OPERATION_ABORTED",
541c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    "CONTROL_LOST"
551c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten};
561c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
571c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Convert result to string; FIXME should move to common test library
581c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
591c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastenstatic const char *result_to_string(SLresult result)
601c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten{
611c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    static char buffer[32];
621c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    if ( /* result >= 0 && */ result < sizeof(result_strings) / sizeof(result_strings[0]))
631c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        return result_strings[result];
641c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    sprintf(buffer, "%d", result);
651c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    return buffer;
661c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten}
671c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
681c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Compare result against expected and exit suddenly if wrong
691c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
701c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastenvoid check2(SLresult result, int line)
711c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten{
721c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    if (SL_RESULT_SUCCESS != result) {
731c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        fprintf(stderr, "error %s at line %d\n", result_to_string(result), line);
741c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        exit(EXIT_FAILURE);
751c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    }
761c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten}
771c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
781c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Same as above but automatically adds the source code line number
791c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
801c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten#define check(result) check2(result, __LINE__)
811c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
821c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten// Main program
831c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
841c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kastenint main(int argc, char **argv)
851c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten{
861c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    int i;
871c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    const char *arg;
881c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    int numPlayers = 0;
891c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLmillibel mixVolumeLevel = 0;
901c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    for (i = 1; i < argc; ++i) {
911c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        arg = argv[i];
921c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        if (arg[0] != '-')
931c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            break;
941c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        if (!strncmp(arg, "-n", 2))
951c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            numPlayers = atoi(&arg[2]);
961c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        else if (!strncmp(arg, "-v", 2))
971c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            mixVolumeLevel = atoi(&arg[2]);
981c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        else
991c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            fprintf(stderr, "unknown option: %s\n", arg);
1001c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    }
1011c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    int numPathnames = argc - i;
1021c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    if (numPathnames <= 0) {
1031c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        fprintf(stderr, "usage: %s file.wav ...\n", argv[0]);
1041c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        return EXIT_FAILURE;
1051c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    }
1061c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    if (numPlayers <= 0)
1071c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        numPlayers = numPathnames;
1081c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    Player *players = (Player *) malloc(sizeof(Player) * numPlayers);
1091c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    assert(NULL != players);
1101c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    char **pathnames = &argv[i];
1111c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLresult result;
1121c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
1131c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    // engine
1141c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    const SLInterfaceID engine_ids[] = {SL_IID_ENGINE};
1151c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    const SLboolean engine_req[] = {SL_BOOLEAN_TRUE};
1161c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLObjectItf engineObject;
1171c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    result = slCreateEngine(&engineObject, 0, NULL, 1, engine_ids, engine_req);
1181c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    check(result);
1191c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
1201c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    check(result);
1211c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLEngineItf engineEngine;
1221c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
1231c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    check(result);
1241c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
1251c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    // mixer
1261c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    const SLInterfaceID mix_ids[] = {SL_IID_VOLUME};
1271c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    const SLboolean mix_req[] = {SL_BOOLEAN_TRUE};
1281c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLObjectItf mixObject;
1291c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, 1, mix_ids, mix_req);
1301c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    check(result);
1311c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE);
1321c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    check(result);
1331c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLVolumeItf mixVolume;
1341c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    result = (*mixObject)->GetInterface(mixObject, SL_IID_VOLUME, &mixVolume);
1351c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    check(result);
1361c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    SLmillibel mixVolumeLevelDefault;
1371c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    result = (*mixVolume)->GetVolumeLevel(mixVolume, &mixVolumeLevelDefault);
1381c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    check(result);
1391c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    printf("default mix volume level = %d\n", mixVolumeLevelDefault);
1401c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
1411c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    printf("numPathnames=%d\n", numPathnames);
1421c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    printf("numPlayers=%d\n", numPlayers);
1431c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    Player *p;
1441c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
1451c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    // create all the players
1461c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    for (i = 0; i < numPlayers; ++i) {
1471c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        const SLInterfaceID player_ids[] = {SL_IID_PLAY, SL_IID_VOLUME, SL_IID_SEEK};
1481c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        const SLboolean player_req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
1491c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        p = &players[i];
1501c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, (SLchar *) pathnames[i % numPathnames]};
1511c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
1521c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        SLDataSource audioSrc = {&locURI, &dfMIME};
1531c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, mixObject};
1541c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        SLDataSink audioSnk = {&locOutputMix, NULL};
155ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = (*engineEngine)->CreateAudioPlayer(engineEngine, &p->mPlayerObject, &audioSrc,
156ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            &audioSnk, 3, player_ids, player_req);
1571c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        check(result);
1581c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        result = (*p->mPlayerObject)->Realize(p->mPlayerObject, SL_BOOLEAN_FALSE);
1591c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        check(result);
1601c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_PLAY, &p->mPlayerPlay);
1611c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        check(result);
162ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_VOLUME,
163ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            &p->mPlayerVolume);
1641c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        check(result);
1651c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        result = (*p->mPlayerObject)->GetInterface(p->mPlayerObject, SL_IID_SEEK, &p->mPlayerSeek);
1661c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        check(result);
1671c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        result = (*p->mPlayerPlay)->GetDuration(p->mPlayerPlay, &p->mPlayerDuration);
1681c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        check(result);
1691c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        printf("player %d duration %d\n", i, p->mPlayerDuration);
1701c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    }
1711c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
1721c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    // now loop randomly doing things to the players
1731c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    for (;;) {
1741c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        SLmillisecond delay = 100 + (rand() & 1023);
1751c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        printf("sleep %u\n", delay);
1761c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        usleep(delay * 1000);
1771c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        i = (rand() & 0x7FFFFFFF) % numPlayers;
1781c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        printf("player %d ", i);
1791c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        p = &players[i];
1801c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        SLuint32 state;
1811c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        result = (*p->mPlayerPlay)->GetPlayState(p->mPlayerPlay, &state);
1821c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        check(result);
1831c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        printf("state = ");
1841c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        switch (state) {
1851c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        case SL_PLAYSTATE_STOPPED:
1861c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            printf("STOPPED");
1871c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            break;
1881c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        case SL_PLAYSTATE_PAUSED:
1891c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            printf("PAUSED");
1901c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            break;
1911c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        case SL_PLAYSTATE_PLAYING:
1921c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            printf("PLAYING");
1931c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            break;
1941c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        default:
1951c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            printf("%u", state);
1961c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            break;
1971c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        }
1981c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        if (state == SL_PLAYSTATE_STOPPED || state == SL_PLAYSTATE_PAUSED) {
1991c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            SLmillibel volumeLevel = -((rand() & 0x7FFFFFFF) % ((SL_MILLIBEL_MIN + 1) / 10));
2001c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            printf(", volume %d", volumeLevel);
2011c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            result = (*p->mPlayerVolume)->SetVolumeLevel(p->mPlayerVolume, volumeLevel);
2021c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            check(result);
2031c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            result = (*p->mPlayerVolume)->EnableStereoPosition(p->mPlayerVolume, SL_BOOLEAN_TRUE);
2041c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            check(result);
2051c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            SLpermille stereoPosition = ((rand() & 0x7FFFFFFF) % 2001) - 1000;
2061c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            printf(", position %d", stereoPosition);
2071c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            result = (*p->mPlayerVolume)->SetStereoPosition(p->mPlayerVolume, stereoPosition);
2081c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            check(result);
2091c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            if (state != SL_PLAYSTATE_STOPPED) {
2101c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten                result = (*p->mPlayerSeek)->SetPosition(p->mPlayerSeek, 0, SL_SEEKMODE_FAST);
2111c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten                check(result);
2121c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            }
2131c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            result = (*p->mPlayerPlay)->SetPlayState(p->mPlayerPlay, SL_PLAYSTATE_PLAYING);
2141c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten            check(result);
2151c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        }
2161c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten        printf("\n");
2171c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    }
2181c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
2191c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    // FIXME It would be interesting to end the test on some condition (timer, key pressed) so it
2201c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    // also exercises the destruction of the players, output mix and engine after this test has run.
2211c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten
2221c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten    // return EXIT_SUCCESS;
2231c1c16f5469b9ebb4943e2c5eb648f832e0a3c37Glenn Kasten}
224