19e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten/*
29e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
39e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten *
49e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
59e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten * you may not use this file except in compliance with the License.
69e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten * You may obtain a copy of the License at
79e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten *
89e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
99e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten *
109e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten * Unless required by applicable law or agreed to in writing, software
119e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
129e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten * See the License for the specific language governing permissions and
149e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten * limitations under the License.
159e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten */
169e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
179e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Demonstrate environmental reverb and preset reverb on an output mix and audio player
189e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
19c6853892c94800e72c0bd676d5d2136d48cea76eGlenn Kasten#include <SLES/OpenSLES.h>
209e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#include <assert.h>
210ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten#include <pthread.h>
229e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#include <string.h>
239e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#include <stdio.h>
249e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#include <stdlib.h>
25c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten#include <unistd.h>
269e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
270a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#define bool int
280a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#define false 0
290a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#define true 1
300a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten
319e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Table of I3DL2 named environmental reverb settings
329e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
339e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kastentypedef struct {
349e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    const char *mName;
359e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLEnvironmentalReverbSettings mSettings;
369e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten} Pair;
379e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
389e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#define _(name) {#name, SL_I3DL2_ENVIRONMENT_PRESET_##name},
399e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
409e60b0a390d780539459f41c2bf4a45a326a7b62Glenn KastenPair pairs[] = {
419e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(DEFAULT)
429e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(GENERIC)
439e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(PADDEDCELL)
449e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(ROOM)
459e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(BATHROOM)
469e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(LIVINGROOM)
479e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(STONEROOM)
489e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(AUDITORIUM)
499e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(CONCERTHALL)
509e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(CAVE)
519e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(ARENA)
529e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(HANGAR)
539e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(CARPETEDHALLWAY)
549e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(HALLWAY)
559e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(STONECORRIDOR)
569e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(ALLEY)
579e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(FOREST)
589e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(CITY)
599e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(MOUNTAINS)
609e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(QUARRY)
619e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(PLAIN)
629e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(PARKINGLOT)
639e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(SEWERPIPE)
649e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(UNDERWATER)
659e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(SMALLROOM)
669e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(MEDIUMROOM)
679e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(LARGEROOM)
689e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(MEDIUMHALL)
699e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(LARGEHALL)
709e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(PLATE)
719e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten};
729e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
7304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten// Parameters for preset reverb on output mix
7404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kastenbool outputMixPresetItfRequested = false;
7504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn KastenSLuint16 outputMixPresetNumber = ~0;
769e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
7704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten// Parameters for environmental reverb on output mix
7804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kastenbool outputMixEnvironmentalItfRequested = false;
7904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kastenchar *outputMixEnvironmentalName = NULL;
8004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn KastenSLEnvironmentalReverbSettings outputMixEnvironmentalSettings;
8104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten
8204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten// Parameters for preset reverb on audio player (not supported)
8304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kastenbool playerPresetItfRequested = false;
840a058cc3d720cdf3f0f8222472a862258482f34fGlenn KastenSLuint16 playerPresetNumber = ~0;
8504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten
8604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten// Parameters for environmental reverb on audio player (not supported)
8704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kastenbool playerEnvironmentalItfRequested = false;
8804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kastenchar *playerEnvironmentalName = NULL;
8904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn KastenSLEnvironmentalReverbSettings playerEnvironmentalSettings;
909e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
919e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Compare two environmental reverb settings structures.
929e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Returns true if the settings are identical, or false if they are different.
939e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
9404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kastenbool slesutCompareEnvironmentalReverbSettings(
959e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        const SLEnvironmentalReverbSettings *settings1,
969e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        const SLEnvironmentalReverbSettings *settings2)
979e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten{
989e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    return
999e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->roomLevel == settings2->roomLevel) &&
1009e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->roomHFLevel == settings2->roomHFLevel) &&
1019e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->decayTime == settings2->decayTime) &&
1029e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->decayHFRatio == settings2->decayHFRatio) &&
1039e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->reflectionsLevel == settings2->reflectionsLevel) &&
1049e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->reflectionsDelay == settings2->reflectionsDelay) &&
1059e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->reverbLevel == settings2->reverbLevel) &&
1069e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->reverbDelay == settings2->reverbDelay) &&
1079e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->diffusion == settings2->diffusion) &&
1089e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->density == settings2->density);
1099e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten}
1109e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1119e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Print an environmental reverb settings structure.
1129e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
11361c8274a30ba403191b05d556d063fa5f309ea95Glenn Kastenvoid slesutPrintEnvironmentalReverbSettings(const SLEnvironmentalReverbSettings *settings)
1149e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten{
11504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    printf("roomLevel: %d\n", settings->roomLevel);
11604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    printf("roomHFLevel: %d\n", settings->roomHFLevel);
11758432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten    printf("decayTime: %d\n", settings->decayTime);
11804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    printf("decayHFRatio: %d\n", settings->decayHFRatio);
11904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    printf("reflectionsLevel: %d\n", settings->reflectionsLevel);
12058432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten    printf("reflectionsDelay: %d\n", settings->reflectionsDelay);
12104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    printf("reverbLevel: %d\n", settings->reverbLevel);
12258432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten    printf("reverbDelay: %d\n", settings->reverbDelay);
12304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    printf("diffusion: %d\n", settings->diffusion);
12404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    printf("density: %d\n", settings->density);
1259e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten}
1269e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1270a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten// Lookup environmental reverb settings by name
1280a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten
1290a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastenconst SLEnvironmentalReverbSettings *lookupEnvName(const char *name)
1300a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{
1310a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    unsigned j;
1320a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    for (j = 0; j < sizeof(pairs) / sizeof(pairs[0]); ++j) {
1330a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        if (!strcasecmp(name, pairs[j].mName)) {
1340a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            return &pairs[j].mSettings;
1350a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        }
1360a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    }
1370a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    return NULL;
1380a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten}
1390a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten
1400a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten// Print all available environmental reverb names
1410a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten
1420a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastenvoid printEnvNames(void)
1430a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten{
1440a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    unsigned j;
1450a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    bool needSpace = false;
1460a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    bool needNewline = false;
1470a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    unsigned lineLen = 0;
1480a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    for (j = 0; j < sizeof(pairs) / sizeof(pairs[0]); ++j) {
1490a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        const char *name = pairs[j].mName;
1500a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        unsigned nameLen = strlen(name);
1510a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        if (lineLen + (needSpace ? 1 : 0) + nameLen > 72) {
1520a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            putchar('\n');
1530a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            needSpace = false;
1540a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            needNewline = false;
1550a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            lineLen = 0;
1560a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        }
1570a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        if (needSpace) {
1580a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            putchar(' ');
1590a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            ++lineLen;
1600a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        }
1610a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        fputs(name, stdout);
1620a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        lineLen += nameLen;
1630a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        needSpace = true;
1640a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        needNewline = true;
1650a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    }
1660a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    if (needNewline) {
1670a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        putchar('\n');
1680a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    }
1690a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten}
1700a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten
1710ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten// These are extensions to OpenSL ES 1.0.1 values
1720ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten
1730ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten#define SL_PREFETCHSTATUS_UNKNOWN 0
1740ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten#define SL_PREFETCHSTATUS_ERROR   (-1)
1750ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten
1760ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten// Mutex and condition shared with main program to protect prefetch_status
1770ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten
1780ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kastenstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
1790ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kastenstatic pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
1800ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn KastenSLuint32 prefetch_status = SL_PREFETCHSTATUS_UNKNOWN;
1810ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten
1820ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten/* used to detect errors likely to have occured when the OpenSL ES framework fails to open
1830ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten * a resource, for instance because a file URI is invalid, or an HTTP server doesn't respond.
1840ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten */
1850ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten#define PREFETCHEVENT_ERROR_CANDIDATE \
1860ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE)
1870ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten
1880ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten// Prefetch status callback
1890ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten
1900ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kastenvoid prefetch_callback(SLPrefetchStatusItf caller, void *context, SLuint32 event)
1910ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten{
1920ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    SLresult result;
1930ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    assert(context == NULL);
1940ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    SLpermille level;
1950ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    result = (*caller)->GetFillLevel(caller, &level);
1960ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
1970ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    SLuint32 status;
1980ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    result = (*caller)->GetPrefetchStatus(caller, &status);
1990ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
2000ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    SLuint32 new_prefetch_status;
2010ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    if ((event & PREFETCHEVENT_ERROR_CANDIDATE) == PREFETCHEVENT_ERROR_CANDIDATE
2020ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten            && level == 0 && status == SL_PREFETCHSTATUS_UNDERFLOW) {
2030ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        new_prefetch_status = SL_PREFETCHSTATUS_ERROR;
2040ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    } else if (event == SL_PREFETCHEVENT_STATUSCHANGE &&
2050ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten            status == SL_PREFETCHSTATUS_SUFFICIENTDATA) {
2060ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        new_prefetch_status = status;
2070ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    } else {
2080ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        return;
2090ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    }
2100ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    int ok;
2110ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    ok = pthread_mutex_lock(&mutex);
2120ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    assert(ok == 0);
2130ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    prefetch_status = new_prefetch_status;
2140ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    ok = pthread_cond_signal(&cond);
2150ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    assert(ok == 0);
2160ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    ok = pthread_mutex_unlock(&mutex);
2170ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    assert(ok == 0);
2180ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten}
2190ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten
2209e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Main program
2219e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
2229e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kastenint main(int argc, char **argv)
2239e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten{
2249e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLresult result;
2250ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    bool loop = false;
2269e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
2279e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // process command line parameters
2289e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    char *prog = argv[0];
2299e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    int i;
2309e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    for (i = 1; i < argc; ++i) {
2319e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        char *arg = argv[i];
2329e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        if (arg[0] != '-')
2339e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            break;
23404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        bool bad = false;   // whether the option string is invalid
23504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        if (!strncmp(arg, "--mix-preset", 12)) {
23604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if ('\0' == arg[12]) {
23704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                outputMixPresetItfRequested = true;
23804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else if ('=' == arg[12]) {
23904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                outputMixPresetNumber = atoi(&arg[13]);
24004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                outputMixPresetItfRequested = true;
24104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else {
24204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                bad = true;
24304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
24404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        } else if (!strncmp(arg, "--mix-name", 10)) {
24504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if ('\0' == arg[10]) {
24604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                outputMixEnvironmentalItfRequested = true;
24704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else if ('=' == arg[10]) {
24804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                outputMixEnvironmentalName = &arg[11];
24904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                outputMixEnvironmentalItfRequested = true;
25004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else {
25104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                bad = true;
25204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
25304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        } else if (!strncmp(arg, "--player-preset", 15)) {
25404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if ('\0' == arg[15]) {
25504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                playerPresetItfRequested = true;
25604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else if ('=' == arg[15]) {
25704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                playerPresetNumber = atoi(&arg[16]);
25804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                playerPresetItfRequested = true;
25904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else {
26004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                bad = true;
26104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
26204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        } else if (!strncmp(arg, "--player-name", 13)) {
26304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if ('\0' == arg[13]) {
26404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                playerEnvironmentalItfRequested = true;
26504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else if ('=' == arg[13]) {
26604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                playerEnvironmentalName = &arg[14];
26704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                playerEnvironmentalItfRequested = true;
26804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else {
26904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                bad = true;
27004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
2710ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        } else if (!strcmp(arg, "--loop")) {
2720ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten            loop = true;
2739e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        } else {
27404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            bad = true;
27504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        }
27604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        if (bad) {
2779e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            fprintf(stderr, "%s: unknown option %s ignored\n", prog, arg);
2789e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        }
2799e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
2809e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (argc - i != 1) {
2810a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        fprintf(stderr, "usage: %s --mix-preset=# --mix-name=I3DL2 --player-preset=# "
2820ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten                "--player-name=I3DL2 --loop filename\n", prog);
28361c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten        return EXIT_FAILURE;
2849e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
2859e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    char *pathname = argv[i];
2869e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
2870a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    const SLEnvironmentalReverbSettings *envSettings;
28804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (NULL != outputMixEnvironmentalName) {
28904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        envSettings = lookupEnvName(outputMixEnvironmentalName);
2900a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        if (NULL == envSettings) {
29104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            fprintf(stderr, "%s: output mix environmental reverb name %s not found, "
29204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    "available names are:\n", prog, outputMixEnvironmentalName);
2930a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            printEnvNames();
2940a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            return EXIT_FAILURE;
2959e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        }
29604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        outputMixEnvironmentalSettings = *envSettings;
2970a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    }
29804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (NULL != playerEnvironmentalName) {
29904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        envSettings = lookupEnvName(playerEnvironmentalName);
3000a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        if (NULL == envSettings) {
3010a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            fprintf(stderr, "%s: player environmental reverb name %s not found, "
30204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    "available names are:\n", prog, playerEnvironmentalName);
3030a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            printEnvNames();
3040a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            return EXIT_FAILURE;
30561c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten        }
30604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        playerEnvironmentalSettings = *envSettings;
3079e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
3089e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
3099e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // create engine
3109e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLObjectItf engineObject;
3119e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
3129e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
3139e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
3149e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
3159e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLEngineItf engineEngine;
3169e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
3179e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
3189e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
3199e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // create output mix
3209e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLInterfaceID mix_ids[2];
3219e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLboolean mix_req[2];
3229e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLuint32 count = 0;
32304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (outputMixPresetItfRequested) {
3249e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        mix_req[count] = SL_BOOLEAN_TRUE;
3259e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        mix_ids[count++] = SL_IID_PRESETREVERB;
3269e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
32704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (outputMixEnvironmentalItfRequested) {
3289e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        mix_req[count] = SL_BOOLEAN_TRUE;
3299e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        mix_ids[count++] = SL_IID_ENVIRONMENTALREVERB;
3309e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
3319e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLObjectItf mixObject;
3329e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, count, mix_ids, mix_req);
3339e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
3349e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE);
3359e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
3369e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
3379e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // configure preset reverb on output mix
33804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    SLPresetReverbItf outputMixPresetReverb;
33904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (outputMixPresetItfRequested) {
34004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        result = (*mixObject)->GetInterface(mixObject, SL_IID_PRESETREVERB, &outputMixPresetReverb);
3419e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
3429e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        SLuint16 getPresetReverb = 12345;
34304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        result = (*outputMixPresetReverb)->GetPreset(outputMixPresetReverb, &getPresetReverb);
3449e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
34504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        printf("Output mix default preset reverb number = %u\n", getPresetReverb);
34604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        if (outputMixPresetNumber != ((SLuint16) ~0)) {
34704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            result = (*outputMixPresetReverb)->SetPreset(outputMixPresetReverb,
34804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    outputMixPresetNumber);
34904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if (SL_RESULT_SUCCESS == result) {
35004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*outputMixPresetReverb)->GetPreset(outputMixPresetReverb,
35104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        &getPresetReverb);
35204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
35304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(getPresetReverb == outputMixPresetNumber);
35404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("Output mix preset reverb successfully changed to %u\n",
35504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        outputMixPresetNumber);
35604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else {
35758432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten                printf("Unable to set output mix preset reverb to %u, result=%u\n",
35804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        outputMixPresetNumber, result);
35904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
36004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        }
3619e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
3629e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
3639e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // configure environmental reverb on output mix
36404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    SLEnvironmentalReverbItf outputMixEnvironmentalReverb;
36504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (outputMixEnvironmentalItfRequested) {
3669e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*mixObject)->GetInterface(mixObject, SL_IID_ENVIRONMENTALREVERB,
36704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                &outputMixEnvironmentalReverb);
3689e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
3699e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        SLEnvironmentalReverbSettings getSettings;
37004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        result = (*outputMixEnvironmentalReverb)->GetEnvironmentalReverbProperties(
37104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                outputMixEnvironmentalReverb, &getSettings);
3729e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
3739e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("Output mix default environmental reverb settings\n");
3749e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("------------------------------------------------\n");
3759e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        slesutPrintEnvironmentalReverbSettings(&getSettings);
3769e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("\n");
37704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        if (outputMixEnvironmentalName != NULL) {
37804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            result = (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(
37904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    outputMixEnvironmentalReverb, &outputMixEnvironmentalSettings);
38004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            assert(SL_RESULT_SUCCESS == result);
38104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("Output mix new environmental reverb settings\n");
38204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("--------------------------------------------\n");
38304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            slesutPrintEnvironmentalReverbSettings(&outputMixEnvironmentalSettings);
38404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("\n");
38504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            result = (*outputMixEnvironmentalReverb)->GetEnvironmentalReverbProperties(
38604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    outputMixEnvironmentalReverb, &getSettings);
38704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            assert(SL_RESULT_SUCCESS == result);
38804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("Output mix read environmental reverb settings\n");
38904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("--------------------------------------------\n");
39004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            slesutPrintEnvironmentalReverbSettings(&getSettings);
39104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("\n");
39204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if (!slesutCompareEnvironmentalReverbSettings(&getSettings,
39304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    &outputMixEnvironmentalSettings)) {
39404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("Warning: new and read are different; check details above\n");
39504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            } else {
39604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("New and read match, life is good\n");
39704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
39861c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten        }
3999e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
4009e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
4019e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // create audio player
402e629abc58c2acadc7487ea71c1e063f8f8989199Glenn Kasten    SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, (SLchar *) pathname};
4039e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
4049e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLDataSource audioSrc = {&locURI, &dfMIME};
4059e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, mixObject};
4069e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLDataSink audioSnk = {&locOutputMix, NULL};
4070ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    SLInterfaceID player_ids[5];
4080ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    SLboolean player_req[5];
4099e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    count = 0;
41004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (playerPresetItfRequested) {
4119e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_req[count] = SL_BOOLEAN_TRUE;
4129e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_ids[count++] = SL_IID_PRESETREVERB;
4139e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
41404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (playerEnvironmentalItfRequested) {
4159e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_req[count] = SL_BOOLEAN_TRUE;
4169e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_ids[count++] = SL_IID_ENVIRONMENTALREVERB;
4179e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
41804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (outputMixPresetItfRequested || outputMixEnvironmentalItfRequested) {
4199e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_req[count] = SL_BOOLEAN_TRUE;
4209e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_ids[count++] = SL_IID_EFFECTSEND;
4219e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
4220ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    if (loop) {
4230ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        player_req[count] = SL_BOOLEAN_TRUE;
4240ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        player_ids[count++] = SL_IID_SEEK;
4250ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    }
42661c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    player_req[count] = SL_BOOLEAN_TRUE;
42761c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    player_ids[count++] = SL_IID_PREFETCHSTATUS;
4289e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLObjectItf playerObject;
4299e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
4309e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        &audioSnk, count, player_ids, player_req);
4319e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
4329e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
43361c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    // realize audio player
43461c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
4359e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
4369e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
43761c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    // if reverb is on output mix (aux effect), then enable it for this player
43804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (outputMixPresetItfRequested || outputMixEnvironmentalItfRequested) {
4399e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        SLEffectSendItf playerEffectSend;
4409e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*playerObject)->GetInterface(playerObject, SL_IID_EFFECTSEND, &playerEffectSend);
4419e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
44204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        SLboolean enabled;
44304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        SLmillibel directLevel;
44404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        SLmillibel sendLevel;
44504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        if (outputMixPresetItfRequested) {
44604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            result = (*playerEffectSend)->IsEnabled(playerEffectSend, outputMixPresetReverb,
44704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    &enabled);
4489e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            assert(SL_RESULT_SUCCESS == result);
44904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("Output mix preset reverb: player effect send default enabled = %s\n",
45004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    enabled ? "true" : "false");
45104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            directLevel = 12345;
45204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            result = (*playerEffectSend)->GetDirectLevel(playerEffectSend, &directLevel);
4539e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            assert(SL_RESULT_SUCCESS == result);
45404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("Output mix preset reverb: player effect send default direct level = %d\n",
45504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    directLevel);
45604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            sendLevel = 12345;
45704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            result = (*playerEffectSend)->GetSendLevel(playerEffectSend, outputMixPresetReverb,
45804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    &sendLevel);
45904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            assert(SL_RESULT_SUCCESS == result);
46004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("Output mix preset reverb: player effect send default send level = %d\n",
46104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    sendLevel);
46204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if (outputMixPresetNumber != ((SLuint16) ~0)) {
46304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->EnableEffectSend(playerEffectSend,
46404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        outputMixPresetReverb, SL_BOOLEAN_TRUE, (SLmillibel) 0);
46504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
46604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->IsEnabled(playerEffectSend, outputMixPresetReverb,
46704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        &enabled);
46804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
46904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                directLevel = 12345;
47004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->GetDirectLevel(playerEffectSend, &directLevel);
47104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
47204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                sendLevel = 12345;
47304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->GetSendLevel(playerEffectSend, outputMixPresetReverb,
47404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        &sendLevel);
47504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
47604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("Output mix preset reverb: player effect send new enabled = %s, direct level"
47704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    " = %d, send level = %d\n", enabled ? "true" : "false", directLevel, sendLevel);
47804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
47904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        }
48004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        if (outputMixEnvironmentalItfRequested) {
48104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if (outputMixEnvironmentalName != NULL) {
48204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->IsEnabled(playerEffectSend,
48304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        outputMixEnvironmentalReverb, &enabled);
48404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
48504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("Output mix environmental reverb: player effect send default enabled = %s\n",
48604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        enabled ? "true" : "false");
48704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                directLevel = 12345;
48804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->GetDirectLevel(playerEffectSend, &directLevel);
48904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
49004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("Output mix environmental reverb: player effect send default direct level"
49104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        " = %d\n", directLevel);
49204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                sendLevel = 12345;
49304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->GetSendLevel(playerEffectSend,
49404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        outputMixEnvironmentalReverb, &sendLevel);
49504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
49604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("Output mix environmental reverb: player effect send default send level"
49704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        " = %d\n", sendLevel);
49804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->EnableEffectSend(playerEffectSend,
49904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        outputMixEnvironmentalReverb, SL_BOOLEAN_TRUE, (SLmillibel) 0);
50004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
50104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->IsEnabled(playerEffectSend,
50204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        outputMixEnvironmentalReverb, &enabled);
50304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
50404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                directLevel = 12345;
50504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->GetDirectLevel(playerEffectSend, &directLevel);
50604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
50704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                sendLevel = 12345;
50804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEffectSend)->GetSendLevel(playerEffectSend,
50904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        outputMixEnvironmentalReverb, &sendLevel);
51004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
51104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("Output mix environmental reverb: player effect send new enabled = %s, "
51204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    "direct level = %d, send level = %d\n", enabled ? "true" : "false",
51304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    directLevel, sendLevel);
51404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
5159e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        }
5169e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
5179e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
5180a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    // configure preset reverb on player
5190a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    SLPresetReverbItf playerPresetReverb;
52004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (playerPresetItfRequested) {
5210a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        result = (*playerObject)->GetInterface(playerObject, SL_IID_PRESETREVERB,
5220a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten                &playerPresetReverb);
5230a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        assert(SL_RESULT_SUCCESS == result);
5240a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        SLuint16 getPresetReverb = 12345;
5250a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        result = (*playerPresetReverb)->GetPreset(playerPresetReverb, &getPresetReverb);
5260a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        if (SL_RESULT_SUCCESS == result) {
52704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("Player default preset reverb %u\n", getPresetReverb);
52804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if (playerPresetNumber != ((SLuint16) ~0)) {
52904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerPresetReverb)->SetPreset(playerPresetReverb, playerPresetNumber);
53004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                if (SL_RESULT_SUCCESS == result) {
53104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    result = (*playerPresetReverb)->GetPreset(playerPresetReverb, &getPresetReverb);
53204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    assert(SL_RESULT_SUCCESS == result);
53304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    assert(getPresetReverb == playerPresetNumber);
53404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    printf("Player preset reverb successfully changed to %u\n", playerPresetNumber);
53504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                } else {
53658432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten                    printf("Unable to set player preset reverb to %u, result=%u\n",
53704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                            playerPresetNumber, result);
53804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                }
53904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
54004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        } else {
54158432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten            printf("Unable to get player default preset reverb, result=%u\n", result);
54204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        }
5430a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    }
5440a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten
5450a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    // configure environmental reverb on player
5460a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    SLEnvironmentalReverbItf playerEnvironmentalReverb;
54704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten    if (playerEnvironmentalItfRequested) {
5480a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        result = (*playerObject)->GetInterface(playerObject, SL_IID_ENVIRONMENTALREVERB,
5490a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten                &playerEnvironmentalReverb);
5500a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        assert(SL_RESULT_SUCCESS == result);
5510a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        SLEnvironmentalReverbSettings getSettings;
5520a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        memset(&getSettings, 0, sizeof(getSettings));
5530a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        result = (*playerEnvironmentalReverb)->GetEnvironmentalReverbProperties(
5540a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten                playerEnvironmentalReverb, &getSettings);
55504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten        if (SL_RESULT_SUCCESS == result) {
55604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("Player default environmental reverb settings\n");
55704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("--------------------------------------------\n");
55804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            slesutPrintEnvironmentalReverbSettings(&getSettings);
55904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            printf("\n");
56004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            if (playerEnvironmentalName != NULL) {
56104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEnvironmentalReverb)->SetEnvironmentalReverbProperties(
56204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        playerEnvironmentalReverb, &playerEnvironmentalSettings);
56304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
56404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("Player new environmental reverb settings\n");
56504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("----------------------------------------\n");
56604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                slesutPrintEnvironmentalReverbSettings(&playerEnvironmentalSettings);
56704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("\n");
56804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                result = (*playerEnvironmentalReverb)->GetEnvironmentalReverbProperties(
56904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        playerEnvironmentalReverb, &getSettings);
57004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                assert(SL_RESULT_SUCCESS == result);
57104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("Player read environmental reverb settings\n");
57204186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("-----------------------------------------\n");
57304186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                slesutPrintEnvironmentalReverbSettings(&getSettings);
57404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                printf("\n");
57504186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                if (!slesutCompareEnvironmentalReverbSettings(&getSettings,
57604186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                        &playerEnvironmentalSettings)) {
57704186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    printf("Warning: new and read are different; check details above\n");
57804186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                } else {
57904186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    printf("New and read match, life is good\n");
58004186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                }
58104186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten            }
5820a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        } else {
58358432eb9cea995c69b4f905e68b38c1b8216edebGlenn Kasten            printf("Unable to get player default environmental reverb properties, result=%u\n",
58404186529e0bcdfa543aa67013fb6d44bf4a1fbbeGlenn Kasten                    result);
5850a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten        }
5860a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    }
5870a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten
58861c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    // get the play interface
58961c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    SLPlayItf playerPlay;
59061c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
59161c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
59261c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten
59361c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    // get the prefetch status interface
59461c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    SLPrefetchStatusItf playerPrefetchStatus;
5950a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten    result = (*playerObject)->GetInterface(playerObject, SL_IID_PREFETCHSTATUS,
5960a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten            &playerPrefetchStatus);
59761c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
59861c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten
5990ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    // enable prefetch status callbacks
6000ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    result = (*playerPrefetchStatus)->RegisterCallback(playerPrefetchStatus, prefetch_callback,
6010ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten            NULL);
6020ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
6030ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    result = (*playerPrefetchStatus)->SetCallbackEventsMask(playerPrefetchStatus,
6040ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten            SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
6050ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
6060ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten
6078653e8eeb955814f49b3b9548e0b6d2931b0221bGlenn Kasten    // set play state to paused to enable pre-fetch so we can get a more reliable duration
6088653e8eeb955814f49b3b9548e0b6d2931b0221bGlenn Kasten    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED);
6098653e8eeb955814f49b3b9548e0b6d2931b0221bGlenn Kasten    assert(SL_RESULT_SUCCESS == result);
6108653e8eeb955814f49b3b9548e0b6d2931b0221bGlenn Kasten
6110ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    // wait for prefetch status callback to indicate either sufficient data or error
6120ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    pthread_mutex_lock(&mutex);
6130ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    while (prefetch_status == SL_PREFETCHSTATUS_UNKNOWN) {
6140ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        pthread_cond_wait(&cond, &mutex);
61561c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    }
6160ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    pthread_mutex_unlock(&mutex);
6170ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    if (prefetch_status == SL_PREFETCHSTATUS_ERROR) {
6180ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        fprintf(stderr, "Error during prefetch, exiting\n");
61961c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten        goto destroyRes;
62061c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    }
62161c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten
62261c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    // get the duration
62361c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    SLmillisecond duration;
62461c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    result = (*playerPlay)->GetDuration(playerPlay, &duration);
62561c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
62661c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    if (SL_TIME_UNKNOWN == duration) {
62761c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten        printf("duration: unknown\n");
62861c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    } else {
62961c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten        printf("duration: %.1f seconds\n", duration / 1000.0);
63061c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    }
63161c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten
6320ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    // enable looping
6330ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    if (loop) {
6340ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        SLSeekItf playerSeek;
6350ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        result = (*playerObject)->GetInterface(playerObject, SL_IID_SEEK, &playerSeek);
6360ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
6370ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        result = (*playerSeek)->SetLoop(playerSeek, SL_BOOLEAN_TRUE, (SLmillisecond) 0,
6380ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten                SL_TIME_UNKNOWN);
6390ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
6400ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten    }
6410ab75a12c246f871771dc37b4ac0233cf7ee3f47Glenn Kasten
6429e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // start audio playing
6439e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
6449e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
6459e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
6469e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // wait for audio to finish playing
6479e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLuint32 state;
6489e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    for (;;) {
6499e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*playerPlay)->GetPlayState(playerPlay, &state);
6509e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
6519e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        if (SL_PLAYSTATE_PLAYING != state)
6529e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            break;
65361c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten        usleep(1000000);
6549e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten     }
6559e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_PLAYSTATE_PAUSED == state);
6569e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
65761c8274a30ba403191b05d556d063fa5f309ea95Glenn KastendestroyRes:
65861c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    // cleanup objects
65961c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    (*playerObject)->Destroy(playerObject);
66061c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    (*mixObject)->Destroy(mixObject);
66161c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten    (*engineObject)->Destroy(engineObject);
66261c8274a30ba403191b05d556d063fa5f309ea95Glenn Kasten
6639e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    return EXIT_SUCCESS;
6649e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten}
665