{-# LINE 1 "Sound/MikMod/Sample.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LINE 2 "Sound/MikMod/Sample.hsc" #-}
module Sound.MikMod.Sample where

import Foreign.Ptr
import Foreign.Storable
import Foreign.C.Types
import Foreign.C.String
import Data.Functor
import Control.Applicative

import Sound.MikMod.Synonyms
import Sound.MikMod.Types
import Sound.MikMod.Flags


{-# LINE 16 "Sound/MikMod/Sample.hsc" #-}

-- | Far left pan. panLeft = Pan 0.
panLeft :: Pan
panLeft = Pan $ fromIntegral (0)
{-# LINE 20 "Sound/MikMod/Sample.hsc" #-}

-- | Far right pan. panRight = Pan 255.
panRight :: Pan
panRight = Pan $ fromIntegral (255)
{-# LINE 24 "Sound/MikMod/Sample.hsc" #-}

packPan :: Pan -> SWORD
packPan (Pan n) = fromIntegral n
packPan PanSurround = (512)
{-# LINE 28 "Sound/MikMod/Sample.hsc" #-}

unpackPan :: SWORD -> Pan
unpackPan n | n == (512) = PanSurround
{-# LINE 31 "Sound/MikMod/Sample.hsc" #-}
            | n >= 0 && n <= 255 = Pan (fromIntegral n)
            | otherwise = error ("unpackPan " ++ show n)

-- | Get a report of the current state of a sample.
getSampleInfo :: SampleHandle -> IO SampleInfo
getSampleInfo ptr = SampleInfo <$>
  (unpackPan    <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr) <*>
{-# LINE 38 "Sound/MikMod/Sample.hsc" #-}
  (fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 4)) ptr :: IO ULONG)) <*>
{-# LINE 39 "Sound/MikMod/Sample.hsc" #-}
  (fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 8)) ptr :: IO UBYTE)) <*>
{-# LINE 40 "Sound/MikMod/Sample.hsc" #-}
  (unpackFlags  <$> ((\hsc_ptr -> peekByteOff hsc_ptr 12)) ptr) <*>
{-# LINE 41 "Sound/MikMod/Sample.hsc" #-}
  (unpackFlags  <$> ((\hsc_ptr -> peekByteOff hsc_ptr 10)) ptr) <*>
{-# LINE 42 "Sound/MikMod/Sample.hsc" #-}
  (fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 16)) ptr :: IO ULONG)) <*>
{-# LINE 43 "Sound/MikMod/Sample.hsc" #-}
  (fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 20)) ptr :: IO ULONG)) <*>
{-# LINE 44 "Sound/MikMod/Sample.hsc" #-}
  (fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 24)) ptr :: IO ULONG))
{-# LINE 45 "Sound/MikMod/Sample.hsc" #-}

-- | Set the panning value of the sample. Valid values range from panLeft (0)
-- to panRight (255), or PanSurround. 
setSamplePanning :: SampleHandle -> Pan -> IO ()
setSamplePanning samp pan = ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) samp (packPan pan)
{-# LINE 50 "Sound/MikMod/Sample.hsc" #-}

getSamplePanning :: SampleHandle -> IO Pan
getSamplePanning samp = unpackPan <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0)) samp
{-# LINE 53 "Sound/MikMod/Sample.hsc" #-}

-- | Set the sample playing frequency in Hertz.
setSampleSpeed :: SampleHandle -> Int -> IO ()
setSampleSpeed samp speed = ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) samp (fromIntegral speed :: ULONG)
{-# LINE 57 "Sound/MikMod/Sample.hsc" #-}

getSampleSpeed :: SampleHandle -> IO Int
getSampleSpeed samp = fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 4)) samp :: IO ULONG)
{-# LINE 60 "Sound/MikMod/Sample.hsc" #-}

-- | Set sample volume to a range 0 to 64 (65 levels). 
setSampleVolume :: SampleHandle -> Int -> IO ()
setSampleVolume samp vol = ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) samp (fromIntegral vol :: UBYTE)
{-# LINE 64 "Sound/MikMod/Sample.hsc" #-}

getSampleVolume :: SampleHandle -> IO Int
getSampleVolume samp = fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 8)) samp :: IO UBYTE)
{-# LINE 67 "Sound/MikMod/Sample.hsc" #-}

-- | Modify the sample flags. Useful for setting the loop, reverse, and bi-directional
-- playback characteristics of the sample.
modifySampleFlags :: SampleHandle -> ([SampleFlag] -> [SampleFlag]) -> IO ()
modifySampleFlags samp f = do
  flags <- getSampleInFlags samp
  setSampleFlags samp (f flags)

-- | See 'modifySampleFlags' to avoid clobbering flags you aren't trying to
-- clear, such as the sample format flags.
setSampleFlags :: SampleHandle -> [SampleFlag] -> IO ()
setSampleFlags samp flags = ((\hsc_ptr -> pokeByteOff hsc_ptr 12)) samp (packFlags flags)
{-# LINE 79 "Sound/MikMod/Sample.hsc" #-}

getSampleFlags :: SampleHandle -> IO [SampleFlag]
getSampleFlags samp = unpackFlags <$> ((\hsc_ptr -> peekByteOff hsc_ptr 12)) samp
{-# LINE 82 "Sound/MikMod/Sample.hsc" #-}

-- | Query the "on disk" flags of the sample if you're curious about the
-- original format.
getSampleInFlags :: SampleHandle -> IO [SampleFlag]
getSampleInFlags samp = unpackFlags <$> ((\hsc_ptr -> peekByteOff hsc_ptr 10)) samp
{-# LINE 87 "Sound/MikMod/Sample.hsc" #-}

-- | Query the length of the sample... in samples.
getSampleLength :: SampleHandle -> IO Int
getSampleLength samp = fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 16)) samp :: IO ULONG)
{-# LINE 91 "Sound/MikMod/Sample.hsc" #-}

-- | Set the loop starting position in samples.
setSampleLoopStart :: SampleHandle -> Int -> IO ()
setSampleLoopStart samp start = ((\hsc_ptr -> pokeByteOff hsc_ptr 20)) samp (fromIntegral start :: ULONG)
{-# LINE 95 "Sound/MikMod/Sample.hsc" #-}

getSampleLoopStart :: SampleHandle -> IO Int
getSampleLoopStart samp = fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 20)) samp :: IO ULONG)
{-# LINE 98 "Sound/MikMod/Sample.hsc" #-}

-- | Set the loop end position in samples.
setSampleLoopEnd :: SampleHandle -> Int -> IO ()
setSampleLoopEnd samp end = ((\hsc_ptr -> pokeByteOff hsc_ptr 24)) samp (fromIntegral end :: ULONG)
{-# LINE 102 "Sound/MikMod/Sample.hsc" #-}

getSampleLoopEnd :: SampleHandle -> IO Int
getSampleLoopEnd samp = fromIntegral <$> (((\hsc_ptr -> peekByteOff hsc_ptr 24)) samp :: IO ULONG)
{-# LINE 105 "Sound/MikMod/Sample.hsc" #-}