reverb.c revision e629abc58c2acadc7487ea71c1e063f8f8989199
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
199e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#include "SLES/OpenSLES.h"
209e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#include <assert.h>
219e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#include <string.h>
229e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#include <stdio.h>
239e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#include <stdlib.h>
24c2303eb5497c488db786dcb2b8514db229452536Glenn Kasten#include <unistd.h>
259e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
269e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Table of I3DL2 named environmental reverb settings
279e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
289e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kastentypedef struct {
299e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    const char *mName;
309e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLEnvironmentalReverbSettings mSettings;
319e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten} Pair;
329e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
339e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#define _(name) {#name, SL_I3DL2_ENVIRONMENT_PRESET_##name},
349e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
359e60b0a390d780539459f41c2bf4a45a326a7b62Glenn KastenPair pairs[] = {
369e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(DEFAULT)
379e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(GENERIC)
389e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(PADDEDCELL)
399e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(ROOM)
409e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(BATHROOM)
419e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(LIVINGROOM)
429e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(STONEROOM)
439e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(AUDITORIUM)
449e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(CONCERTHALL)
459e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(CAVE)
469e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(ARENA)
479e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(HANGAR)
489e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(CARPETEDHALLWAY)
499e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(HALLWAY)
509e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(STONECORRIDOR)
519e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(ALLEY)
529e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(FOREST)
539e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(CITY)
549e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(MOUNTAINS)
559e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(QUARRY)
569e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(PLAIN)
579e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(PARKINGLOT)
589e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(SEWERPIPE)
599e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(UNDERWATER)
609e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(SMALLROOM)
619e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(MEDIUMROOM)
629e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(LARGEROOM)
639e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(MEDIUMHALL)
649e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(LARGEHALL)
659e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    _(PLATE)
669e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten};
679e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
689e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Reverb parameters for output mix
699e60b0a390d780539459f41c2bf4a45a326a7b62Glenn KastenSLuint16 mixPresetNumber = ~0;
709e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kastenchar *mixEnvName = NULL;
719e60b0a390d780539459f41c2bf4a45a326a7b62Glenn KastenSLEnvironmentalReverbSettings mixEnvSettings;
729e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
739e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Reverb parameters for audio player
749e60b0a390d780539459f41c2bf4a45a326a7b62Glenn KastenSLuint16 playerPreset = ~0;
759e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kastenchar *playerName = NULL;
769e60b0a390d780539459f41c2bf4a45a326a7b62Glenn KastenSLEnvironmentalReverbSettings playerSettings;
779e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
789e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Compare two environmental reverb settings structures.
799e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Returns true if the settings are identical, or false if they are different.
809e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
819e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten#define bool int
829e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kastenbool slesutCompareEnvronmentalReverbSettings(
839e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        const SLEnvironmentalReverbSettings *settings1,
849e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        const SLEnvironmentalReverbSettings *settings2)
859e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten{
869e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    return
879e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->roomLevel == settings2->roomLevel) &&
889e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->roomHFLevel == settings2->roomHFLevel) &&
899e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->decayTime == settings2->decayTime) &&
909e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->decayHFRatio == settings2->decayHFRatio) &&
919e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->reflectionsLevel == settings2->reflectionsLevel) &&
929e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->reflectionsDelay == settings2->reflectionsDelay) &&
939e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->reverbLevel == settings2->reverbLevel) &&
949e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->reverbDelay == settings2->reverbDelay) &&
959e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->diffusion == settings2->diffusion) &&
969e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        (settings1->density == settings2->density);
979e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten}
989e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
999e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Print an environmental reverb settings structure.
1009e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1019e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kastenvoid slesutPrintEnvironmentalReverbSettings( const SLEnvironmentalReverbSettings *settings)
1029e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten{
1039e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("roomLevel: %u\n", settings->roomLevel);
1049e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("roomHFLevel: %u\n", settings->roomHFLevel);
1059e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("decayTime: %lu\n", settings->decayTime);
1069e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("decayHFRatio: %u\n", settings->decayHFRatio);
1079e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("reflectionsLevel: %u\n", settings->reflectionsLevel);
1089e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("reflectionsDelay: %lu\n", settings->reflectionsDelay);
1099e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("reverbLevel: %u\n", settings->reverbLevel);
1109e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("reverbDelay: %lu\n", settings->reverbDelay);
1119e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("diffusion: %u\n", settings->diffusion);
1129e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    printf("density: %u\n", settings->density);
1139e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten}
1149e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1159e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten// Main program
1169e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1179e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kastenint main(int argc, char **argv)
1189e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten{
1199e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLresult result;
1209e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1219e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // process command line parameters
1229e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    char *prog = argv[0];
1239e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    int i;
1249e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    for (i = 1; i < argc; ++i) {
1259e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        char *arg = argv[i];
1269e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        if (arg[0] != '-')
1279e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            break;
1289e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        if (!strncmp(arg, "--mix-preset=", 13)) {
1299e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            mixPresetNumber = atoi(&arg[13]);
1309e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        } else if (!strncmp(arg, "--mix-name=", 11)) {
1319e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            mixEnvName = &arg[11];
1329e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        } else {
1339e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            fprintf(stderr, "%s: unknown option %s ignored\n", prog, arg);
1349e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        }
1359e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
1369e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (argc - i != 1) {
1379e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        fprintf(stderr, "usage: %s --mix-preset=# --mix-name=name filename\n", prog);
1389e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        exit(EXIT_FAILURE);
1399e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
1409e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    char *pathname = argv[i];
1419e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1429e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (NULL != mixEnvName) {
1439e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        unsigned j;
1449e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        for (j = 0; j < sizeof(pairs) / sizeof(pairs[0]); ++j) {
1459e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            //printf("comparing %s %s\n", mixEnvName, pairs[j].mName);
1469e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            if (!strcasecmp(mixEnvName, pairs[j].mName)) {
1479e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten                mixEnvSettings = pairs[j].mSettings;
1489e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten                goto found;
1499e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            }
1509e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        }
1519e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        fprintf(stderr, "%s: reverb name %s not found\n", prog, mixEnvName);
1529e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        exit(EXIT_FAILURE);
1539e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kastenfound:
1549e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("Using reverb name %s\n", mixEnvName);
1559e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
1569e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1579e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // create engine
1589e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLObjectItf engineObject;
1599e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
1609e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
1619e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
1629e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
1639e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLEngineItf engineEngine;
1649e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
1659e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
1669e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1679e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // create output mix
1689e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLInterfaceID mix_ids[2];
1699e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLboolean mix_req[2];
1709e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLuint32 count = 0;
1719e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (mixPresetNumber != ((SLuint16) ~0)) {
1729e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        mix_req[count] = SL_BOOLEAN_TRUE;
1739e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        mix_ids[count++] = SL_IID_PRESETREVERB;
1749e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
1759e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (mixEnvName != NULL) {
1769e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        mix_req[count] = SL_BOOLEAN_TRUE;
1779e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        mix_ids[count++] = SL_IID_ENVIRONMENTALREVERB;
1789e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
1799e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLObjectItf mixObject;
1809e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, count, mix_ids, mix_req);
1819e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
1829e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE);
1839e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
1849e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
1859e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // configure preset reverb on output mix
1869e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLPresetReverbItf mixPresetReverb;
1879e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (mixPresetNumber != ((SLuint16) ~0)) {
1889e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*mixObject)->GetInterface(mixObject, SL_IID_PRESETREVERB, &mixPresetReverb);
1899e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
1909e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        SLuint16 getPresetReverb = 12345;
1919e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*mixPresetReverb)->GetPreset(mixPresetReverb, &getPresetReverb);
1929e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
1939e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("Output mix default preset reverb %u\n", getPresetReverb);
1949e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*mixPresetReverb)->SetPreset(mixPresetReverb, mixPresetNumber);
1959e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        if (SL_RESULT_SUCCESS == result) {
1969e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            result = (*mixPresetReverb)->GetPreset(mixPresetReverb, &getPresetReverb);
1979e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            assert(SL_RESULT_SUCCESS == result);
1989e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            assert(getPresetReverb == mixPresetNumber);
1999e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            printf("output mix preset reverb successfully changed to %u\n", mixPresetNumber);
2009e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        } else
2019e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            printf("Unable to set preset reverb to %u, result=%lu\n", mixPresetNumber, result);
2029e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
2039e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
2049e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // configure environmental reverb on output mix
2059e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLEnvironmentalReverbItf mixEnvironmentalReverb;
2069e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (mixEnvName != NULL) {
2079e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*mixObject)->GetInterface(mixObject, SL_IID_ENVIRONMENTALREVERB,
2089e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten                &mixEnvironmentalReverb);
2099e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
2109e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        SLEnvironmentalReverbSettings getSettings;
2119e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*mixEnvironmentalReverb)->GetEnvironmentalReverbProperties(mixEnvironmentalReverb,
2129e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten                &getSettings);
2139e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
2149e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("Output mix default environmental reverb settings\n");
2159e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("------------------------------------------------\n");
2169e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        slesutPrintEnvironmentalReverbSettings(&getSettings);
2179e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("\n");
2189e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*mixEnvironmentalReverb)->SetEnvironmentalReverbProperties(mixEnvironmentalReverb,
2199e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten                &mixEnvSettings);
2209e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
2219e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("Output mix new environmental reverb settings\n");
2229e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("--------------------------------------------\n");
2239e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        slesutPrintEnvironmentalReverbSettings(&mixEnvSettings);
2249e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("\n");
2259e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*mixEnvironmentalReverb)->GetEnvironmentalReverbProperties(mixEnvironmentalReverb,
2269e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten                &getSettings);
2279e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
2289e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("Output mix read environmental reverb settings\n");
2299e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("--------------------------------------------\n");
2309e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        slesutPrintEnvironmentalReverbSettings(&getSettings);
2319e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("\n");
2329e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        // assert(slesutCompareEnvronmentalReverbSettings(&getSettings, &mixEnvSettings));
2339e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
2349e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
2359e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // create audio player
236e629abc58c2acadc7487ea71c1e063f8f8989199Glenn Kasten    SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, (SLchar *) pathname};
2379e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
2389e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLDataSource audioSrc = {&locURI, &dfMIME};
2399e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, mixObject};
2409e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLDataSink audioSnk = {&locOutputMix, NULL};
2419e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLInterfaceID player_ids[3];
2429e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLboolean player_req[3];
2439e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    count = 0;
2449e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (playerPreset != ((SLuint16) ~0)) {
2459e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_req[count] = SL_BOOLEAN_TRUE;
2469e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_ids[count++] = SL_IID_PRESETREVERB;
2479e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
2489e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (playerName != NULL) {
2499e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_req[count] = SL_BOOLEAN_TRUE;
2509e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_ids[count++] = SL_IID_ENVIRONMENTALREVERB;
2519e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
2529e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (mixPresetNumber != ((SLuint16) ~0) || mixEnvName != NULL) {
2539e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_req[count] = SL_BOOLEAN_TRUE;
2549e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        player_ids[count++] = SL_IID_EFFECTSEND;
2559e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
2569e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLObjectItf playerObject;
2579e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
2589e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        &audioSnk, count, player_ids, player_req);
2599e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
2609e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
2619e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLPlayItf playerPlay;
2629e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
2639e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
2649e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
2659e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // get duration
2669e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLmillisecond duration;
2679e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*playerPlay)->GetDuration(playerPlay, &duration);
2689e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
2699e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (SL_TIME_UNKNOWN == duration)
2709e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("first attempt at duration: unknown\n");
2719e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    else
2729e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("first attempt at duration: %.1f seconds\n", duration / 1000.0);
2739e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
2749e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // set play state to paused to enable pre-fetch so we can get a more reliable duration
2759e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED);
2769e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
2779e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    usleep(1000000);
2789e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*playerPlay)->GetDuration(playerPlay, &duration);
2799e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
2809e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (SL_TIME_UNKNOWN == duration)
2819e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("second attempt at duration: unknown\n");
2829e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    else
2839e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        printf("second attempt at duration: %.1f seconds\n", duration / 1000.0);
2849e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
2859e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // if reverb is on output mix (aux effect), then enable it
2869e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    if (mixPresetNumber != ((SLuint16) ~0) || mixEnvName != NULL) {
2879e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        SLEffectSendItf playerEffectSend;
2889e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*playerObject)->GetInterface(playerObject, SL_IID_EFFECTSEND, &playerEffectSend);
2899e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
2909e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        if (mixPresetNumber != ((SLuint16) ~0)) {
2919e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            result = (*playerEffectSend)->EnableEffectSend(playerEffectSend, mixPresetReverb,
2929e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten                    SL_BOOLEAN_TRUE, (SLmillibel) 0);
2939e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            assert(SL_RESULT_SUCCESS == result);
2949e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        }
2959e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        if (mixEnvName != NULL) {
2969e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            result = (*playerEffectSend)->EnableEffectSend(playerEffectSend, mixEnvironmentalReverb,
2979e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten                    SL_BOOLEAN_TRUE, (SLmillibel) 0);
2989e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            assert(SL_RESULT_SUCCESS == result);
2999e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        }
3009e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    }
3019e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
3029e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // start audio playing
3039e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
3049e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_RESULT_SUCCESS == result);
3059e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
3069e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    // wait for audio to finish playing
3079e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    SLuint32 state;
3089e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    for (;;) {
3099e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        result = (*playerPlay)->GetPlayState(playerPlay, &state);
3109e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
3119e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        if (SL_PLAYSTATE_PLAYING != state)
3129e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten            break;
3139e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten        usleep(5000000);
3149e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten     }
3159e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    assert(SL_PLAYSTATE_PAUSED == state);
3169e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten
3179e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten    return EXIT_SUCCESS;
3189e60b0a390d780539459f41c2bf4a45a326a7b62Glenn Kasten}
319