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

 This example shows how to use FMODEXP.DLL and its associated plugins.
 The example lists the available plugins, and loads a new plugin that isnt normally included
 with FMOD Ex, which is output_mp3.dll.  When this is loaded, it can be chosen as an output
 mode, for realtime encoding of audio output into the mp3 format.
==============================================================================================='/
#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  = 0
    dim as FMOD_SOUND      ptr sound   = 0
    dim as FMOD_CHANNEL    ptr channel = 0
    dim as FMOD_RESULT      result = any
    dim as integer              count = any
    dim as integer              playing = FALSE
    dim as string              key
    dim as integer             numoutputplugins = any
    dim as uinteger     version = any
    dim as uinteger     handle = 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

    /'
        Set the source directory for all of the FMOD plugins.
    '/
    result = FMOD_System_SetPluginPath(fsystem, "")
    ERRCHECK(result)

    /'
        Load up an extra plugin that is not normally used by FMOD.
    '/
    result = FMOD_System_LoadPlugin(fsystem, "output_mp3.dll", 0, 0)
    if (result = FMOD_ERR_FILE_NOTFOUND) then
        /'
            If it isn't in the same directory, try for the plugin directory.
        '/
        result = FMOD_System_LoadPlugin(fsystem, "output_mp3.dll", 0, 0)
        ERRCHECK(result)
    end if


    /'
        Display plugins
    '/
    scope
        dim as integer num = any
        dim as zstring * 256 pname = any

        printf(!"Codec plugins\n")
        printf(!"--------------\n")
        result = FMOD_System_GetNumPlugins(fsystem, FMOD_PLUGINTYPE_CODEC, @num)
        ERRCHECK(result)
        for count = 0 to num-1
            result = FMOD_System_GetPluginHandle(fsystem, FMOD_PLUGINTYPE_CODEC, count, @handle)
            ERRCHECK(result)
            
            result = FMOD_System_GetPluginInfo(fsystem, handle, 0, @pname, 256, 0)
            ERRCHECK(result)

            printf(!"%2d - %-30s", count + 1, @pname)

            if (count mod 2 ) then
                printf(!"\n")
            end if
        next
        printf(!"\n")
        if (count mod 2) then
            printf(!"\n")
        end if

        printf(!"DSP plugins\n")
        printf(!"--------------\n")
        result = FMOD_System_GetNumPlugins(fsystem, FMOD_PLUGINTYPE_DSP, @num)
        ERRCHECK(result)
        for count = 0 to num-1
            result = FMOD_System_GetPluginHandle(fsystem, FMOD_PLUGINTYPE_DSP, count, @handle)
            ERRCHECK(result)

            result = FMOD_System_GetPluginInfo(fsystem, handle, 0, @pname, 256, 0)
            ERRCHECK(result)

            printf(!"%2d - %-30s", count + 1, @pname)

            if (count mod 2) then
                printf(!"\n")
            end if
        next
        printf(!"\n")
        if (count mod 2) then
            printf(!"\n")
        end if

        printf(!"Output plugins\n")
        printf(!"--------------\n")
        result = FMOD_System_GetNumPlugins(fsystem, FMOD_PLUGINTYPE_OUTPUT, @numoutputplugins)
        ERRCHECK(result)
        for count = 0 to numoutputplugins-1
            result = FMOD_System_GetPluginHandle(fsystem, FMOD_PLUGINTYPE_OUTPUT, count, @handle)
            ERRCHECK(result)

            result = FMOD_System_GetPluginInfo(fsystem, handle, 0, @pname, 256, 0)
            ERRCHECK(result)

            printf(!"%2d - %-30s", count + 1, @pname)

            if (count mod 2) then
                printf(!"\n")
            end if
        next
        if (count mod 2) then
            printf(!"\n")
        end if
    end scope

    /'
        System initialization
    '/
    printf(!"-----------------------------------------------------------------------\n")    ' print driver names
    printf(!"Press a corresponding number for an OUTPUT PLUGIN to use or ESC to quit\n")

    do
        key = inkey
sleep 10
    loop while (key <> chr(27) AndAlso key < "1" )
    if (key = chr(27)) then
        end 0
    end if
    
    result = FMOD_System_GetPluginHandle(fsystem, FMOD_PLUGINTYPE_OUTPUT, asc(key) - asc("1"), @handle)
    ERRCHECK(result)
    result = FMOD_System_SetOutputByPlugin(fsystem, handle)
    ERRCHECK(result)
    result = FMOD_System_Init(fsystem, 32, FMOD_INIT_NORMAL, NULL)
    ERRCHECK(result)

    result = FMOD_System_CreateSound(fsystem, "media/wave.mp3", FMOD_SOFTWARE or FMOD_CREATESTREAM, 0, @sound)
    ERRCHECK(result)

    printf(!"Press a key to play sound to output device.\n")

    result = FMOD_System_PlaySound(fsystem, FMOD_CHANNEL_FREE, sound, 0, @channel)
    ERRCHECK(result)

    /'
        Main loop.
    '/
    do
        dim as uinteger ms = 0
        dim as uinteger lenms = 0
        dim as integer          paused = FALSE
        dim as integer          channelsplaying = 0
        dim as FMOD_SOUND  ptr currentsound = 0

        FMOD_System_Update(fsystem)

        playing = FALSE

        result = FMOD_Channel_IsPlaying(channel, @playing)
        if ((result <> FMOD_OK) AndAlso (result <> FMOD_ERR_INVALID_HANDLE) AndAlso (result <> FMOD_ERR_CHANNEL_STOLEN)) then
            ERRCHECK(result)
        end if
        result = FMOD_Channel_GetPaused(channel, @paused)
        if ((result <> FMOD_OK) AndAlso (result <> FMOD_ERR_INVALID_HANDLE) AndAlso (result <> FMOD_ERR_CHANNEL_STOLEN)) then
            ERRCHECK(result)
        end if

        result = FMOD_Channel_GetPosition(channel, @ms, FMOD_TIMEUNIT_MS)
        if ((result <> FMOD_OK) AndAlso (result <> FMOD_ERR_INVALID_HANDLE) AndAlso (result <> FMOD_ERR_CHANNEL_STOLEN)) then
            ERRCHECK(result)
        end if
       
        FMOD_Channel_GetCurrentSound(channel, @currentsound)
        if (currentsound) then
            result = FMOD_Sound_GetLength(currentsound, @lenms, FMOD_TIMEUNIT_MS)
            if ((result <> FMOD_OK) AndAlso (result <> FMOD_ERR_INVALID_HANDLE) AndAlso (result <> FMOD_ERR_CHANNEL_STOLEN)) then
                ERRCHECK(result)
            end if
        end if

        FMOD_System_GetChannelsPlaying(fsystem, @channelsplaying)

        printf(!"Time %02d:%02d:%02d/%02d:%02d:%02d : %s : Channels Playing %2d\r", _
ms \ 1000 \ 60, ms \ 1000 mod 60, ms \ 10 mod 100, lenms \ 1000 \ 60, lenms \ 1000 mod 60, lenms \ 10 mod 100, _
iif(paused,@"Paused ",iif(playing ,@"Playing",@"Stopped")), channelsplaying)

        Sleep(5)

            key = inkey
            if (key = chr(27)) then
                exit do
            end if
    loop while (playing)

    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)
