{-# LANGUAGE ForeignFunctionInterface #-} {-# OPTIONS_GHC -fno-warn-unused-imports #-} -------------------------------------------------------------------------------- -- | -- Module : Sound.OpenAL.AL.Doppler -- Copyright : (c) Sven Panne 2003-2013 -- License : BSD3 -- -- Maintainer : Sven Panne -- Stability : stable -- Portability : portable -- -- This module corresponds to section 3.5.2. (Velocity Dependent Doppler Effect) -- of the OpenAL Specification and Reference (version 1.1). -- -------------------------------------------------------------------------------- module Sound.OpenAL.AL.Doppler ( -- * Introduction -- $Introduction dopplerFactor, speedOfSound ) where import Foreign.C.Types import Foreign.Ptr import Graphics.Rendering.OpenGL.GL.StateVar import Sound.OpenAL.AL.BasicTypes import Sound.OpenAL.AL.Extensions import Sound.OpenAL.AL.QueryUtils -- For Haddock only. import Sound.OpenAL.AL.Errors -------------------------------------------------------------------------------- -- | 'dopplerFactor' is a simple scaling of source and listener velocities to -- exaggerate or deemphasize the Doppler (pitch) shift resulting from the -- calculation. Setting 'dopplerFactor' to a negative value will result in an -- 'ALInvalidValue' error, the command is then ignored. The default value is 1. -- The implementation is free to optimize the case of 'dopplerFactor' containing -- zero, as this effectively disables the effect. dopplerFactor :: StateVar ALfloat dopplerFactor = makeDopplerVar GetDopplerFactor "alDopplerFactor" -------------------------------------------------------------------------------- -- | 'speedOfSound' allows the application to change the reference (propagation) -- speed used in the Doppler calculation. The source and listener velocities -- should be expressed in the same units as the speed of sound. Setting -- 'speedOfSound' to a negative or zero value will result in an 'ALInvalidValue' -- error, the command is ignored then. The default value is 343.3 (appropriate -- for velocity units of meters and air as the propagation medium). speedOfSound :: StateVar ALfloat speedOfSound = makeDopplerVar GetSpeedOfSound "alSpeedOfSound" -------------------------------------------------------------------------------- makeDopplerVar :: GetPName -> String -> StateVar ALfloat makeDopplerVar p apiEntryName = makeStateVar (alGetFloat (marshalGetPName p)) (\value -> do -- ToDo: Should we check alcVersion or alIsExtensionPresent here? funPtr <- get (alProcAddress apiEntryName) invokeWithFloat funPtr value) foreign import ccall unsafe "alGetFloat" alGetFloat :: ALenum -> IO ALfloat type Invoker a = FunPtr a -> a foreign import ccall unsafe "dynamic" invokeWithFloat :: Invoker (ALfloat -> IO ()) -------------------------------------------------------------------------------- -- $Introduction -- The Doppler Effect depends on the velocities of source and listener relative -- to the medium, and the propagation speed of sound in that medium. The -- application might want to emphasize or de-emphasize the Doppler Effect as -- physically accurate calculation might not give the desired results. -- The amount of frequency shift (pitch change) is proportional to the speed of -- listener and source along their line of sight. -- -- The Doppler Effect as implemented by OpenAL is described in detail in section -- 3.5.2 of the OpenAL 1.1 specification. Note that effects of the medium (air, -- water) moving with respect to listener and source are ignored. There are two -- API calls global to the current context that provide control of the Doppler -- factor and the speed of sound. Distance and velocity units are completely -- independent of one another (so you could use different units for each if -- desired).