/'===============================================================================================
 Offline Decoding Example
 Copyright (c), Firelight Technologies Pty, Ltd 2004-2011.

 This example shows how decode a file to PCM, without playing it.
 It writes out the data as a raw data file.
 The FMOD_System_CreateSound function uses FMOD_OPENONLY so that FMOD does not read any data 
 itself.
 If this is uses then it is up to the user to use FMOD_Sound_ReadData to get the data out of 
 the file and into the destination buffer.
==============================================================================================='/
#include "windows.bi"
#include "crt.bi"

#include "fmodex/fmodex.bi"
#include "fmodex/fmod_errors.bi"

sub ERRCHECK(byval result as FMOD_RESULT)
    if (result <> FMOD_OK) then
        printf(!"FMOD error! (%d) %s\n", result, FMOD_ErrorString(result))
        end -1
end if
end sub

' program start
    dim as FMOD_SYSTEM     ptr fsystem = any
    dim as FMOD_SOUND      ptr sound = any
    dim as FMOD_RESULT       result = any
    dim as uinteger      version = any

    /'
        Create a System object and initialize.
    '/
    result = FMOD_System_Create(@fsystem)
    ERRCHECK(result)

    result = FMOD_System_GetVersion(fsystem, @version)
    ERRCHECK(result)

    if (version < FMOD_VERSION) then
        printf(!"Error!  You are using an old version of FMOD %08x.  This program requires %08x\n", version, FMOD_VERSION)
        end 0
    end if

    result = FMOD_System_Init(fsystem, 1, FMOD_INIT_NORMAL, 0)
    ERRCHECK(result)

    result = FMOD_System_CreateStream(fsystem, "media/wave.mp3", FMOD_OPENONLY or FMOD_ACCURATETIME, 0, @sound)
    ERRCHECK(result)

    printf(!"===============================================================================\n")
    printf(!"Offline Decoding Example.  Copyright (c) Firelight Technologies 2004-2011.\n")
    printf(!"===============================================================================\n")
    printf(!"\n")
    printf(!"This program will open wave.mp3 and decode it into wave.raw using the\n")
    printf(!"FMOD_Sound_ReadData function.\n")
    printf(!"\n")

    /'
        Decode the sound and write it to a .raw file.
    '/
    scope
        dim as any ptr sdata = any
        dim as uinteger length = 0, lread = 0
        dim as uinteger bytesread = 0
        dim as FILE ptr outfp = any

        #define CHUNKSIZE 4096

        result = FMOD_Sound_GetLength(sound, @length, FMOD_TIMEUNIT_PCMBYTES)
        ERRCHECK(result)

        outfp = fopen("output.raw", "wb")
        if (outfp = 0) then
            printf(!"Error!  Could not open output.raw output file.\n")
            end 0
        end if

        sdata = allocate(CHUNKSIZE)
        if (sdata = 0) then
            printf(!"Error!  Failed to allocate %d bytes.\n", CHUNKSIZE)
            end 0
        end if

        do
            result = FMOD_Sound_ReadData(sound, sdata, CHUNKSIZE, @lread)

            fwrite(sdata, lread, 1, outfp)
                       
            bytesread += lread

            printf(!"writing %d bytes of %d to output.raw\r", bytesread, length)
        loop while (result = FMOD_OK and lread = CHUNKSIZE)

        /'
            Loop terminates when either 
            1. the read function returns an error.  (ie FMOD_ERR_FILE_EOF etc).
            2. the amount requested was different to the amount returned. (somehow got an EOF without the file error, maybe a non stream file format like mod/s3m/xm/it/midi).

            If 'bytesread' is bigger than 'length' then it just means that FMOD miscalculated the size, 
            but this will not usually happen if FMOD_ACCURATETIME is used.  (this will give the correct length for VBR formats)
        '/

        printf(!"\n")

        if (outfp) then
            fclose(outfp)
        end if
    end scope
        

    printf(!"\n")

    /'
        Shut down
    '/
    result = FMOD_Sound_Release(sound)
    ERRCHECK(result)
    result = FMOD_System_Close(fsystem)
    ERRCHECK(result)
    result = FMOD_System_Release(fsystem)
    ERRCHECK(result)
