/*
 * 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 <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <system/audio.h>
#include <audio_utils/fifo.h>
#include <audio_utils/primitives.h>
#include <audio_utils/sndfile.h>

#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
void *buffers;
SLuint32 byteOrder; // desired to use for PCM buffers
SLuint32 nativeByteOrder;   // of platform
audio_format_t transferFormat = AUDIO_FORMAT_DEFAULT;
size_t sfframesize = 0;

// FIXME move to audio_utils
// 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;
    }
}

static audio_utils_fifo *fifo;
static audio_utils_fifo_reader *fifoReader;
static audio_utils_fifo_writer *fifoWriter;
static unsigned underruns = 0;

static SLuint32 squeeze(void *buffer, SLuint32 nbytes)
{
    if (byteOrder != nativeByteOrder) {
        // FIXME does not work for non 16-bit
        swab(buffer, buffer, nbytes);
    }
    if (transferFormat == AUDIO_FORMAT_PCM_8_BIT) {
        memcpy_to_u8_from_i16((uint8_t *) buffer, (const int16_t *) buffer,
                nbytes / sizeof(int16_t));
        nbytes /= 2;
    } else if (transferFormat == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
        memcpy_to_p24_from_i32((uint8_t *) buffer, (const int32_t *) buffer,
                nbytes / sizeof(int32_t));
        nbytes = nbytes * 3 / 4;
    }
    return nbytes;
}

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

static void callback(SLBufferQueueItf bufq, void *param)
{
    assert(NULL == param);
    if (!eof) {
        void *buffer = (char *)buffers + framesPerBuffer * sfframesize * which;
        ssize_t count = fifoReader->read(buffer, framesPerBuffer);
        // on underrun from pipe, substitute silence
        if (0 >= count) {
            memset(buffer, 0, framesPerBuffer * sfframesize);
            count = framesPerBuffer;
            ++underruns;
        }
        if (count > 0) {
            SLuint32 nbytes = count * sfframesize;
            nbytes = squeeze(buffer, nbytes);
            SLresult result = (*bufq)->Enqueue(bufq, buffer, nbytes);
            assert(SL_RESULT_SUCCESS == result);
            if (++which >= numBuffers)
                which = 0;
        }
    }
}

// This thread reads from a (slow) filesystem with unpredictable latency and writes to pipe

static void *file_reader_loop(void *arg __unused)
{
#define READ_FRAMES 256
    void *temp = malloc(READ_FRAMES * sfframesize);
    sf_count_t total = 0;
    sf_count_t count;
    for (;;) {
        switch (transferFormat) {
        case AUDIO_FORMAT_PCM_FLOAT:
            count = sf_readf_float(sndfile, (float *) temp, READ_FRAMES);
            break;
        case AUDIO_FORMAT_PCM_32_BIT:
        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
            count = sf_readf_int(sndfile, (int *) temp, READ_FRAMES);
            break;
        case AUDIO_FORMAT_PCM_16_BIT:
        case AUDIO_FORMAT_PCM_8_BIT:
            count = sf_readf_short(sndfile, (short *) temp, READ_FRAMES);
            break;
        default:
            count = 0;
            break;
        }
        if (0 >= count) {
            eof = SL_BOOLEAN_TRUE;
            break;
        }
        const unsigned char *ptr = (unsigned char *) temp;
        while (count > 0) {
            ssize_t actual = fifoWriter->write(ptr, (size_t) count);
            if (actual < 0) {
                break;
            }
            if ((sf_count_t) actual < count) {
                usleep(10000);
            }
            ptr += actual * sfframesize;
            count -= actual;
            total += actual;
        }
        // simulate occasional filesystem latency
        if ((total & 0xFF00) == 0xFF00) {
            usleep(100000);
        }
    }
    free(temp);
    return NULL;
}

// Main program

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;
    SLboolean enablePlaybackRate = 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")) {
            transferFormat = AUDIO_FORMAT_PCM_8_BIT;
        } else if (!strcmp(arg, "-16")) {
            transferFormat = AUDIO_FORMAT_PCM_16_BIT;
        } else if (!strcmp(arg, "-24")) {
            transferFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
        } else if (!strcmp(arg, "-32")) {
            transferFormat = AUDIO_FORMAT_PCM_32_BIT;
        } else if (!strcmp(arg, "-32f")) {
            transferFormat = AUDIO_FORMAT_PCM_FLOAT;
        } 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]);
            enablePlaybackRate = SL_BOOLEAN_TRUE;
        } else if (!strncmp(arg, "-P", 2)) {
            finalRate = atoi(&arg[2]);
            enablePlaybackRate = SL_BOOLEAN_TRUE;
        } else if (!strncmp(arg, "-q", 2)) {
            deltaRate = atoi(&arg[2]);
            // deltaRate is a magnitude, so take absolute value
            if (deltaRate < 0) {
                deltaRate = -deltaRate;
            }
            enablePlaybackRate = SL_BOOLEAN_TRUE;
        } else if (!strncmp(arg, "-Q", 2)) {
            deltaRateMs = atoi(&arg[2]);
            enablePlaybackRate = SL_BOOLEAN_TRUE;
        } 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 | | -16 | -24 | -32 | -32f] [-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 that of input file)\n");
        fprintf(stderr, "    -16 output 16-bits per sample\n");
        fprintf(stderr, "    -24 output 24-bits per sample\n");
        fprintf(stderr, "    -32 output 32-bits per sample\n");
        fprintf(stderr, "    -32f output float 32-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;
    }

    if (sfinfo.samplerate < 8000 || sfinfo.samplerate > 192000) {
        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_FLOAT:
        if (transferFormat == AUDIO_FORMAT_DEFAULT) {
            transferFormat = AUDIO_FORMAT_PCM_FLOAT;
        }
        break;
    case SF_FORMAT_PCM_32:
        if (transferFormat == AUDIO_FORMAT_DEFAULT) {
            transferFormat = AUDIO_FORMAT_PCM_32_BIT;
        }
        break;
    case SF_FORMAT_PCM_16:
        if (transferFormat == AUDIO_FORMAT_DEFAULT) {
            transferFormat = AUDIO_FORMAT_PCM_16_BIT;
        }
        break;
    case SF_FORMAT_PCM_U8:
        if (transferFormat == AUDIO_FORMAT_DEFAULT) {
            transferFormat = AUDIO_FORMAT_PCM_8_BIT;
        }
        break;
    case SF_FORMAT_PCM_24:
        if (transferFormat == AUDIO_FORMAT_DEFAULT) {
            transferFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
        }
        break;
    default:
        fprintf(stderr, "unsupported sub-format 0x%x\n", sfinfo.format & SF_FORMAT_SUBMASK);
        goto close_sndfile;
    }

    SLuint32 bitsPerSample;
    switch (transferFormat) {
    case AUDIO_FORMAT_PCM_FLOAT:
        bitsPerSample = 32;
        sfframesize = sfinfo.channels * sizeof(float);
        break;
    case AUDIO_FORMAT_PCM_32_BIT:
        bitsPerSample = 32;
        sfframesize = sfinfo.channels * sizeof(int);
        break;
    case AUDIO_FORMAT_PCM_24_BIT_PACKED:
        bitsPerSample = 24;
        sfframesize = sfinfo.channels * sizeof(int); // use int size
        break;
    case AUDIO_FORMAT_PCM_16_BIT:
        bitsPerSample = 16;
        sfframesize = sfinfo.channels * sizeof(short);
        break;
    case AUDIO_FORMAT_PCM_8_BIT:
        bitsPerSample = 8;
        sfframesize = sfinfo.channels * sizeof(short); // use short size
        break;
    default:
        fprintf(stderr, "unsupported transfer format %#x\n", transferFormat);
        goto close_sndfile;
    }

    {
    buffers = malloc(framesPerBuffer * sfframesize * 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;
    SLAndroidDataFormat_PCM_EX format_pcm;
    format_pcm.formatType = transferFormat == AUDIO_FORMAT_PCM_FLOAT
            ? SL_ANDROID_DATAFORMAT_PCM_EX : SL_DATAFORMAT_PCM;
    format_pcm.numChannels = sfinfo.channels;
    format_pcm.sampleRate = 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;
    format_pcm.representation = transferFormat == AUDIO_FORMAT_PCM_FLOAT
            ? SL_ANDROID_PCM_REPRESENTATION_FLOAT : transferFormat == AUDIO_FORMAT_PCM_8_BIT
                    ? SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT
                            : SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
    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 : (enablePlaybackRate ? 2 : 1), 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;
    SLpermille currentRate = 0;
    if (enablePlaybackRate) {
        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;
        }
        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) {
        void *buffer = (char *)buffers + framesPerBuffer * sfframesize * which;
        sf_count_t frames = framesPerBuffer;
        sf_count_t count;
        switch (transferFormat) {
        case AUDIO_FORMAT_PCM_FLOAT:
            count = sf_readf_float(sndfile, (float *) buffer, frames);
            break;
        case AUDIO_FORMAT_PCM_32_BIT:
            count = sf_readf_int(sndfile, (int *) buffer, frames);
            break;
        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
            count = sf_readf_int(sndfile, (int *) buffer, frames);
            break;
        case AUDIO_FORMAT_PCM_16_BIT:
        case AUDIO_FORMAT_PCM_8_BIT:
            count = sf_readf_short(sndfile, (short *) buffer, frames);
            break;
        default:
            count = 0;
            break;
        }
        if (0 >= count) {
            eof = SL_BOOLEAN_TRUE;
            break;
        }

        // enqueue a buffer
        SLuint32 nbytes = count * sfframesize;
        nbytes = squeeze(buffer, nbytes);
        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);

#define FIFO_FRAMES 16384
    void *fifoBuffer = malloc(FIFO_FRAMES * sfframesize);
    fifo = new audio_utils_fifo(FIFO_FRAMES, sfframesize, fifoBuffer);
    fifoReader = new audio_utils_fifo_reader(*fifo, true /*throttlesWriter*/);
    fifoWriter = new audio_utils_fifo_writer(*fifo);

    // create thread to read from file
    pthread_t thread;
    int ok = pthread_create(&thread, (const pthread_attr_t *) NULL, file_reader_loop, NULL);
    assert(0 == ok);

    // give thread a head start so that the pipe is initially filled
    sleep(1);

    // 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 (!enablePlaybackRate || 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);
            }
        }

    }

    // wait for reader thread to exit
    ok = pthread_join(thread, (void **) NULL);
    assert(0 == ok);

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

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

    delete fifoWriter;
    fifoWriter = NULL;
    delete fifoReader;
    fifoReader = NULL;
    delete fifo;
    fifo = NULL;
    free(fifoBuffer);
    fifoBuffer = NULL;

    }

no_player:

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

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

    }

close_sndfile:

    (void) sf_close(sndfile);

    return EXIT_SUCCESS;
}
