/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Sam Lantinga
    slouken@libsdl.org

    This file based on Apple sample code. We haven't changed the file name, 
    so if you want to see the original search for it on apple.com/developer
*/
#include "SDL_config.h"

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    AudioFilePlayer.cpp
*/
#include "AudioFilePlayer.h"

/*
void ThrowResult (OSStatus result, const char* str)
{
    SDL_SetError ("Error: %s %d", str, result);
    throw result;
}
*/

#if DEBUG
static void
PrintStreamDesc(AudioStreamBasicDescription * inDesc)
{
    if (!inDesc) {
        printf("Can't print a NULL desc!\n");
        return;
    }

    printf("- - - - - - - - - - - - - - - - - - - -\n");
    printf("  Sample Rate:%f\n", inDesc->mSampleRate);
    printf("  Format ID:%s\n", (char *) &inDesc->mFormatID);
    printf("  Format Flags:%lX\n", inDesc->mFormatFlags);
    printf("  Bytes per Packet:%ld\n", inDesc->mBytesPerPacket);
    printf("  Frames per Packet:%ld\n", inDesc->mFramesPerPacket);
    printf("  Bytes per Frame:%ld\n", inDesc->mBytesPerFrame);
    printf("  Channels per Frame:%ld\n", inDesc->mChannelsPerFrame);
    printf("  Bits per Channel:%ld\n", inDesc->mBitsPerChannel);
    printf("- - - - - - - - - - - - - - - - - - - -\n");
}
#endif


static int
AudioFilePlayer_SetDestination(AudioFilePlayer * afp, AudioUnit * inDestUnit)
{
    /*if (afp->mConnected) throw static_cast<OSStatus>(-1); *//* can't set dest if already engaged */
    if (afp->mConnected)
        return 0;

    SDL_memcpy(&afp->mPlayUnit, inDestUnit, sizeof(afp->mPlayUnit));

    OSStatus result = noErr;


    /* we can "down" cast a component instance to a component */
    ComponentDescription desc;
    result = GetComponentInfo((Component) * inDestUnit, &desc, 0, 0, 0);
    if (result)
        return 0;               /*THROW_RESULT("GetComponentInfo") */

    /* we're going to use this to know which convert routine to call
       a v1 audio unit will have a type of 'aunt'
       a v2 audio unit will have one of several different types. */
    if (desc.componentType != kAudioUnitComponentType) {
        result = badComponentInstance;
        /*THROW_RESULT("BAD COMPONENT") */
        if (result)
            return 0;
    }

    /* Set the input format of the audio unit. */
    result = AudioUnitSetProperty(*inDestUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  0,
                                  &afp->mFileDescription,
                                  sizeof(afp->mFileDescription));
    /*THROW_RESULT("AudioUnitSetProperty") */
    if (result)
        return 0;
    return 1;
}

static void
AudioFilePlayer_SetNotifier(AudioFilePlayer * afp,
                            AudioFilePlayNotifier inNotifier, void *inRefCon)
{
    afp->mNotifier = inNotifier;
    afp->mRefCon = inRefCon;
}

static int
AudioFilePlayer_IsConnected(AudioFilePlayer * afp)
{
    return afp->mConnected;
}

static AudioUnit
AudioFilePlayer_GetDestUnit(AudioFilePlayer * afp)
{
    return afp->mPlayUnit;
}

static void
AudioFilePlayer_Print(AudioFilePlayer * afp)
{
#if DEBUG
    printf("Is Connected:%s\n", (IsConnected()? "true" : "false"));
    printf("- - - - - - - - - - - - - - \n");
#endif
}

static void
AudioFilePlayer_SetStartFrame(AudioFilePlayer * afp, int frame)
{
    SInt64 position = frame * 2352;

    afp->mStartFrame = frame;
    afp->mAudioFileManager->SetPosition(afp->mAudioFileManager, position);
}


static int
AudioFilePlayer_GetCurrentFrame(AudioFilePlayer * afp)
{
    return afp->mStartFrame +
        (afp->mAudioFileManager->GetByteCounter(afp->mAudioFileManager) /
         2352);
}

static void
AudioFilePlayer_SetStopFrame(AudioFilePlayer * afp, int frame)
{
    SInt64 position = frame * 2352;

    afp->mAudioFileManager->SetEndOfFile(afp->mAudioFileManager, position);
}

void
delete_AudioFilePlayer(AudioFilePlayer * afp)
{
    if (afp != NULL) {
        afp->Disconnect(afp);

        if (afp->mAudioFileManager) {
            delete_AudioFileManager(afp->mAudioFileManager);
            afp->mAudioFileManager = 0;
        }

        if (afp->mForkRefNum) {
            FSCloseFork(afp->mForkRefNum);
            afp->mForkRefNum = 0;
        }
        SDL_free(afp);
    }
}

static int
AudioFilePlayer_Connect(AudioFilePlayer * afp)
{
#if DEBUG
    printf("Connect:%x, engaged=%d\n", (int) afp->mPlayUnit,
           (afp->mConnected ? 1 : 0));
#endif
    if (!afp->mConnected) {
        if (!afp->mAudioFileManager->DoConnect(afp->mAudioFileManager))
            return 0;

        /* set the render callback for the file data to be supplied to the sound converter AU */
        afp->mInputCallback.inputProc = afp->mAudioFileManager->FileInputProc;
        afp->mInputCallback.inputProcRefCon = afp->mAudioFileManager;

        OSStatus result = AudioUnitSetProperty(afp->mPlayUnit,
                                               kAudioUnitProperty_SetInputCallback,
                                               kAudioUnitScope_Input,
                                               0,
                                               &afp->mInputCallback,
                                               sizeof(afp->mInputCallback));
        if (result)
            return 0;           /*THROW_RESULT("AudioUnitSetProperty") */
        afp->mConnected = 1;
    }

    return 1;
}

/* warning noted, now please go away ;-) */
/* #warning This should redirect the calling of notification code to some other thread */
static void
AudioFilePlayer_DoNotification(AudioFilePlayer * afp, OSStatus inStatus)
{
    if (afp->mNotifier) {
        (*afp->mNotifier) (afp->mRefCon, inStatus);
    } else {
        SDL_SetError("Notification posted with no notifier in place");

        if (inStatus == kAudioFilePlay_FileIsFinished)
            afp->Disconnect(afp);
        else if (inStatus != kAudioFilePlayErr_FilePlayUnderrun)
            afp->Disconnect(afp);
    }
}

static void
AudioFilePlayer_Disconnect(AudioFilePlayer * afp)
{
#if DEBUG
    printf("Disconnect:%x,%ld, engaged=%d\n", (int) afp->mPlayUnit, 0,
           (afp->mConnected ? 1 : 0));
#endif
    if (afp->mConnected) {
        afp->mConnected = 0;

        afp->mInputCallback.inputProc = 0;
        afp->mInputCallback.inputProcRefCon = 0;
        OSStatus result = AudioUnitSetProperty(afp->mPlayUnit,
                                               kAudioUnitProperty_SetInputCallback,
                                               kAudioUnitScope_Input,
                                               0,
                                               &afp->mInputCallback,
                                               sizeof(afp->mInputCallback));
        if (result)
            SDL_SetError("AudioUnitSetProperty:RemoveInputCallback:%ld",
                         result);

        afp->mAudioFileManager->Disconnect(afp->mAudioFileManager);
    }
}

typedef struct
{
    UInt32 offset;
    UInt32 blockSize;
} SSNDData;

static int
AudioFilePlayer_OpenFile(AudioFilePlayer * afp, const FSRef * inRef,
                         SInt64 * outFileDataSize)
{
    ContainerChunk chunkHeader;
    ChunkHeader chunk;
    SSNDData ssndData;

    OSErr result;
    HFSUniStr255 dfName;
    ByteCount actual;
    SInt64 offset;

    /* Open the data fork of the input file */
    result = FSGetDataForkName(&dfName);
    if (result)
        return 0;               /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSGetDataForkName") */

    result =
        FSOpenFork(inRef, dfName.length, dfName.unicode, fsRdPerm,
                   &afp->mForkRefNum);
    if (result)
        return 0;               /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSOpenFork") */

    /* Read the file header, and check if it's indeed an AIFC file */
    result =
        FSReadFork(afp->mForkRefNum, fsAtMark, 0, sizeof(chunkHeader),
                   &chunkHeader, &actual);
    if (result)
        return 0;               /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork") */

    if (chunkHeader.ckID != 'FORM') {
        result = -1;
        if (result)
            return 0;           /*THROW_RESULT("AudioFilePlayer::OpenFile(): chunk id is not 'FORM'"); */
    }

    if (chunkHeader.formType != 'AIFC') {
        result = -1;
        if (result)
            return 0;           /*THROW_RESULT("AudioFilePlayer::OpenFile(): file format is not 'AIFC'"); */
    }

    /* Search for the SSND chunk. We ignore all compression etc. information
       in other chunks. Of course that is kind of evil, but for now we are lazy
       and rely on the cdfs to always give us the same fixed format.
       TODO: Parse the COMM chunk we currently skip to fill in mFileDescription.
     */
    offset = 0;
    do {
        result =
            FSReadFork(afp->mForkRefNum, fsFromMark, offset,
                       sizeof(chunk), &chunk, &actual);
        if (result)
            return 0;           /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork") */

        /* Skip the chunk data */
        offset = chunk.ckSize;
    } while (chunk.ckID != 'SSND');

    /* Read the header of the SSND chunk. After this, we are positioned right
       at the start of the audio data. */
    result =
        FSReadFork(afp->mForkRefNum, fsAtMark, 0, sizeof(ssndData),
                   &ssndData, &actual);
    if (result)
        return 0;               /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork") */

    result = FSSetForkPosition(afp->mForkRefNum, fsFromMark, ssndData.offset);
    if (result)
        return 0;               /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSSetForkPosition") */

    /* Data size */
    *outFileDataSize = chunk.ckSize - ssndData.offset - 8;

    /* File format */
    afp->mFileDescription.mSampleRate = 44100;
    afp->mFileDescription.mFormatID = kAudioFormatLinearPCM;
    afp->mFileDescription.mFormatFlags =
        kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger;
    afp->mFileDescription.mBytesPerPacket = 4;
    afp->mFileDescription.mFramesPerPacket = 1;
    afp->mFileDescription.mBytesPerFrame = 4;
    afp->mFileDescription.mChannelsPerFrame = 2;
    afp->mFileDescription.mBitsPerChannel = 16;

    return 1;
}

AudioFilePlayer *
new_AudioFilePlayer(const FSRef * inFileRef)
{
    SInt64 fileDataSize = 0;

    AudioFilePlayer *afp =
        (AudioFilePlayer *) SDL_malloc(sizeof(AudioFilePlayer));
    if (afp == NULL)
        return NULL;
    SDL_memset(afp, '\0', sizeof(*afp));

#define SET_AUDIOFILEPLAYER_METHOD(m) afp->m = AudioFilePlayer_##m
    SET_AUDIOFILEPLAYER_METHOD(SetDestination);
    SET_AUDIOFILEPLAYER_METHOD(SetNotifier);
    SET_AUDIOFILEPLAYER_METHOD(SetStartFrame);
    SET_AUDIOFILEPLAYER_METHOD(GetCurrentFrame);
    SET_AUDIOFILEPLAYER_METHOD(SetStopFrame);
    SET_AUDIOFILEPLAYER_METHOD(Connect);
    SET_AUDIOFILEPLAYER_METHOD(Disconnect);
    SET_AUDIOFILEPLAYER_METHOD(DoNotification);
    SET_AUDIOFILEPLAYER_METHOD(IsConnected);
    SET_AUDIOFILEPLAYER_METHOD(GetDestUnit);
    SET_AUDIOFILEPLAYER_METHOD(Print);
    SET_AUDIOFILEPLAYER_METHOD(OpenFile);
#undef SET_AUDIOFILEPLAYER_METHOD

    if (!afp->OpenFile(afp, inFileRef, &fileDataSize)) {
        SDL_free(afp);
        return NULL;
    }

    /* we want about 4 seconds worth of data for the buffer */
    int bytesPerSecond =
        (UInt32) (4 * afp->mFileDescription.mSampleRate *
                  afp->mFileDescription.mBytesPerFrame);

#if DEBUG
    printf("File format:\n");
    PrintStreamDesc(&afp->mFileDescription);
#endif

    afp->mAudioFileManager = new_AudioFileManager(afp, afp->mForkRefNum,
                                                  fileDataSize,
                                                  bytesPerSecond);
    if (afp->mAudioFileManager == NULL) {
        delete_AudioFilePlayer(afp);
        return NULL;
    }

    return afp;
}

/* vi: set ts=4 sw=4 expandtab: */
