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

 This example shows how simply play generated tones using FMOD_System_PlayDSP instead of 
 manually connecting and disconnecting DSP units.
==============================================================================================='/
#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_CHANNEL   ptr channel = 0
    dim as FMOD_DSP       ptr dsp = 0
    dim as FMOD_RESULT     result = any
    dim as string key
    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
    end if

    result = FMOD_System_Init(fsystem, 32, FMOD_INIT_NORMAL, NULL)
    ERRCHECK(result)

    /'
        Create an oscillator DSP unit for the tone.
    '/
    result = FMOD_System_CreateDSPByType(fsystem, FMOD_DSP_TYPE_OSCILLATOR, @dsp)
    ERRCHECK(result)
    result = FMOD_DSP_SetParameter(dsp, FMOD_DSP_OSCILLATOR_RATE, 440.0f)       /' musical note 'A' '/
    ERRCHECK(result)

    
    printf(!"======================================================================\n")
    printf(!"GenerateTone Example.  Copyright (c) Firelight Technologies 2004-2011.\n")
    printf(!"======================================================================\n\n")
    printf(!"\n")
    printf(!"Press '1' to play a sine wave\n")
    printf(!"Press '2' to play a square wave\n")
    printf(!"Press '3' to play a saw wave\n")
    printf(!"Press '4' to play a triangle wave\n")
    printf(!"Press '5' to play a white noise\n")
    printf(!"Press 's' to stop channel\n")
    printf(!"\n")
    printf(!"Press 'v'/'V' to change channel volume\n")
    printf(!"Press 'f'/'F' to change channel frequency\n")
    printf(!"Press '['/']' to change channel pan\n")
    printf(!"Press 'Esc' to quit\n")
    printf(!"\n")

    /'
        Main loop
    '/
    do
key = inkey
            select case key
                case "1" :
                    result = FMOD_System_PlayDSP(fsystem, FMOD_CHANNEL_REUSE, dsp, TRUE, @channel)
                    FMOD_Channel_SetVolume(channel, 0.5f)
                    result = FMOD_DSP_SetParameter(dsp, FMOD_DSP_OSCILLATOR_TYPE, 0)
                    ERRCHECK(result)
                    FMOD_Channel_SetPaused(channel, FALSE)
                case "2" :
                    result = FMOD_System_PlayDSP(fsystem, FMOD_CHANNEL_REUSE, dsp, TRUE, @channel)
                    FMOD_Channel_SetVolume(channel, 0.125f)
                    result = FMOD_DSP_SetParameter(dsp, FMOD_DSP_OSCILLATOR_TYPE, 1)
                    ERRCHECK(result)
                    FMOD_Channel_SetPaused(channel, FALSE)
                case "3" :
                    result = FMOD_System_PlayDSP(fsystem, FMOD_CHANNEL_REUSE, dsp, TRUE, @channel)
                    FMOD_Channel_SetVolume(channel, 0.125f)
                    result = FMOD_DSP_SetParameter(dsp, FMOD_DSP_OSCILLATOR_TYPE, 2)
                    ERRCHECK(result)
                    FMOD_Channel_SetPaused(channel, FALSE)
                case "4" :
                    result = FMOD_System_PlayDSP(fsystem, FMOD_CHANNEL_REUSE, dsp, TRUE, @channel)
                    FMOD_Channel_SetVolume(channel, 0.5f)
                    result = FMOD_DSP_SetParameter(dsp, FMOD_DSP_OSCILLATOR_TYPE, 4)
                    ERRCHECK(result)
                    FMOD_Channel_SetPaused(channel, FALSE)
                case "5" :
                    result = FMOD_System_PlayDSP(fsystem, FMOD_CHANNEL_REUSE, dsp, TRUE, @channel)
                    FMOD_Channel_SetVolume(channel, 0.25f)
                    result = FMOD_DSP_SetParameter(dsp, FMOD_DSP_OSCILLATOR_TYPE, 5)
                    ERRCHECK(result)
                    FMOD_Channel_SetPaused(channel, FALSE)
                case "s" :
                    FMOD_Channel_Stop(channel)
                case "v" :
                    dim as float volume = any

                    FMOD_Channel_GetVolume(channel, @volume)
                    volume -= 0.1f
                    FMOD_Channel_SetVolume(channel, volume)
                case "V" :

                    dim as float volume = any

                    FMOD_Channel_GetVolume(channel, @volume)
                    volume += 0.1f
                    FMOD_Channel_SetVolume(channel, volume)
               case "f" :
                    dim as float frequency = any

                    FMOD_Channel_GetFrequency(channel, @frequency)
                    frequency -= 500
                    FMOD_Channel_SetFrequency(channel, frequency)
                case "F" :
                    dim as float frequency = any

                    FMOD_Channel_GetFrequency(channel, @frequency)
                    frequency += 500.0f
                    FMOD_Channel_SetFrequency(channel, frequency)
                case "[" :
                    dim as float pan = any

                    FMOD_Channel_GetPan(channel, @pan)
                    pan -= 0.1f
                    FMOD_Channel_SetPan(channel, pan)
                case "]" :
                    dim as float pan = any

                    FMOD_Channel_GetPan(channel, @pan)
                    pan += 0.1f
                    FMOD_Channel_SetPan(channel, pan)
end select

        FMOD_System_Update(fsystem)

        scope
            dim as float frequency = 0, volume = 0, pan = 0
            dim as integer playing = FALSE

            if (channel) then
                FMOD_Channel_GetFrequency(channel, @frequency)
                FMOD_Channel_GetVolume(channel, @volume)
                FMOD_Channel_GetPan(channel, @pan)
                FMOD_Channel_IsPlaying(channel, @playing)
            end if

            printf(!"Channel %s : Frequency %.1f Volume %.1f Pan %.1f  \r", iif(playing,@"playing",@"stopped"), frequency, volume, pan)
        end scope
        
        Sleep(10)

    loop while (key <> chr(27))

    printf(!"\n")

    /'
        Shut down
    '/
    result = FMOD_DSP_Release(dsp)
    ERRCHECK(result)
    result = FMOD_System_Close(fsystem)
    ERRCHECK(result)
    result = FMOD_System_Release(fsystem)
    ERRCHECK(result)
