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

 This example shows how to apply some of the built in software effects to sounds. 
 This example filters the global mix.  All software sounds played here would be filtered in the 
 same way.
 To filter per channel, and not have other channels affected, simply replace FMOD_System_AddDSP with
 FMOD_Channel_AddDSP.
 Note in this example you don't have to add and remove units each time, you could simply add them 
 all at the start then use FMOD_DSP_SetActive to toggle them on and off.
==============================================================================================='/
#include "windows.bi"
#include "crt.bi"

#include "fmodex/fmodex.bi"
#include "fmodex/fmod_dsp.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_DSP        ptr dsplowpass    = 0
    dim as FMOD_DSP        ptr dsphighpass   = 0
    dim as FMOD_DSP        ptr dspecho       = 0
    dim as FMOD_DSP        ptr dspflange     = 0
    dim as FMOD_DSP        ptr dspdistortion = 0
    dim as FMOD_DSP        ptr dspchorus     = 0
    dim as FMOD_DSP        ptr dspparameq    = 0
    dim as FMOD_RESULT       result
    dim as string               key
    dim as uinteger      version

    /'
        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, 32, FMOD_INIT_NORMAL, NULL)
    ERRCHECK(result)

    result = FMOD_System_CreateSound(fsystem, "media/drumloop.wav", FMOD_SOFTWARE, 0, @sound)
    ERRCHECK(result)

    printf(!"===================================================================\n")
    printf(!"Effects Example.  Copyright (c) Firelight Technologies 2004-2011.\n")
    printf(!"===================================================================\n")
    printf(!"\n")
    printf(!"Press SPACE to paused/unpause sound.\n")
    printf(!"Press 1 to toggle dsplowpass effect.\n")
    printf(!"Press 2 to toggle dsphighpass effect.\n")
    printf(!"Press 3 to toggle dspecho effect.\n")
    printf(!"Press 4 to toggle dspflange effect.\n")
    printf(!"Press 5 to toggle dspdistortion effect.\n")
    printf(!"Press 6 to toggle dspchorus effect.\n")
    printf(!"Press 7 to toggle dspparameq effect.\n")
    printf(!"Press 'Esc' to quit\n")
    printf(!"\n")

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

    /'
        Create some effects to play with.
    '/
    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_LOWPASS, @dsplowpass)
    ERRCHECK(result)
    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_HIGHPASS, @dsphighpass)
    ERRCHECK(result)
    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_ECHO, @dspecho)
    ERRCHECK(result)
    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_FLANGE, @dspflange)
    ERRCHECK(result)
    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_DISTORTION, @dspdistortion)
    ERRCHECK(result)
    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_CHORUS, @dspchorus)
    ERRCHECK(result)
    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_PARAMEQ, @dspparameq)
    ERRCHECK(result)

    /'
        Main loop.
    '/
    do
            key = inkey

select case key
                case " " :
                    dim as integer paused = any

                    FMOD_Channel_GetPaused(channel, @paused)
                    ERRCHECK(result)

                    paused xor= 1

                    result = FMOD_Channel_SetPaused(channel, paused)
                    ERRCHECK(result)
                case "1" :
                    dim as integer active = any

                    result = FMOD_DSP_GetActive(dsplowpass, @active)
                    ERRCHECK(result)

                    if (active) then
                        result = FMOD_DSP_Remove(dsplowpass)
                        ERRCHECK(result)
                    else
                        result = FMOD_System_AddDSP(fsystem, dsplowpass, 0)
                        ERRCHECK(result)
                    end if
                case "2" :
                    dim as integer active = any

                    result = FMOD_DSP_GetActive(dsphighpass, @active)
                    ERRCHECK(result)

                    if (active) then
                        result = FMOD_DSP_Remove(dsphighpass)
                        ERRCHECK(result)
                    else
                        result = FMOD_System_AddDSP(fsystem, dsphighpass, 0)
                        ERRCHECK(result)
                    end if
                case "3" :
                    dim as integer active = any

                    result = FMOD_DSP_GetActive(dspecho, @active)
                    ERRCHECK(result)

                    if (active) then
                        result = FMOD_DSP_Remove(dspecho)
                        ERRCHECK(result)
                    else
                        result = FMOD_System_AddDSP(fsystem, dspecho, 0)
                        ERRCHECK(result)

                        result = FMOD_DSP_SetParameter(dspecho, FMOD_DSP_ECHO_DELAY, 50.0f)
                        ERRCHECK(result)
                    end if
                case "4" :
                    dim as integer  active = any

                    result = FMOD_DSP_GetActive(dspflange, @active)
                    ERRCHECK(result)

                    if (active) then
                        result = FMOD_DSP_Remove(dspflange)
                        ERRCHECK(result)
                    else
                        result = FMOD_System_AddDSP(fsystem, dspflange, 0)
                        ERRCHECK(result)
                    end if
                case "5" :
                    dim as integer active = any

                    result = FMOD_DSP_GetActive(dspdistortion, @active)
                    ERRCHECK(result)

                    if (active) then
                        result = FMOD_DSP_Remove(dspdistortion)
                        ERRCHECK(result)
                    else
                        result = FMOD_System_AddDSP(fsystem, dspdistortion, 0)
                        ERRCHECK(result)

                        result = FMOD_DSP_SetParameter(dspdistortion, FMOD_DSP_DISTORTION_LEVEL, 0.8f)
                        ERRCHECK(result)
                    end if
                case "6" :
                    dim as integer active = any

                    result = FMOD_DSP_GetActive(dspchorus, @active)
                    ERRCHECK(result)

                    if (active) then
                        result = FMOD_DSP_Remove(dspchorus)
                        ERRCHECK(result)
                    else
                        result = FMOD_System_AddDSP(fsystem, dspchorus, 0)
                        ERRCHECK(result)
                    end if
                case "7" :
                    dim as integer active = any

                    result = FMOD_DSP_GetActive(dspparameq, @active)
                    ERRCHECK(result)

                    if (active) then
                        result = FMOD_DSP_Remove(dspparameq)
                        ERRCHECK(result)
                    else
                        result = FMOD_System_AddDSP(fsystem, dspparameq, 0)
                        ERRCHECK(result)

                        result = FMOD_DSP_SetParameter(dspparameq, FMOD_DSP_PARAMEQ_CENTER, 5000.0f)
                        ERRCHECK(result)
                        result = FMOD_DSP_SetParameter(dspparameq, FMOD_DSP_PARAMEQ_GAIN, 0.0f)
                        ERRCHECK(result)
                    end if
end select
        FMOD_System_Update(fsystem)

        scope
            dim as integer paused = 0
            dim as integer dsplowpass_active = any
            dim as integer dsphighpass_active = any
            dim as integer dspecho_active = any
            dim as integer dspflange_active = any
            dim as integer dspdistortion_active = any
            dim as integer dspchorus_active = any
            dim as integer dspparameq_active = any

            FMOD_DSP_GetActive(dsplowpass   , @dsplowpass_active)
            FMOD_DSP_GetActive(dsphighpass  , @dsphighpass_active)
            FMOD_DSP_GetActive(dspecho      , @dspecho_active)
            FMOD_DSP_GetActive(dspflange    , @dspflange_active)
            FMOD_DSP_GetActive(dspdistortion, @dspdistortion_active)
            FMOD_DSP_GetActive(dspchorus    , @dspchorus_active)
            FMOD_DSP_GetActive(dspparameq   , @dspparameq_active)

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

            printf(!"%s : lowpass[%c] highpass[%c] echo[%c] flange[%c] dist[%c] chorus[%c] parameq[%c]\r", _
                    iif(paused, @"Paused ", @"Playing"), _
                    iif(dsplowpass_active, asc("x"), asc(" ")), _
                    iif(dsphighpass_active, asc("x"), asc(" ")), _
                    iif(dspecho_active, asc("x"), asc(" ")), _
                    iif(dspflange_active, asc("x"), asc(" ")), _
                    iif(dspdistortion_active, asc("x"), asc(" ")), _
                    iif(dspchorus_active, asc("x"), asc(" ")), _
                    iif(dspparameq_active,asc("x"), asc(" ")))
        end scope

        Sleep(10)

    loop while (key <> chr(27))

    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)
