/*
 * 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.
 */

// Play an audio file using buffer queue

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <SLES/OpenSLES.h>
#ifdef ANDROID
#include "sndfile.h"
#else
#include <sndfile.h>
#endif

#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))

unsigned numBuffers = 2;
int framesPerBuffer = 512;
SNDFILE *sndfile;
SF_INFO sfinfo;
unsigned which; // which buffer to use next
SLboolean eof;  // whether we have hit EOF on input yet
short *buffers;
SLuint32 byteOrder; // desired to use for PCM buffers
SLuint32 nativeByteOrder;   // of platform
SLuint32 bitsPerSample = 16;

// swap adjacent bytes; this would normally be in <unistd.h> but is missing here
static void swab(const void *from, void *to, ssize_t n)
{
    // from and to as char pointers
    const char *from_ch = (const char *) from;
    char *to_ch = (char *) to;
    // note that we don't swap the last odd byte
    while (n >= 2) {
        to_ch[0] = from_ch[1];
        to_ch[1] = from_ch[0];
        to_ch += 2;
        from_ch += 2;
        n -= 2;
    }
}

// squeeze 16-bit signed PCM samples down to 8-bit unsigned PCM samples by truncation; no dithering
static void squeeze(const short *from, unsigned char *to, ssize_t n)
{
    // note that we don't squeeze the last odd byte
    while (n >= 2) {
        *to++ = (*from++ + 32768) >> 8;
        n -= 2;
    }
}

// This callback is called each time a buffer finishes playing

static void callback(SLBufferQueueItf bufq, void *param)
{
    assert(NULL == param);
    if (!eof) {
        short *buffer = &buffers[framesPerBuffer * sfinfo.channels * which];
        sf_count_t count;
        count = sf_readf_short(sndfile, buffer, (sf_count_t) framesPerBuffer);
        if (0 >= count) {
            eof = SL_BOOLEAN_TRUE;
        } else {
            SLuint32 nbytes = count * sfinfo.channels * sizeof(short);
            if (byteOrder != nativeByteOrder) {
                swab(buffer, buffer, nbytes);
            }
            if (bitsPerSample == 8) {
                squeeze(buffer, (unsigned char *) buffer, nbytes);
                nbytes /= 2;
            }
            SLresult result = (*bufq)->Enqueue(bufq, buffer, nbytes);
            assert(SL_RESULT_SUCCESS == result);
            if (++which >= numBuffers)
                which = 0;
        }
    }
}

int main(int argc, char **argv)
{
    // Determine the native byte order (SL_BYTEORDER_NATIVE not available until 1.1)
    union {
        short s;
        char c[2];
    } u;
    u.s = 0x1234;
    if (u.c[0] == 0x34) {
        nativeByteOrder = SL_BYTEORDER_LITTLEENDIAN;
    } else if (u.c[0] == 0x12) {
        nativeByteOrder = SL_BYTEORDER_BIGENDIAN;
    } else {
        fprintf(stderr, "Unable to determine native byte order\n");
        return EXIT_FAILURE;
    }
    byteOrder = nativeByteOrder;

    SLboolean enableReverb = SL_BOOLEAN_FALSE;
    SLpermille initialRate = 0;
    SLpermille finalRate = 0;
    SLpermille deltaRate = 1;
    SLmillisecond deltaRateMs = 0;

    // process command-line options
    int i;
    for (i = 1; i < argc; ++i) {
        char *arg = argv[i];
        if (arg[0] != '-') {
            break;
        }
        if (!strcmp(arg, "-b")) {
            byteOrder = SL_BYTEORDER_BIGENDIAN;
        } else if (!strcmp(arg, "-l")) {
            byteOrder = SL_BYTEORDER_LITTLEENDIAN;
        } else if (!strcmp(arg, "-8")) {
            bitsPerSample = 8;
        } else if (!strncmp(arg, "-f", 2)) {
            framesPerBuffer = atoi(&arg[2]);
        } else if (!strncmp(arg, "-n", 2)) {
            numBuffers = atoi(&arg[2]);
        } else if (!strncmp(arg, "-p", 2)) {
            initialRate = atoi(&arg[2]);
        } else if (!strncmp(arg, "-P", 2)) {
            finalRate = atoi(&arg[2]);
        } else if (!strncmp(arg, "-q", 2)) {
            deltaRate = atoi(&arg[2]);
            // deltaRate is a magnitude, so take absolute value
            if (deltaRate < 0) {
                deltaRate = -deltaRate;
            }
        } else if (!strncmp(arg, "-Q", 2)) {
            deltaRateMs = atoi(&arg[2]);
        } else if (!strcmp(arg, "-r")) {
            enableReverb = SL_BOOLEAN_TRUE;
        } else {
            fprintf(stderr, "option %s ignored\n", arg);
        }
    }

    if (argc - i != 1) {
        fprintf(stderr, "usage: [-b/l] [-8] [-f#] [-n#] [-p#] [-r] %s filename\n", argv[0]);
        fprintf(stderr, "    -b  force big-endian byte order (default is native byte order)\n");
        fprintf(stderr, "    -l  force little-endian byte order (default is native byte order)\n");
        fprintf(stderr, "    -8  output 8-bits per sample (default is 16-bits per sample)\n");
        fprintf(stderr, "    -f# frames per buffer (default 512)\n");
        fprintf(stderr, "    -n# number of buffers (default 2)\n");
        fprintf(stderr, "    -p# initial playback rate in per mille (default 1000)\n");
        fprintf(stderr, "    -P# final playback rate in per mille (default same as -p#)\n");
        fprintf(stderr, "    -q# magnitude of playback rate changes in per mille (default 1)\n");
        fprintf(stderr, "    -Q# period between playback rate changes in ms (default 50)\n");
        fprintf(stderr, "    -r  enable reverb (default disabled)\n");
        return EXIT_FAILURE;
    }

    const char *filename = argv[i];
    //memset(&sfinfo, 0, sizeof(SF_INFO));
    sfinfo.format = 0;
    sndfile = sf_open(filename, SFM_READ, &sfinfo);
    if (NULL == sndfile) {
        perror(filename);
        return EXIT_FAILURE;
    }

    // verify the file format
    switch (sfinfo.channels) {
    case 1:
    case 2:
        break;
    default:
        fprintf(stderr, "unsupported channel count %d\n", sfinfo.channels);
        goto close_sndfile;
    }

    switch (sfinfo.samplerate) {
    case  8000:
    case 11025:
    case 12000:
    case 16000:
    case 22050:
    case 24000:
    case 32000:
    case 44100:
    case 48000:
        break;
    default:
        fprintf(stderr, "unsupported sample rate %d\n", sfinfo.samplerate);
        goto close_sndfile;
    }

    switch (sfinfo.format & SF_FORMAT_TYPEMASK) {
    case SF_FORMAT_WAV:
        break;
    default:
        fprintf(stderr, "unsupported format type 0x%x\n", sfinfo.format & SF_FORMAT_TYPEMASK);
        goto close_sndfile;
    }

    switch (sfinfo.format & SF_FORMAT_SUBMASK) {
    case SF_FORMAT_PCM_16:
    case SF_FORMAT_PCM_U8:
    case SF_FORMAT_ULAW:
    case SF_FORMAT_ALAW:
    case SF_FORMAT_IMA_ADPCM:
        break;
    default:
        fprintf(stderr, "unsupported sub-format 0x%x\n", sfinfo.format & SF_FORMAT_SUBMASK);
        goto close_sndfile;
    }

    buffers = (short *) malloc(framesPerBuffer * sfinfo.channels * sizeof(short) * numBuffers);

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

    // create output mix
    SLObjectItf outputMixObject;
    SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
    SLboolean req[1] = {SL_BOOLEAN_TRUE};
    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, enableReverb ? 1 : 0,
            ids, req);
    assert(SL_RESULT_SUCCESS == result);
    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
    assert(SL_RESULT_SUCCESS == result);

    // configure environmental reverb on output mix
    SLEnvironmentalReverbItf mixEnvironmentalReverb = NULL;
    if (enableReverb) {
        result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
                &mixEnvironmentalReverb);
        assert(SL_RESULT_SUCCESS == result);
        SLEnvironmentalReverbSettings settings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;
        result = (*mixEnvironmentalReverb)->SetEnvironmentalReverbProperties(mixEnvironmentalReverb,
                &settings);
        assert(SL_RESULT_SUCCESS == result);
    }

    // configure audio source
    SLDataLocator_BufferQueue loc_bufq;
    loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
    loc_bufq.numBuffers = numBuffers;
    SLDataFormat_PCM format_pcm;
    format_pcm.formatType = SL_DATAFORMAT_PCM;
    format_pcm.numChannels = sfinfo.channels;
    format_pcm.samplesPerSec = sfinfo.samplerate * 1000;
    format_pcm.bitsPerSample = bitsPerSample;
    format_pcm.containerSize = format_pcm.bitsPerSample;
    format_pcm.channelMask = 1 == format_pcm.numChannels ? SL_SPEAKER_FRONT_CENTER :
            SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
    format_pcm.endianness = byteOrder;
    SLDataSource audioSrc;
    audioSrc.pLocator = &loc_bufq;
    audioSrc.pFormat = &format_pcm;

    // configure audio sink
    SLDataLocator_OutputMix loc_outmix;
    loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
    loc_outmix.outputMix = outputMixObject;
    SLDataSink audioSnk;
    audioSnk.pLocator = &loc_outmix;
    audioSnk.pFormat = NULL;

    // create audio player
    SLInterfaceID ids2[3] = {SL_IID_BUFFERQUEUE, SL_IID_PLAYBACKRATE, SL_IID_EFFECTSEND};
    SLboolean req2[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
    SLObjectItf playerObject;
    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
            &audioSnk, enableReverb ? 3 : 2, ids2, req2);
    if (SL_RESULT_SUCCESS != result) {
        fprintf(stderr, "can't create audio player\n");
        goto no_player;
    }

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

    // get the effect send interface and enable effect send reverb for this player
    if (enableReverb) {
        SLEffectSendItf playerEffectSend;
        result = (*playerObject)->GetInterface(playerObject, SL_IID_EFFECTSEND, &playerEffectSend);
        assert(SL_RESULT_SUCCESS == result);
        result = (*playerEffectSend)->EnableEffectSend(playerEffectSend, mixEnvironmentalReverb,
                SL_BOOLEAN_TRUE, (SLmillibel) 0);
        assert(SL_RESULT_SUCCESS == result);
    }

    // get the playback rate interface and configure the rate
    SLPlaybackRateItf playerPlaybackRate;
    result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAYBACKRATE, &playerPlaybackRate);
    assert(SL_RESULT_SUCCESS == result);
    SLpermille defaultRate;
    result = (*playerPlaybackRate)->GetRate(playerPlaybackRate, &defaultRate);
    assert(SL_RESULT_SUCCESS == result);
    SLuint32 defaultProperties;
    result = (*playerPlaybackRate)->GetProperties(playerPlaybackRate, &defaultProperties);
    assert(SL_RESULT_SUCCESS == result);
    printf("default playback rate %d per mille, properties 0x%x\n", defaultRate, defaultProperties);
    if (initialRate <= 0) {
        initialRate = defaultRate;
    }
    if (finalRate <= 0) {
        finalRate = initialRate;
    }
    SLpermille currentRate = defaultRate;
    if (finalRate == initialRate) {
        deltaRate = 0;
    } else if (finalRate < initialRate) {
        deltaRate = -deltaRate;
    }
    if (initialRate != defaultRate) {
        result = (*playerPlaybackRate)->SetRate(playerPlaybackRate, initialRate);
        if (SL_RESULT_FEATURE_UNSUPPORTED == result) {
            fprintf(stderr, "initial playback rate %d is unsupported\n", initialRate);
            deltaRate = 0;
        } else if (SL_RESULT_PARAMETER_INVALID == result) {
            fprintf(stderr, "initial playback rate %d is invalid\n", initialRate);
            deltaRate = 0;
        } else {
            assert(SL_RESULT_SUCCESS == result);
            currentRate = initialRate;
        }
    }

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

    // get the buffer queue interface
    SLBufferQueueItf playerBufferQueue;
    result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE,
            &playerBufferQueue);
    assert(SL_RESULT_SUCCESS == result);

    // loop until EOF or no more buffers
    for (which = 0; which < numBuffers; ++which) {
        short *buffer = &buffers[framesPerBuffer * sfinfo.channels * which];
        sf_count_t frames = framesPerBuffer;
        sf_count_t count;
        count = sf_readf_short(sndfile, buffer, frames);
        if (0 >= count) {
            eof = SL_BOOLEAN_TRUE;
            break;
        }

        // enqueue a buffer
        SLuint32 nbytes = count * sfinfo.channels * sizeof(short);
        if (byteOrder != nativeByteOrder) {
            swab(buffer, buffer, nbytes);
        }
        if (bitsPerSample == 8) {
            squeeze(buffer, (unsigned char *) buffer, nbytes);
            nbytes /= 2;
        }
        result = (*playerBufferQueue)->Enqueue(playerBufferQueue, buffer, nbytes);
        assert(SL_RESULT_SUCCESS == result);
    }
    if (which >= numBuffers) {
        which = 0;
    }

    // register a callback on the buffer queue
    result = (*playerBufferQueue)->RegisterCallback(playerBufferQueue, callback, NULL);
    assert(SL_RESULT_SUCCESS == result);

    // set the player's state to playing
    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
    assert(SL_RESULT_SUCCESS == result);

    // get the initial time
    struct timespec prevTs;
    clock_gettime(CLOCK_MONOTONIC, &prevTs);
    long elapsedNs = 0;
    long deltaRateNs = deltaRateMs * 1000000;

    // wait until the buffer queue is empty
    SLBufferQueueState bufqstate;
    for (;;) {
        result = (*playerBufferQueue)->GetState(playerBufferQueue, &bufqstate);
        assert(SL_RESULT_SUCCESS == result);
        if (0 >= bufqstate.count) {
            break;
        }
        if (deltaRate == 0) {
            sleep(1);
        } else {
            struct timespec curTs;
            clock_gettime(CLOCK_MONOTONIC, &curTs);
            elapsedNs += (curTs.tv_sec - prevTs.tv_sec) * 1000000000 +
                    // this term can be negative
                    (curTs.tv_nsec - prevTs.tv_nsec);
            prevTs = curTs;
            if (elapsedNs < deltaRateNs) {
                usleep((deltaRateNs - elapsedNs) / 1000);
                continue;
            }
            elapsedNs -= deltaRateNs;
            SLpermille nextRate = currentRate + deltaRate;
            result = (*playerPlaybackRate)->SetRate(playerPlaybackRate, nextRate);
            if (SL_RESULT_SUCCESS != result) {
                fprintf(stderr, "next playback rate %d is unsupported\n", nextRate);
            } else if (SL_RESULT_PARAMETER_INVALID == result) {
                fprintf(stderr, "next playback rate %d is invalid\n", nextRate);
            } else {
                assert(SL_RESULT_SUCCESS == result);
            }
            currentRate = nextRate;
            if (currentRate >= max(initialRate, finalRate)) {
                currentRate = max(initialRate, finalRate);
                deltaRate = -abs(deltaRate);
            } else if (currentRate <= min(initialRate, finalRate)) {
                currentRate = min(initialRate, finalRate);
                deltaRate = abs(deltaRate);
            }
        }
    }

    // destroy audio player
    (*playerObject)->Destroy(playerObject);

no_player:

    // destroy output mix
    (*outputMixObject)->Destroy(outputMixObject);

    // destroy engine
    (*engineObject)->Destroy(engineObject);

close_sndfile:

    (void) sf_close(sndfile);

    return EXIT_SUCCESS;
}
