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

 This example shows how to put channels into channel groups, so that you can affect a group
 of channels at a time instead of just one channel at a time.
==============================================================================================='/
#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
    dim as FMOD_SOUND        ptr sound(5-1)
    dim as FMOD_CHANNEL      ptr channel(5-1)
    dim as FMOD_CHANNELGROUP ptr groupA = any, groupB = any, masterGroup = any
    dim as FMOD_DSP          ptr dspreverb = any, dspflange = any, dsplowpass = any
    dim as FMOD_RESULT        result = any
    dim as string                key
    dim as integer count = 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, 32, FMOD_INIT_NORMAL, 0)
    ERRCHECK(result)

    result = FMOD_System_CreateSound(fsystem, "media/drumloop.wav", FMOD_SOFTWARE or FMOD_LOOP_NORMAL, 0, @sound(0))
    ERRCHECK(result)
    result = FMOD_System_CreateSound(fsystem, "media/jaguar.wav", FMOD_SOFTWARE or FMOD_LOOP_NORMAL, 0, @sound(1))
    ERRCHECK(result)
    result = FMOD_System_CreateSound(fsystem, "media/c.ogg", FMOD_SOFTWARE or FMOD_LOOP_NORMAL, 0, @sound(2))
    ERRCHECK(result)
    result = FMOD_System_CreateSound(fsystem, "media/d.ogg", FMOD_SOFTWARE or FMOD_LOOP_NORMAL, 0, @sound(3))
    ERRCHECK(result)
    result = FMOD_System_CreateSound(fsystem, "media/e.ogg", FMOD_SOFTWARE or FMOD_LOOP_NORMAL, 0, @sound(4))
    ERRCHECK(result)

    result = FMOD_System_CreateChannelGroup(fsystem, "Group A", @groupA)
    ERRCHECK(result)

    result = FMOD_System_CreateChannelGroup(fsystem, "Group B", @groupB)
    ERRCHECK(result)

    result = FMOD_System_GetMasterChannelGroup(fsystem, @masterGroup)
    ERRCHECK(result)

    result = FMOD_ChannelGroup_AddGroup(masterGroup, groupA)
    ERRCHECK(result)

    result = FMOD_ChannelGroup_AddGroup(masterGroup, groupB)
    ERRCHECK(result)

    printf(!"======================================================================\n")
    printf(!"Sub-mixing example.  Copyright (c) Firelight Technologies 2004-2011.\n")
    printf(!"======================================================================\n")
    printf(!"                                                       (drumloop.wav) \n")
    printf(!"                                                      /               \n")
    printf(!"                                              (groupA)                \n")
    printf(!"                                     (reverb)/        \\               \n")
    printf(!"                                    /                  (jaguar.wav)   \n")
    printf(!"(soundcard)--(lowpass)--(mastergroup)                                  \n")
    printf(!"                                    \\                  (c.ogg)        \n")
    printf(!"                                     (flange)         /                \n")
    printf(!"                                             \\(groupB)--(d.ogg)       \n")
    printf(!"                                                      \\               \n")
    printf(!"                                                       (e.ogg)        \n")
    printf(!"Press 'A' to mute/unmute group A\n")
    printf(!"Press 'B' to mute/unmute group B\n")
    printf(!"\n")
    printf(!"Press 'R' to place reverb on group A\n")
    printf(!"Press 'F' to place flange on group B\n")
    printf(!"Press 'L' to place lowpass on master group (everything)\n")
    printf(!"Press 'Esc' to quit\n")
    printf(!"\n")

    /'
        Start all the sounds!
    '/
    for count = 0 to 5-1
        result = FMOD_System_PlaySound(fsystem, FMOD_CHANNEL_FREE, sound(count), TRUE, @channel(count))
        ERRCHECK(result)
        if (count < 2) then
            result = FMOD_Channel_SetChannelGroup(channel(count), groupA)
        else
            result = FMOD_Channel_SetChannelGroup(channel(count), groupB)
        end if
        ERRCHECK(result)
        result = FMOD_Channel_SetPaused(channel(count), FALSE)
        ERRCHECK(result)
    next

    /'
        Create the DSP effects we want to apply to our submixes.
    '/  
    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_SFXREVERB, @dspreverb)
    ERRCHECK(result)

    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_FLANGE, @dspflange)
    ERRCHECK(result)
    result = FMOD_DSP_SetParameter(dspflange, FMOD_DSP_FLANGE_RATE, 1.0f)
    ERRCHECK(result)

    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_LOWPASS, @dsplowpass)
    ERRCHECK(result)
    result = FMOD_DSP_SetParameter(dsplowpass, FMOD_DSP_LOWPASS_CUTOFF, 500.0f)
    ERRCHECK(result)

    /'
        Main loop.
    '/
    do
            key = inkey

            select case key
                case "a","A" : 
                    static as integer mute = TRUE

                    FMOD_ChannelGroup_SetMute(groupA, mute)

                    mute xor= 1
                case "b","B" : 
                    static as integer mute = TRUE

                    FMOD_ChannelGroup_SetMute(groupB, mute)

                    mute xor= 1
                case "r","R" : 
                    static as integer reverb = TRUE

                    if (reverb) then
                        FMOD_ChannelGroup_AddDSP(groupA, dspreverb, 0)
                    else
                        FMOD_DSP_Remove(dspreverb)
                    end if

                    reverb xor= 1
                case "f","F" : 
                    static as integer flange = TRUE

                    if (flange) then
                        FMOD_ChannelGroup_AddDSP(groupB, dspflange, 0)
                    else
                        FMOD_DSP_Remove(dspflange)
                    end if

                    flange xor= 1
                case "l","L" : 
                    static as integer lowpass = TRUE

                    if (lowpass) then
                        FMOD_ChannelGroup_AddDSP(masterGroup, dsplowpass, 0)
                    else
                        FMOD_DSP_Remove(dsplowpass)
                    end if

                    lowpass xor = 1
        end select

        FMOD_System_Update(fsystem)

        scope
            dim as integer  channelsplaying = 0

            FMOD_System_GetChannelsPlaying(fsystem, @channelsplaying)

            printf(!"Channels Playing %2d\r", channelsplaying)
        end scope

        Sleep(10)

    loop while (key <> chr(27))

    printf(!"\n")

    /'
        Shut down
    '/
    for count = 0 to 5-1
        result = FMOD_Sound_Release(sound(count))
        ERRCHECK(result)
    next

    result = FMOD_DSP_Release(dspreverb)
    ERRCHECK(result)
    result = FMOD_DSP_Release(dspflange)
    ERRCHECK(result)
    result = FMOD_DSP_Release(dsplowpass)
    ERRCHECK(result)

    result = FMOD_ChannelGroup_Release(groupA)
    ERRCHECK(result)
    result = FMOD_ChannelGroup_Release(groupB)
    ERRCHECK(result)

    result = FMOD_System_Close(fsystem)
    ERRCHECK(result)
    result = FMOD_System_Release(fsystem)
    ERRCHECK(result)
