/'===============================================================================================
 CODEC_RAW.DLL
 Copyright (c), Firelight Technologies Pty, Ltd 2004-2011.

compile: fbc -dll codec_raw.bas
==============================================================================================='/



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

declare function rawopen(byval codec as FMOD_CODEC_STATE ptr, byval usermode as FMOD_MODE, byval userexinfo as FMOD_CREATESOUNDEXINFO ptr)  as FMOD_RESULT
declare function rawclose(byval codec as FMOD_CODEC_STATE ptr) as FMOD_RESULT
declare function rawread(byval codec as FMOD_CODEC_STATE ptr, byval buffer as any ptr, byval size as uinteger, byval read_ as uinteger ptr) as FMOD_RESULT
declare function rawsetposition(byval codec as FMOD_CODEC_STATE ptr, byval subsound as integer, byval position as uinteger, byval postype as FMOD_TIMEUNIT) as FMOD_RESULT

dim shared as FMOD_CODEC_DESCRIPTION rawcodec = type( _
    @"FMOD Raw player plugin example", _  ' Name.
    &h00010000, _                        ' Version 0xAAAABBBB   A = major, B = minor.
    0, _                                 ' Don't force everything using this codec to be a stream
    FMOD_TIMEUNIT_PCMBYTES, _            ' The time format we would like to accept into setposition/getposition.
    @rawopen, _                          ' Open callback.
    @rawclose, _                         ' Close callback.
    @rawread, _                          ' Read callback.
    0, _                                 ' Getlength callback.  (If not specified FMOD return the length in FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_MS or FMOD_TIMEUNIT_PCMBYTES units based on the lengthpcm member of the FMOD_CODEC structure).
    @rawsetposition, _                   ' Setposition callback.
    0, _                                 ' Getposition callback. (only used for timeunit types that are not FMOD_TIMEUNIT_PCM, FMOD_TIMEUNIT_MS and FMOD_TIMEUNIT_PCMBYTES).
    0)                                   ' Sound create callback (don't need it)



/'
    FMODGetCodecDescription is mandatory for every fmod plugin.  This is the symbol the registerplugin function searches for.
    Must be declared with F_API to make it export as stdcall.
    MUST BE EXTERN'ED AS C!  C++ functions will be mangled incorrectly and not load in fmod.
'/

function  FMODGetCodecDescription stdcall alias "_FMODGetCodecDescription"() as FMOD_CODEC_DESCRIPTION ptr export
    function = @rawcodec
end function


static shared as FMOD_CODEC_WAVEFORMAT    rawwaveformat

/'
    The actual codec code.

    Note that the callbacks uses FMOD's supplied file system callbacks.

    This is important as even though you might want to open the file yourself, you would lose the following benefits.
    1. Automatic support of memory files, CDDA based files, and HTTP/TCPIP based files.
    2. "fileoffset" / "length" support when user calls System::createSound with FMOD_CREATESOUNDEXINFO structure.
    3. Buffered file access.
    FMOD files are high level abstracts that support all sorts of 'file', they are not just disk file handles.
    If you want FMOD to use your own filesystem (and potentially lose the above benefits) use System::setFileSystem.
'/

function rawopen(byval codec as FMOD_CODEC_STATE ptr, byval usermode as FMOD_MODE, byval userexinfo as FMOD_CREATESOUNDEXINFO ptr) as FMOD_RESULT
    rawwaveformat.channels     = 2
    rawwaveformat.format       = FMOD_SOUND_FORMAT_PCM16
    rawwaveformat.frequency    = 44100
    rawwaveformat.blockalign   = rawwaveformat.channels * 2          /' 2 = 16bit pcm '/
    rawwaveformat.lengthpcm    = codec->filesize / rawwaveformat.blockalign   /' bytes converted to PCM samples '/

    codec->numsubsounds = 0                    /' number of 'subsounds' in this sound.  For most codecs this is 0, only multi sound codecs such as FSB or CDDA have subsounds. '/
    codec->waveformat   = @rawwaveformat
    codec->plugindata   = 0                    /' user data value '/

    function = FMOD_OK
end function

function rawclose(byval codec as FMOD_CODEC_STATE ptr) as FMOD_RESULT
    function = FMOD_OK
end function

function rawread(byval codec as FMOD_CODEC_STATE ptr, byval buffer as any ptr, byval size as uinteger, byval read_ as uinteger ptr) as FMOD_RESULT
    function =  codec->fileread(codec->filehandle, buffer, size, read_, 0)
end function

function rawsetposition(byval codec as FMOD_CODEC_STATE ptr, byval subsound as integer, byval position as uinteger, byval postype as FMOD_TIMEUNIT) as FMOD_RESULT
    return codec->fileseek(codec->filehandle, position, 0)
end function

