/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>

#include <SLES/OpenSLES.h>


#define MAX_NUMBER_INTERFACES 3

#define REPETITIONS 4  // 4 repetitions, but will stop the looping before the end

#define INITIAL_RATE 2000 // 2x normal playback speed

// These are extensions to OpenSL ES 1.0.1 values

#define SL_PREFETCHSTATUS_UNKNOWN 0
#define SL_PREFETCHSTATUS_ERROR   ((SLuint32) -1)

// Mutex and condition shared with main program to protect prefetch_status

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
SLuint32 prefetch_status = SL_PREFETCHSTATUS_UNKNOWN;

/* used to detect errors likely to have occured when the OpenSL ES framework fails to open
 * a resource, for instance because a file URI is invalid, or an HTTP server doesn't respond.
 */
#define PREFETCHEVENT_ERROR_CANDIDATE \
        (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE)

//-----------------------------------------------------------------
//* Exits the application if an error is encountered */
#define CheckErr(x) ExitOnErrorFunc(x,__LINE__)

void ExitOnErrorFunc( SLresult result , int line)
{
    if (SL_RESULT_SUCCESS != result) {
        fprintf(stderr, "%u error code encountered at line %d, exiting\n", result, line);
        exit(EXIT_FAILURE);
    }
}

//-----------------------------------------------------------------
/* PlayItf callback for an audio player */
void PlayEventCallback( SLPlayItf caller __unused, void *pContext, SLuint32 event)
{
    fprintf(stdout, "PlayEventCallback event = ");
    if (event & SL_PLAYEVENT_HEADATEND) {
        fprintf(stdout, "SL_PLAYEVENT_HEADATEND \n");
        /* slow playback down by 2x for next loop,  if possible */
        SLpermille minRate, maxRate, stepSize, rate = 1000;
        SLuint32 capa;
        assert(NULL != pContext);
        SLPlaybackRateItf pRateItf = (SLPlaybackRateItf)pContext;
        SLresult res = (*pRateItf)->GetRate(pRateItf, &rate); CheckErr(res);
        res = (*pRateItf)->GetRateRange(pRateItf, 0, &minRate, &maxRate, &stepSize, &capa);
        CheckErr(res);
        fprintf(stdout, "old rate = %d, minRate=%d, maxRate=%d\n", rate, minRate, maxRate);
        rate /= 2;
        if (rate < minRate) {
            rate = minRate;
        }
        fprintf(stdout, "new rate = %d\n", rate);
        res = (*pRateItf)->SetRate(pRateItf, rate); CheckErr(res);
        if (res == SL_RESULT_FEATURE_UNSUPPORTED) {
            fprintf(stderr, "new playback rate %d per mille is unsupported\n", rate);
        } else {
            CheckErr(res);
        }
    }
    if (event & SL_PLAYEVENT_HEADATMARKER) {
        fprintf(stdout, "SL_PLAYEVENT_HEADATMARKER ");
    }
    if (event & SL_PLAYEVENT_HEADATNEWPOS) {
        fprintf(stdout, "SL_PLAYEVENT_HEADATNEWPOS ");
    }
    if (event & SL_PLAYEVENT_HEADMOVING) {
        fprintf(stdout, "SL_PLAYEVENT_HEADMOVING ");
    }
    if (event & SL_PLAYEVENT_HEADSTALLED) {
        fprintf(stdout, "SL_PLAYEVENT_HEADSTALLED");
    }
    fprintf(stdout, "\n");
}

//-----------------------------------------------------------------
/* PrefetchStatusItf callback for an audio player */
void PrefetchEventCallback( SLPrefetchStatusItf caller,  void *pContext, SLuint32 event)
{
    //fprintf(stdout, "\t\tPrefetchEventCallback: received event %u\n", event);
    SLresult result;
    assert(pContext == NULL);
    SLpermille level = 0;
    result = (*caller)->GetFillLevel(caller, &level);
    CheckErr(result);
    SLuint32 status;
    result = (*caller)->GetPrefetchStatus(caller, &status);
    CheckErr(result);
    if (event & SL_PREFETCHEVENT_FILLLEVELCHANGE) {
        fprintf(stdout, "\t\tPrefetchEventCallback: Buffer fill level is = %d\n", level);
    }
    if (event & SL_PREFETCHEVENT_STATUSCHANGE) {
        fprintf(stdout, "\t\tPrefetchEventCallback: Prefetch Status is = %u\n", status);
    }
    SLuint32 new_prefetch_status;
    if ((event & PREFETCHEVENT_ERROR_CANDIDATE) == PREFETCHEVENT_ERROR_CANDIDATE
            && level == 0 && status == SL_PREFETCHSTATUS_UNDERFLOW) {
        fprintf(stdout, "\t\tPrefetchEventCallback: Error while prefetching data, exiting\n");
        new_prefetch_status = SL_PREFETCHSTATUS_ERROR;
    } else if (event == SL_PREFETCHEVENT_STATUSCHANGE &&
            status == SL_PREFETCHSTATUS_SUFFICIENTDATA) {
        new_prefetch_status = status;
    } else {
        return;
    }
    int ok;
    ok = pthread_mutex_lock(&mutex);
    assert(ok == 0);
    prefetch_status = new_prefetch_status;
    ok = pthread_cond_signal(&cond);
    assert(ok == 0);
    ok = pthread_mutex_unlock(&mutex);
    assert(ok == 0);
}

// Display rate capabilities in a nicely formatted way

void printCapabilities(SLuint32 capabilities)
{
    bool needBar = false;
    printf("0x%x (", capabilities);
#define _(x)                             \
    if (capabilities & SL_RATEPROP_##x) { \
        if (needBar)                     \
            printf("|");                 \
        printf("SL_RATEPROP_" #x);        \
        needBar = true;                  \
        capabilities &= ~SL_RATEPROP_##x; \
    }
    _(SILENTAUDIO)
    _(STAGGEREDAUDIO)
    _(NOPITCHCORAUDIO)
    _(PITCHCORAUDIO)
    if (capabilities != 0) {
        if (needBar)
            printf("|");
        printf("0x%x", capabilities);
        needBar = true;
    }
    if (!needBar)
        printf("N/A");
    printf(")");
}

//-----------------------------------------------------------------

/* Play some music from a URI  */
void TestSlowDownUri( SLObjectItf sl, const char* path)
{
    SLEngineItf                EngineItf;

    SLresult                   res;

    SLDataSource               audioSource;
    SLDataLocator_URI          uri;
    SLDataFormat_MIME          mime;

    SLDataSink                 audioSink;
    SLDataLocator_OutputMix    locator_outputmix;

    SLObjectItf                player;
    SLPlayItf                  playItf;
    SLSeekItf                  seekItf;
    SLPrefetchStatusItf        prefetchItf;
    SLPlaybackRateItf          rateItf;

    SLObjectItf                OutputMix;

    SLboolean required[MAX_NUMBER_INTERFACES];
    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];

    /* Get the SL Engine Interface which is implicit */
    res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);   CheckErr(res);

    /* Initialize arrays required[] and iidArray[] */
    for (int i=0 ; i < MAX_NUMBER_INTERFACES ; i++) {
        required[i] = SL_BOOLEAN_FALSE;
        iidArray[i] = SL_IID_NULL;
    }

    required[0] = SL_BOOLEAN_TRUE;
    iidArray[0] = SL_IID_VOLUME;
    // Create Output Mix object to be used by player
    res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0,
            iidArray, required);  CheckErr(res);

    // Realizing the Output Mix object in synchronous mode.
    res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE);  CheckErr(res);

    /* Setup the data source structure for the URI */
    uri.locatorType = SL_DATALOCATOR_URI;
    uri.URI         =  (SLchar*) path;
    mime.formatType    = SL_DATAFORMAT_MIME;
    mime.mimeType      = (SLchar*)NULL;
    mime.containerType = SL_CONTAINERTYPE_UNSPECIFIED;

    audioSource.pFormat  = (void *)&mime;
    audioSource.pLocator = (void *)&uri;

    /* Setup the data sink structure */
    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
    locator_outputmix.outputMix   = OutputMix;
    audioSink.pLocator            = (void *)&locator_outputmix;
    audioSink.pFormat             = NULL;

    /******************************************************/
    /* Create the audio player */
    required[0] = SL_BOOLEAN_TRUE;
    iidArray[0] = SL_IID_SEEK;
    required[1] = SL_BOOLEAN_TRUE;
    iidArray[1] = SL_IID_PREFETCHSTATUS;
    required[2] = SL_BOOLEAN_TRUE;
    iidArray[2] = SL_IID_PLAYBACKRATE;
    res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink,
            MAX_NUMBER_INTERFACES, iidArray, required); CheckErr(res);

    /* Realizing the player in synchronous mode. */
    res = (*player)->Realize(player, SL_BOOLEAN_FALSE); CheckErr(res);
    fprintf(stdout, "URI example: after Realize\n");

    /* Get interfaces */
    res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);  CheckErr(res);

    res = (*player)->GetInterface(player, SL_IID_SEEK,  (void*)&seekItf);  CheckErr(res);

    res = (*player)->GetInterface(player, SL_IID_PLAYBACKRATE, (void*)&rateItf);  CheckErr(res);

    res = (*player)->GetInterface(player, SL_IID_PREFETCHSTATUS, (void*)&prefetchItf);
    CheckErr(res);
    res = (*prefetchItf)->RegisterCallback(prefetchItf, PrefetchEventCallback, NULL);
    CheckErr(res);
    res = (*prefetchItf)->SetCallbackEventsMask(prefetchItf,
            SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);  CheckErr(res);

    /* Configure fill level updates every 5 percent */
    (*prefetchItf)->SetFillUpdatePeriod(prefetchItf, 50);  CheckErr(res);

    /* Display duration */
    SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
    res = (*playItf)->GetDuration(playItf, &durationInMsec);  CheckErr(res);
    if (durationInMsec == SL_TIME_UNKNOWN) {
        fprintf(stdout, "Content duration is unknown (before starting to prefetch)\n");
    } else {
        fprintf(stdout, "Content duration is %u ms (before starting to prefetch)\n",
                durationInMsec);
    }

    /* Loop on the whole of the content */
    res = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN);  CheckErr(res);

    /* Set up marker and position callbacks */
    res = (*playItf)->RegisterCallback(playItf, PlayEventCallback, (void *) rateItf);
            CheckErr(res);
    res = (*playItf)->SetCallbackEventsMask(playItf,
            SL_PLAYEVENT_HEADATEND | SL_PLAYEVENT_HEADATMARKER | SL_PLAYEVENT_HEADATNEWPOS);
    res = (*playItf)->SetMarkerPosition(playItf, 1500); CheckErr(res);
    res = (*playItf)->SetPositionUpdatePeriod(playItf, 500); CheckErr(res);

    /* Get the default rate */
    SLpermille rate = 1234;
    res = (*rateItf)->GetRate(rateItf, &rate); CheckErr(res);
    printf("default rate = %d per mille\n", rate);
    assert(1000 == rate);

    /* Get the default rate properties */
    SLuint32 properties = 0;
    res = (*rateItf)->GetProperties(rateItf, &properties); CheckErr(res);
    printf("default rate properties: ");
    printCapabilities(properties);
    printf("\n");
    assert(SL_RATEPROP_NOPITCHCORAUDIO == properties);

    /* Get all supported playback rate ranges */
    SLuint8 index;
    for (index = 0; ; ++index) {
        SLpermille minRate, maxRate, stepSize;
        SLuint32 capabilities;
        res = (*rateItf)->GetRateRange(rateItf, index, &minRate, &maxRate, &stepSize,
                &capabilities);
        if (res == SL_RESULT_PARAMETER_INVALID) {
            if (index == 0) {
                fprintf(stderr, "implementation supports no rate ranges\n");
            }
            break;
        }
        CheckErr(res);
        if (index == 255) {
            fprintf(stderr, "implementation supports way too many rate ranges, I'm giving up\n");
            break;
        }
        printf("range[%u]: min=%d, max=%d, capabilities=", index, minRate, maxRate);
        printCapabilities(capabilities);
        printf("\n");
    }

    /* Change the playback rate before playback */
    res = (*rateItf)->SetRate(rateItf, INITIAL_RATE);
    if (res == SL_RESULT_FEATURE_UNSUPPORTED || res == SL_RESULT_PARAMETER_INVALID) {
        fprintf(stderr, "initial playback rate %d per mille is unsupported\n", INITIAL_RATE);
    } else {
        CheckErr(res);
    }

    /******************************************************/
    /* Play the URI */
    /*     first cause the player to prefetch the data */
    res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PAUSED ); CheckErr(res);

    // 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;
    }

    /* Display duration again, */
    res = (*playItf)->GetDuration(playItf, &durationInMsec); CheckErr(res);
    if (durationInMsec == SL_TIME_UNKNOWN) {
        fprintf(stdout, "Content duration is unknown (after prefetch completed)\n");
    } else {
        fprintf(stdout, "Content duration is %u ms (after prefetch completed)\n", durationInMsec);
    }

    /* Start playing */
    fprintf(stdout, "starting to play\n");
    res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING ); CheckErr(res);

    /* Wait as long as the duration of the content, times the repetitions,
     * before stopping the loop */
#if 1
    usleep( (REPETITIONS-1) * durationInMsec * 1100);
#else
    int ii;
    for (ii = 0; ii < REPETITIONS; ++ii) {
        usleep(durationInMsec * 1100);
        PlayEventCallback(playItf, (void *) rateItf, SL_PLAYEVENT_HEADATEND);
    }
#endif

    res = (*seekItf)->SetLoop(seekItf, SL_BOOLEAN_FALSE, 0, SL_TIME_UNKNOWN); CheckErr(res);
    fprintf(stdout, "As of now, stopped looping (sound shouldn't repeat from now on)\n");
    /* wait some more to make sure it doesn't repeat */
    usleep(durationInMsec * 1000);

    /* Stop playback */
    fprintf(stdout, "stopping playback\n");
    res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); CheckErr(res);

destroyRes:

    /* Destroy the player */
    (*player)->Destroy(player);

    /* Destroy Output Mix object */
    (*OutputMix)->Destroy(OutputMix);
}

//-----------------------------------------------------------------
int main(int argc, char* const argv[])
{
    SLresult    res;
    SLObjectItf sl;

    fprintf(stdout, "OpenSL ES test %s: exercises SLPlayItf, SLSeekItf, SLPlaybackRateItf\n",
            argv[0]);
    fprintf(stdout, "and AudioPlayer with SLDataLocator_URI source / OutputMix sink\n");
    fprintf(stdout, "Plays a sound and loops it %d times while changing the \n", REPETITIONS);
    fprintf(stdout, "playback rate each time.\n\n");

    if (argc == 1) {
        fprintf(stdout, "Usage: \n\t%s path \n\t%s url\n", argv[0], argv[0]);
        fprintf(stdout, "Example: \"%s /sdcard/my.mp3\"  or \"%s file:///sdcard/my.mp3\"\n",
                argv[0], argv[0]);
        return EXIT_FAILURE;
    }

    SLEngineOption EngineOption[] = {
            {(SLuint32) SL_ENGINEOPTION_THREADSAFE,
            (SLuint32) SL_BOOLEAN_TRUE}};

    res = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
    CheckErr(res);
    /* Realizing the SL Engine in synchronous mode. */
    res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
    CheckErr(res);

    TestSlowDownUri(sl, argv[1]);

    /* Shutdown OpenSL ES */
    (*sl)->Destroy(sl);

    return EXIT_SUCCESS;
}
