lambdasound-1.1: src/LambdaSound/Sound/Types.hs
module LambdaSound.Sound.Types where
import Control.DeepSeq (NFData)
import Data.Hashable (Hashable)
import Foreign.Storable (Storable)
import GHC.Generics (Generic)
import Data.Coerce (coerce)
-- | An audio sample
newtype Pulse = Pulse Float deriving (Show, Eq, Floating, Num, Fractional, Ord, Real, RealFrac, NFData, Storable, Hashable, Enum)
-- | The duration of a 'Sound'
newtype Duration = Duration Float deriving (Show, Eq, Floating, Num, Fractional, Ord, Real, RealFrac, NFData, Storable, Hashable, Enum)
-- | The progress of a 'Sound'. A sound progresses from '0' to '1'
-- while it plays.
newtype Progress = Progress Float deriving (Show, Eq, Floating, Num, Fractional, Ord, Real, RealFrac, NFData, Storable, Hashable, Enum)
-- | The percentage of a 'Sound'. '0.3' corresponds to 30% of a 'Sound'.
newtype Percentage = Percentage Float deriving (Show, Eq, Floating, Num, Fractional, Ord, Real, RealFrac, NFData, Storable, Hashable, Enum)
-- | Hz are the unit for frequencies. 440 Hz means that 440 oscillations happen per second
newtype Hz = Hz Float deriving (Show, Eq, Ord, Num, Fractional, Floating, Enum, Generic, Real, RealFrac)
-- | Time progresses while a 'Sound' is playing and is used to create samples.
-- It is not guaranteed that 'Time' will correspond to the real runtime of a 'Sound'
newtype Time = Time Float deriving (Show, Eq, Floating, Num, Fractional, Ord, Real, RealFrac, NFData, Storable, Hashable, Enum)
-- | Gives information about how many samples are needed during computation
data SamplingInfo = SamplingInfo
{ period :: !Float,
sampleRate :: Hz,
samples :: Int
}
deriving (Generic, Show, Eq)
instance Hashable Hz
instance Hashable SamplingInfo where
makeSamplingInfo :: Hz -> Duration -> SamplingInfo
makeSamplingInfo hz duration =
let period = coerce $ 1 / hz
in SamplingInfo period hz (round $ coerce duration / period)