module Csound.Typed.Misc( HeadPanSpec(..), headPan, headPan', staticHeadPan ) where import Data.Default import Csound.Typed.Types import Csound.Typed.GlobalState -- | Static head response based spacialization. It works when you listen in headphones. -- It works only with sample rate of 44100, 48000 or 96000. It's more efficient than @headPan@. -- -- > staticHeadPan (azimuth, elevation) asig -- -- azimuth and elevation are measured in ratios (0, 1), staticHeadPan :: (D, D) -> Sig -> Sig2 staticHeadPan (az, elev) asrc = toTuple $ do azExpr <- toGE $ -90 + 180 * az elevExpr <- toGE $ -40 + 130 * elev asrcExpr <- toGE asrc sr <- toGE $ getSampleRate (a1, a2) <- simpleHrtfstat asrcExpr azExpr elevExpr iradius sr return [a1, a2] where iradius = 9.0 -- | Optional arguments for opcode hrtfmove. -- -- phase is 0 or 1 -- -- fade is 1 to 24. -- -- See csound docs for hrtfmove for details. data HeadPanSpec = HeadPanSpec { headPanPhase :: D , hradPanFade :: D } instance Default HeadPanSpec where def = HeadPanSpec 0 8 -- | Head response based spacialization. It works when you listen in headphones. -- It works only with sample rate of 44100, 48000 or 96000. -- -- > headPan (azimuth, elevation) asig -- -- azimuth and elevation are measured in ratios (0, 1), headPan :: (Sig, Sig) -> Sig -> Sig2 headPan = headPan' def -- | HeadPan with optional arguments. headPan' :: HeadPanSpec -> (Sig, Sig) -> Sig -> Sig2 headPan' spec (az, elev) asrc = toTuple $ do azExpr <- toGE $ -90 + 180 * az elevExpr <- toGE $ -40 + 130 * elev asrcExpr <- toGE asrc phase <- toGE $ headPanPhase spec fade <- toGE $ hradPanFade spec sr <- toGE $ getSampleRate (a1, a2) <- simpleHrtfmove asrcExpr azExpr elevExpr phase fade sr return [a1, a2]