Exemplo n.º 1
0
int main(int argc, char **argv)
{
    SLresult result;
    bool loop = false;

    // process command line parameters
    char *prog = argv[0];
    int i;
    for (i = 1; i < argc; ++i) {
        char *arg = argv[i];
        if (arg[0] != '-')
            break;
        bool bad = false;   // whether the option string is invalid
        if (!strncmp(arg, "--mix-preset", 12)) {
            if ('\0' == arg[12]) {
                outputMixPresetItfRequested = true;
            } else if ('=' == arg[12]) {
                outputMixPresetNumber = atoi(&arg[13]);
                outputMixPresetItfRequested = true;
            } else {
                bad = true;
            }
        } else if (!strncmp(arg, "--mix-name", 10)) {
            if ('\0' == arg[10]) {
                outputMixEnvironmentalItfRequested = true;
            } else if ('=' == arg[10]) {
                outputMixEnvironmentalName = &arg[11];
                outputMixEnvironmentalItfRequested = true;
            } else {
                bad = true;
            }
        } else if (!strncmp(arg, "--player-preset", 15)) {
            if ('\0' == arg[15]) {
                playerPresetItfRequested = true;
            } else if ('=' == arg[15]) {
                playerPresetNumber = atoi(&arg[16]);
                playerPresetItfRequested = true;
            } else {
                bad = true;
            }
        } else if (!strncmp(arg, "--player-name", 13)) {
            if ('\0' == arg[13]) {
                playerEnvironmentalItfRequested = true;
            } else if ('=' == arg[13]) {
                playerEnvironmentalName = &arg[14];
                playerEnvironmentalItfRequested = true;
            } else {
                bad = true;
            }
        } else if (!strcmp(arg, "--loop")) {
            loop = true;
        } else {
            bad = true;
        }
        if (bad) {
            fprintf(stderr, "%s: unknown option %s ignored\n", prog, arg);
        }
    }
    if (argc - i != 1) {
        fprintf(stderr, "usage: %s --mix-preset=# --mix-name=I3DL2 --player-preset=# "
                "--player-name=I3DL2 --loop filename\n", prog);
        return EXIT_FAILURE;
    }
    char *pathname = argv[i];

    const SLEnvironmentalReverbSettings *envSettings;
    if (NULL != outputMixEnvironmentalName) {
        envSettings = lookupEnvName(outputMixEnvironmentalName);
        if (NULL == envSettings) {
            fprintf(stderr, "%s: output mix environmental reverb name %s not found, "
                    "available names are:\n", prog, outputMixEnvironmentalName);
            printEnvNames();
            return EXIT_FAILURE;
        }
        outputMixEnvironmentalSettings = *envSettings;
    }
    if (NULL != playerEnvironmentalName) {
        envSettings = lookupEnvName(playerEnvironmentalName);
        if (NULL == envSettings) {
            fprintf(stderr, "%s: player environmental reverb name %s not found, "
                    "available names are:\n", prog, playerEnvironmentalName);
            printEnvNames();
            return EXIT_FAILURE;
        }
        playerEnvironmentalSettings = *envSettings;
    }

    // create engine
    SLObjectItf engineObject;
    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
    assert(SL_RESULT_SUCCESS == result);
    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
    assert(SL_RESULT_SUCCESS == result);
    SLEngineItf engineEngine;
    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
    assert(SL_RESULT_SUCCESS == result);

    // create output mix
    SLInterfaceID mix_ids[2];
    SLboolean mix_req[2];
    SLuint32 count = 0;
    if (outputMixPresetItfRequested) {
        mix_req[count] = SL_BOOLEAN_TRUE;
        mix_ids[count++] = SL_IID_PRESETREVERB;
    }
    if (outputMixEnvironmentalItfRequested) {
        mix_req[count] = SL_BOOLEAN_TRUE;
        mix_ids[count++] = SL_IID_ENVIRONMENTALREVERB;
    }
    SLObjectItf mixObject;
    result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, count, mix_ids, mix_req);
    assert(SL_RESULT_SUCCESS == result);
    result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE);
    assert(SL_RESULT_SUCCESS == result);

    // configure preset reverb on output mix
    SLPresetReverbItf outputMixPresetReverb;
    if (outputMixPresetItfRequested) {
        result = (*mixObject)->GetInterface(mixObject, SL_IID_PRESETREVERB, &outputMixPresetReverb);
        assert(SL_RESULT_SUCCESS == result);
        SLuint16 getPresetReverb = 12345;
        result = (*outputMixPresetReverb)->GetPreset(outputMixPresetReverb, &getPresetReverb);
        assert(SL_RESULT_SUCCESS == result);
        printf("Output mix default preset reverb number = %u\n", getPresetReverb);
        if (outputMixPresetNumber != ((SLuint16) ~0)) {
            result = (*outputMixPresetReverb)->SetPreset(outputMixPresetReverb,
                    outputMixPresetNumber);
            if (SL_RESULT_SUCCESS == result) {
                result = (*outputMixPresetReverb)->GetPreset(outputMixPresetReverb,
                        &getPresetReverb);
                assert(SL_RESULT_SUCCESS == result);
                assert(getPresetReverb == outputMixPresetNumber);
                printf("Output mix preset reverb successfully changed to %u\n",
                        outputMixPresetNumber);
            } else {
                printf("Unable to set output mix preset reverb to %u, result=%u\n",
                        outputMixPresetNumber, result);
            }
        }
    }

    // configure environmental reverb on output mix
    SLEnvironmentalReverbItf outputMixEnvironmentalReverb;
    if (outputMixEnvironmentalItfRequested) {
        result = (*mixObject)->GetInterface(mixObject, SL_IID_ENVIRONMENTALREVERB,
                &outputMixEnvironmentalReverb);
        assert(SL_RESULT_SUCCESS == result);
        SLEnvironmentalReverbSettings getSettings;
        result = (*outputMixEnvironmentalReverb)->GetEnvironmentalReverbProperties(
                outputMixEnvironmentalReverb, &getSettings);
        assert(SL_RESULT_SUCCESS == result);
        printf("Output mix default environmental reverb settings\n");
        printf("------------------------------------------------\n");
        slesutPrintEnvironmentalReverbSettings(&getSettings);
        printf("\n");
        if (outputMixEnvironmentalName != NULL) {
            result = (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(
                    outputMixEnvironmentalReverb, &outputMixEnvironmentalSettings);
            assert(SL_RESULT_SUCCESS == result);
            printf("Output mix new environmental reverb settings\n");
            printf("--------------------------------------------\n");
            slesutPrintEnvironmentalReverbSettings(&outputMixEnvironmentalSettings);
            printf("\n");
            result = (*outputMixEnvironmentalReverb)->GetEnvironmentalReverbProperties(
                    outputMixEnvironmentalReverb, &getSettings);
            assert(SL_RESULT_SUCCESS == result);
            printf("Output mix read environmental reverb settings\n");
            printf("--------------------------------------------\n");
            slesutPrintEnvironmentalReverbSettings(&getSettings);
            printf("\n");
            if (!slesutCompareEnvironmentalReverbSettings(&getSettings,
                    &outputMixEnvironmentalSettings)) {
                printf("Warning: new and read are different; check details above\n");
            } else {
                printf("New and read match, life is good\n");
            }
        }
    }

    // create audio player
    SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, (SLchar *) pathname};
    SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
    SLDataSource audioSrc = {&locURI, &dfMIME};
    SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, mixObject};
    SLDataSink audioSnk = {&locOutputMix, NULL};
    SLInterfaceID player_ids[5];
    SLboolean player_req[5];
    count = 0;
    if (playerPresetItfRequested) {
        player_req[count] = SL_BOOLEAN_TRUE;
        player_ids[count++] = SL_IID_PRESETREVERB;
    }
    if (playerEnvironmentalItfRequested) {
        player_req[count] = SL_BOOLEAN_TRUE;
        player_ids[count++] = SL_IID_ENVIRONMENTALREVERB;
    }
    if (outputMixPresetItfRequested || outputMixEnvironmentalItfRequested) {
        player_req[count] = SL_BOOLEAN_TRUE;
        player_ids[count++] = SL_IID_EFFECTSEND;
    }
    if (loop) {
        player_req[count] = SL_BOOLEAN_TRUE;
        player_ids[count++] = SL_IID_SEEK;
    }
    player_req[count] = SL_BOOLEAN_TRUE;
    player_ids[count++] = SL_IID_PREFETCHSTATUS;
    SLObjectItf playerObject;
    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
        &audioSnk, count, player_ids, player_req);
    assert(SL_RESULT_SUCCESS == result);

    // realize audio player
    result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
    assert(SL_RESULT_SUCCESS == result);

    // if reverb is on output mix (aux effect), then enable it for this player
    if (outputMixPresetItfRequested || outputMixEnvironmentalItfRequested) {
        SLEffectSendItf playerEffectSend;
        result = (*playerObject)->GetInterface(playerObject, SL_IID_EFFECTSEND, &playerEffectSend);
        assert(SL_RESULT_SUCCESS == result);
        SLboolean enabled;
        SLmillibel directLevel;
        SLmillibel sendLevel;
        if (outputMixPresetItfRequested) {
            result = (*playerEffectSend)->IsEnabled(playerEffectSend, outputMixPresetReverb,
                    &enabled);
            assert(SL_RESULT_SUCCESS == result);
            printf("Output mix preset reverb: player effect send default enabled = %s\n",
                    enabled ? "true" : "false");
            directLevel = 12345;
            result = (*playerEffectSend)->GetDirectLevel(playerEffectSend, &directLevel);
            assert(SL_RESULT_SUCCESS == result);
            printf("Output mix preset reverb: player effect send default direct level = %d\n",
                    directLevel);
            sendLevel = 12345;
            result = (*playerEffectSend)->GetSendLevel(playerEffectSend, outputMixPresetReverb,
                    &sendLevel);
            assert(SL_RESULT_SUCCESS == result);
            printf("Output mix preset reverb: player effect send default send level = %d\n",
                    sendLevel);
            if (outputMixPresetNumber != ((SLuint16) ~0)) {
                result = (*playerEffectSend)->EnableEffectSend(playerEffectSend,
                        outputMixPresetReverb, SL_BOOLEAN_TRUE, (SLmillibel) 0);
                assert(SL_RESULT_SUCCESS == result);
                result = (*playerEffectSend)->IsEnabled(playerEffectSend, outputMixPresetReverb,
                        &enabled);
                assert(SL_RESULT_SUCCESS == result);
                directLevel = 12345;
                result = (*playerEffectSend)->GetDirectLevel(playerEffectSend, &directLevel);
                assert(SL_RESULT_SUCCESS == result);
                sendLevel = 12345;
                result = (*playerEffectSend)->GetSendLevel(playerEffectSend, outputMixPresetReverb,
                        &sendLevel);
                assert(SL_RESULT_SUCCESS == result);
                printf("Output mix preset reverb: player effect send new enabled = %s, direct level"
                    " = %d, send level = %d\n", enabled ? "true" : "false", directLevel, sendLevel);
            }
        }
        if (outputMixEnvironmentalItfRequested) {
            if (outputMixEnvironmentalName != NULL) {
                result = (*playerEffectSend)->IsEnabled(playerEffectSend,
                        outputMixEnvironmentalReverb, &enabled);
                assert(SL_RESULT_SUCCESS == result);
                printf("Output mix environmental reverb: player effect send default enabled = %s\n",
                        enabled ? "true" : "false");
                directLevel = 12345;
                result = (*playerEffectSend)->GetDirectLevel(playerEffectSend, &directLevel);
                assert(SL_RESULT_SUCCESS == result);
                printf("Output mix environmental reverb: player effect send default direct level"
                        " = %d\n", directLevel);
                sendLevel = 12345;
                result = (*playerEffectSend)->GetSendLevel(playerEffectSend,
                        outputMixEnvironmentalReverb, &sendLevel);
                assert(SL_RESULT_SUCCESS == result);
                printf("Output mix environmental reverb: player effect send default send level"
                        " = %d\n", sendLevel);
                result = (*playerEffectSend)->EnableEffectSend(playerEffectSend,
                        outputMixEnvironmentalReverb, SL_BOOLEAN_TRUE, (SLmillibel) 0);
                assert(SL_RESULT_SUCCESS == result);
                result = (*playerEffectSend)->IsEnabled(playerEffectSend,
                        outputMixEnvironmentalReverb, &enabled);
                assert(SL_RESULT_SUCCESS == result);
                directLevel = 12345;
                result = (*playerEffectSend)->GetDirectLevel(playerEffectSend, &directLevel);
                assert(SL_RESULT_SUCCESS == result);
                sendLevel = 12345;
                result = (*playerEffectSend)->GetSendLevel(playerEffectSend,
                        outputMixEnvironmentalReverb, &sendLevel);
                assert(SL_RESULT_SUCCESS == result);
                printf("Output mix environmental reverb: player effect send new enabled = %s, "
                    "direct level = %d, send level = %d\n", enabled ? "true" : "false",
                    directLevel, sendLevel);
            }
        }
    }

    // configure preset reverb on player
    SLPresetReverbItf playerPresetReverb;
    if (playerPresetItfRequested) {
        result = (*playerObject)->GetInterface(playerObject, SL_IID_PRESETREVERB,
                &playerPresetReverb);
        assert(SL_RESULT_SUCCESS == result);
        SLuint16 getPresetReverb = 12345;
        result = (*playerPresetReverb)->GetPreset(playerPresetReverb, &getPresetReverb);
        if (SL_RESULT_SUCCESS == result) {
            printf("Player default preset reverb %u\n", getPresetReverb);
            if (playerPresetNumber != ((SLuint16) ~0)) {
                result = (*playerPresetReverb)->SetPreset(playerPresetReverb, playerPresetNumber);
                if (SL_RESULT_SUCCESS == result) {
                    result = (*playerPresetReverb)->GetPreset(playerPresetReverb, &getPresetReverb);
                    assert(SL_RESULT_SUCCESS == result);
                    assert(getPresetReverb == playerPresetNumber);
                    printf("Player preset reverb successfully changed to %u\n", playerPresetNumber);
                } else {
                    printf("Unable to set player preset reverb to %u, result=%u\n",
                            playerPresetNumber, result);
                }
            }
        } else {
            printf("Unable to get player default preset reverb, result=%u\n", result);
        }
    }

    // configure environmental reverb on player
    SLEnvironmentalReverbItf playerEnvironmentalReverb;
    if (playerEnvironmentalItfRequested) {
        result = (*playerObject)->GetInterface(playerObject, SL_IID_ENVIRONMENTALREVERB,
                &playerEnvironmentalReverb);
        assert(SL_RESULT_SUCCESS == result);
        SLEnvironmentalReverbSettings getSettings;
        memset(&getSettings, 0, sizeof(getSettings));
        result = (*playerEnvironmentalReverb)->GetEnvironmentalReverbProperties(
                playerEnvironmentalReverb, &getSettings);
        if (SL_RESULT_SUCCESS == result) {
            printf("Player default environmental reverb settings\n");
            printf("--------------------------------------------\n");
            slesutPrintEnvironmentalReverbSettings(&getSettings);
            printf("\n");
            if (playerEnvironmentalName != NULL) {
                result = (*playerEnvironmentalReverb)->SetEnvironmentalReverbProperties(
                        playerEnvironmentalReverb, &playerEnvironmentalSettings);
                assert(SL_RESULT_SUCCESS == result);
                printf("Player new environmental reverb settings\n");
                printf("----------------------------------------\n");
                slesutPrintEnvironmentalReverbSettings(&playerEnvironmentalSettings);
                printf("\n");
                result = (*playerEnvironmentalReverb)->GetEnvironmentalReverbProperties(
                        playerEnvironmentalReverb, &getSettings);
                assert(SL_RESULT_SUCCESS == result);
                printf("Player read environmental reverb settings\n");
                printf("-----------------------------------------\n");
                slesutPrintEnvironmentalReverbSettings(&getSettings);
                printf("\n");
                if (!slesutCompareEnvironmentalReverbSettings(&getSettings,
                        &playerEnvironmentalSettings)) {
                    printf("Warning: new and read are different; check details above\n");
                } else {
                    printf("New and read match, life is good\n");
                }
            }
        } else {
            printf("Unable to get player default environmental reverb properties, result=%u\n",
                    result);
        }
    }

    // get the play interface
    SLPlayItf playerPlay;
    result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
    assert(SL_RESULT_SUCCESS == result);

    // get the prefetch status interface
    SLPrefetchStatusItf playerPrefetchStatus;
    result = (*playerObject)->GetInterface(playerObject, SL_IID_PREFETCHSTATUS,
            &playerPrefetchStatus);
    assert(SL_RESULT_SUCCESS == result);

    // enable prefetch status callbacks
    result = (*playerPrefetchStatus)->RegisterCallback(playerPrefetchStatus, prefetch_callback,
            NULL);
    assert(SL_RESULT_SUCCESS == result);
    result = (*playerPrefetchStatus)->SetCallbackEventsMask(playerPrefetchStatus,
            SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE);
    assert(SL_RESULT_SUCCESS == result);

    // set play state to paused to enable pre-fetch so we can get a more reliable duration
    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED);
    assert(SL_RESULT_SUCCESS == result);

    // wait for prefetch status callback to indicate either sufficient data or error
    pthread_mutex_lock(&mutex);
    while (prefetch_status == SL_PREFETCHSTATUS_UNKNOWN) {
        pthread_cond_wait(&cond, &mutex);
    }
    pthread_mutex_unlock(&mutex);
    if (prefetch_status == SL_PREFETCHSTATUS_ERROR) {
        fprintf(stderr, "Error during prefetch, exiting\n");
        goto destroyRes;
    }

    // get the duration
    SLmillisecond duration;
    result = (*playerPlay)->GetDuration(playerPlay, &duration);
    assert(SL_RESULT_SUCCESS == result);
    if (SL_TIME_UNKNOWN == duration) {
        printf("duration: unknown\n");
    } else {
        printf("duration: %.1f seconds\n", duration / 1000.0);
    }

    // enable looping
    if (loop) {
        SLSeekItf playerSeek;
        result = (*playerObject)->GetInterface(playerObject, SL_IID_SEEK, &playerSeek);
        assert(SL_RESULT_SUCCESS == result);
        result = (*playerSeek)->SetLoop(playerSeek, SL_BOOLEAN_TRUE, (SLmillisecond) 0,
                SL_TIME_UNKNOWN);
        assert(SL_RESULT_SUCCESS == result);
    }

    // start audio playing
    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
    assert(SL_RESULT_SUCCESS == result);

    // wait for audio to finish playing
    SLuint32 state;
    for (;;) {
        result = (*playerPlay)->GetPlayState(playerPlay, &state);
        assert(SL_RESULT_SUCCESS == result);
        if (SL_PLAYSTATE_PLAYING != state)
            break;
        usleep(1000000);
     }
    assert(SL_PLAYSTATE_PAUSED == state);

destroyRes:
    // cleanup objects
    (*playerObject)->Destroy(playerObject);
    (*mixObject)->Destroy(mixObject);
    (*engineObject)->Destroy(engineObject);

    return EXIT_SUCCESS;
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
    SLresult result;

    // process command line parameters
    char *prog = argv[0];
    int i;
    for (i = 1; i < argc; ++i) {
        char *arg = argv[i];
        if (arg[0] != '-')
            break;
        if (!strncmp(arg, "--mix-preset=", 13)) {
            mixPresetNumber = atoi(&arg[13]);
        } else if (!strncmp(arg, "--mix-name=", 11)) {
            mixEnvName = &arg[11];
        } else if (!strncmp(arg, "--player-preset=", 16)) {
            playerPresetNumber = atoi(&arg[16]);
        } else if (!strncmp(arg, "--player-name=", 14)) {
            playerEnvName = &arg[14];
        } else {
            fprintf(stderr, "%s: unknown option %s ignored\n", prog, arg);
        }
    }
    if (argc - i != 1) {
        fprintf(stderr, "usage: %s --mix-preset=# --mix-name=I3DL2 --player-preset=# "
                "--player-name=I3DL2 filename\n", prog);
        return EXIT_FAILURE;
    }
    char *pathname = argv[i];

    const SLEnvironmentalReverbSettings *envSettings;
    if (NULL != mixEnvName) {
        envSettings = lookupEnvName(mixEnvName);
        if (NULL == envSettings) {
            fprintf(stderr, "%s: mix environmental reverb name %s not found, "
                    "available names are:\n", prog, mixEnvName);
            printEnvNames();
            return EXIT_FAILURE;
        }
        mixEnvSettings = *envSettings;
    }
    if (NULL != playerEnvName) {
        envSettings = lookupEnvName(playerEnvName);
        if (NULL == envSettings) {
            fprintf(stderr, "%s: player environmental reverb name %s not found, "
                    "available names are:\n", prog, playerEnvName);
            printEnvNames();
            return EXIT_FAILURE;
        }
        playerEnvSettings = *envSettings;
    }

    // create engine
    SLObjectItf engineObject;
    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
    assert(SL_RESULT_SUCCESS == result);
    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
    assert(SL_RESULT_SUCCESS == result);
    SLEngineItf engineEngine;
    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
    assert(SL_RESULT_SUCCESS == result);

    // create output mix
    SLInterfaceID mix_ids[2];
    SLboolean mix_req[2];
    SLuint32 count = 0;
    if (mixPresetNumber != ((SLuint16) ~0)) {
        mix_req[count] = SL_BOOLEAN_TRUE;
        mix_ids[count++] = SL_IID_PRESETREVERB;
    }
    if (mixEnvName != NULL) {
        mix_req[count] = SL_BOOLEAN_TRUE;
        mix_ids[count++] = SL_IID_ENVIRONMENTALREVERB;
    }
    SLObjectItf mixObject;
    result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, count, mix_ids, mix_req);
    assert(SL_RESULT_SUCCESS == result);
    result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE);
    assert(SL_RESULT_SUCCESS == result);

    // configure preset reverb on output mix
    SLPresetReverbItf mixPresetReverb;
    if (mixPresetNumber != ((SLuint16) ~0)) {
        result = (*mixObject)->GetInterface(mixObject, SL_IID_PRESETREVERB, &mixPresetReverb);
        assert(SL_RESULT_SUCCESS == result);
        SLuint16 getPresetReverb = 12345;
        result = (*mixPresetReverb)->GetPreset(mixPresetReverb, &getPresetReverb);
        assert(SL_RESULT_SUCCESS == result);
        printf("Output mix default preset reverb %u\n", getPresetReverb);
        result = (*mixPresetReverb)->SetPreset(mixPresetReverb, mixPresetNumber);
        if (SL_RESULT_SUCCESS == result) {
            result = (*mixPresetReverb)->GetPreset(mixPresetReverb, &getPresetReverb);
            assert(SL_RESULT_SUCCESS == result);
            assert(getPresetReverb == mixPresetNumber);
            printf("Output mix preset reverb successfully changed to %u\n", mixPresetNumber);
        } else
            printf("Unable to set output mix preset reverb to %u, result=%lu\n", mixPresetNumber,
                    result);
    }

    // configure environmental reverb on output mix
    SLEnvironmentalReverbItf mixEnvironmentalReverb;
    if (mixEnvName != NULL) {
        result = (*mixObject)->GetInterface(mixObject, SL_IID_ENVIRONMENTALREVERB,
                &mixEnvironmentalReverb);
        assert(SL_RESULT_SUCCESS == result);
        SLEnvironmentalReverbSettings getSettings;
        result = (*mixEnvironmentalReverb)->GetEnvironmentalReverbProperties(mixEnvironmentalReverb,
                &getSettings);
        assert(SL_RESULT_SUCCESS == result);
        printf("Output mix default environmental reverb settings\n");
        printf("------------------------------------------------\n");
        slesutPrintEnvironmentalReverbSettings(&getSettings);
        printf("\n");
        result = (*mixEnvironmentalReverb)->SetEnvironmentalReverbProperties(mixEnvironmentalReverb,
                &mixEnvSettings);
        assert(SL_RESULT_SUCCESS == result);
        printf("Output mix new environmental reverb settings\n");
        printf("--------------------------------------------\n");
        slesutPrintEnvironmentalReverbSettings(&mixEnvSettings);
        printf("\n");
        result = (*mixEnvironmentalReverb)->GetEnvironmentalReverbProperties(mixEnvironmentalReverb,
                &getSettings);
        assert(SL_RESULT_SUCCESS == result);
        printf("Output mix read environmental reverb settings\n");
        printf("--------------------------------------------\n");
        slesutPrintEnvironmentalReverbSettings(&getSettings);
        printf("\n");
        if (!slesutCompareEnvronmentalReverbSettings(&getSettings, &mixEnvSettings)) {
            printf("Warning: new and read are different; check details above\n");
        } else {
            printf("New and read match, life is good\n");
        }
    }

    // create audio player
    SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, (SLchar *) pathname};
    SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
    SLDataSource audioSrc = {&locURI, &dfMIME};
    SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, mixObject};
    SLDataSink audioSnk = {&locOutputMix, NULL};
    SLInterfaceID player_ids[4];
    SLboolean player_req[4];
    count = 0;
    if (playerPresetNumber != ((SLuint16) ~0)) {
        player_req[count] = SL_BOOLEAN_TRUE;
        player_ids[count++] = SL_IID_PRESETREVERB;
    }
    if (playerEnvName != NULL) {
        player_req[count] = SL_BOOLEAN_TRUE;
        player_ids[count++] = SL_IID_ENVIRONMENTALREVERB;
    }
    if (mixPresetNumber != ((SLuint16) ~0) || mixEnvName != NULL) {
        player_req[count] = SL_BOOLEAN_TRUE;
        player_ids[count++] = SL_IID_EFFECTSEND;
    }
    player_req[count] = SL_BOOLEAN_TRUE;
    player_ids[count++] = SL_IID_PREFETCHSTATUS;
    SLObjectItf playerObject;
    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
        &audioSnk, count, player_ids, player_req);
    assert(SL_RESULT_SUCCESS == result);

    // realize audio player
    result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
    assert(SL_RESULT_SUCCESS == result);

    // if reverb is on output mix (aux effect), then enable it for this player
    if (mixPresetNumber != ((SLuint16) ~0) || mixEnvName != NULL) {
        SLEffectSendItf playerEffectSend;
        result = (*playerObject)->GetInterface(playerObject, SL_IID_EFFECTSEND, &playerEffectSend);
        assert(SL_RESULT_SUCCESS == result);
        if (mixPresetNumber != ((SLuint16) ~0)) {
            result = (*playerEffectSend)->EnableEffectSend(playerEffectSend, mixPresetReverb,
                    SL_BOOLEAN_TRUE, (SLmillibel) 0);
            assert(SL_RESULT_SUCCESS == result);
        }
        if (mixEnvName != NULL) {
            result = (*playerEffectSend)->EnableEffectSend(playerEffectSend, mixEnvironmentalReverb,
                    SL_BOOLEAN_TRUE, (SLmillibel) 0);
            assert(SL_RESULT_SUCCESS == result);
        }
    }

    // configure preset reverb on player
    SLPresetReverbItf playerPresetReverb;
    if (playerPresetNumber != ((SLuint16) ~0)) {
        result = (*playerObject)->GetInterface(playerObject, SL_IID_PRESETREVERB,
                &playerPresetReverb);
        assert(SL_RESULT_SUCCESS == result);
        SLuint16 getPresetReverb = 12345;
        result = (*playerPresetReverb)->GetPreset(playerPresetReverb, &getPresetReverb);
        assert(SL_RESULT_SUCCESS == result);
        printf("Player default preset reverb %u\n", getPresetReverb);
        result = (*playerPresetReverb)->SetPreset(playerPresetReverb, playerPresetNumber);
        if (SL_RESULT_SUCCESS == result) {
            result = (*playerPresetReverb)->GetPreset(playerPresetReverb, &getPresetReverb);
            assert(SL_RESULT_SUCCESS == result);
            assert(getPresetReverb == playerPresetNumber);
            printf("Player preset reverb successfully changed to %u\n", playerPresetNumber);
        } else
            printf("Unable to set player preset reverb to %u, result=%lu\n", playerPresetNumber,
                    result);
    }

    // configure environmental reverb on player
    SLEnvironmentalReverbItf playerEnvironmentalReverb;
    if (playerEnvName != NULL) {
        result = (*playerObject)->GetInterface(playerObject, SL_IID_ENVIRONMENTALREVERB,
                &playerEnvironmentalReverb);
        assert(SL_RESULT_SUCCESS == result);
        SLEnvironmentalReverbSettings getSettings;
        memset(&getSettings, 0, sizeof(getSettings));
        result = (*playerEnvironmentalReverb)->GetEnvironmentalReverbProperties(
                playerEnvironmentalReverb, &getSettings);
        assert(SL_RESULT_SUCCESS == result);
        printf("Player default environmental reverb settings\n");
        printf("--------------------------------------------\n");
        slesutPrintEnvironmentalReverbSettings(&getSettings);
        printf("\n");
        result = (*playerEnvironmentalReverb)->SetEnvironmentalReverbProperties(
                playerEnvironmentalReverb, &playerEnvSettings);
        assert(SL_RESULT_SUCCESS == result);
        printf("Player new environmental reverb settings\n");
        printf("----------------------------------------\n");
        slesutPrintEnvironmentalReverbSettings(&playerEnvSettings);
        printf("\n");
        result = (*playerEnvironmentalReverb)->GetEnvironmentalReverbProperties(
                playerEnvironmentalReverb, &getSettings);
        assert(SL_RESULT_SUCCESS == result);
        printf("Player read environmental reverb settings\n");
        printf("-----------------------------------------\n");
        slesutPrintEnvironmentalReverbSettings(&getSettings);
        printf("\n");
        if (!slesutCompareEnvronmentalReverbSettings(&getSettings, &playerEnvSettings)) {
            printf("Warning: new and read are different; check details above\n");
        } else {
            printf("New and read match, life is good\n");
        }
    }

    // get the play interface
    SLPlayItf playerPlay;
    result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
    assert(SL_RESULT_SUCCESS == result);

    // set play state to paused to enable pre-fetch so we can get a more reliable duration
    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED);
    assert(SL_RESULT_SUCCESS == result);

    // get the prefetch status interface
    SLPrefetchStatusItf playerPrefetchStatus;
    result = (*playerObject)->GetInterface(playerObject, SL_IID_PREFETCHSTATUS,
            &playerPrefetchStatus);
    assert(SL_RESULT_SUCCESS == result);

    // poll prefetch status to detect when it completes
    SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
    SLuint32 timeOutIndex = 100; // 10s
    while ((prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA) && (timeOutIndex > 0)) {
        usleep(100 * 1000);
        (*playerPrefetchStatus)->GetPrefetchStatus(playerPrefetchStatus, &prefetchStatus);
        timeOutIndex--;
    }
    if (timeOutIndex == 0) {
        fprintf(stderr, "\nWe\'re done waiting, failed to prefetch data in time, exiting\n");
        goto destroyRes;
    }

    // get the duration
    SLmillisecond duration;
    result = (*playerPlay)->GetDuration(playerPlay, &duration);
    assert(SL_RESULT_SUCCESS == result);
    if (SL_TIME_UNKNOWN == duration) {
        printf("duration: unknown\n");
    } else {
        printf("duration: %.1f seconds\n", duration / 1000.0);
    }

    // start audio playing
    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
    assert(SL_RESULT_SUCCESS == result);

    // wait for audio to finish playing
    SLuint32 state;
    for (;;) {
        result = (*playerPlay)->GetPlayState(playerPlay, &state);
        assert(SL_RESULT_SUCCESS == result);
        if (SL_PLAYSTATE_PLAYING != state)
            break;
        usleep(1000000);
     }
    assert(SL_PLAYSTATE_PAUSED == state);

destroyRes:
    // cleanup objects
    (*playerObject)->Destroy(playerObject);
    (*mixObject)->Destroy(mixObject);
    (*engineObject)->Destroy(engineObject);

    return EXIT_SUCCESS;
}