module Synthesizer.Modifiers.Envelopes
where
import Synthesizer.Structure (Length, Sample, SamplingRate,
SoundEvent (SoundEvent))
type Step = Double
type AttackLength = Double
type DecayLength = Double
type SustainLevel = Double
type ReleaseLength = Double
type TotalLength = Length
data Envelope = Envelope {
Envelope -> AttackLength
attackLength :: AttackLength,
Envelope -> AttackLength
decayLength :: DecayLength,
Envelope -> AttackLength
sustainLevel :: SustainLevel,
Envelope -> AttackLength
releaseLength :: ReleaseLength
} deriving (Int -> Envelope -> ShowS
[Envelope] -> ShowS
Envelope -> String
(Int -> Envelope -> ShowS)
-> (Envelope -> String) -> ([Envelope] -> ShowS) -> Show Envelope
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Envelope] -> ShowS
$cshowList :: [Envelope] -> ShowS
show :: Envelope -> String
$cshow :: Envelope -> String
showsPrec :: Int -> Envelope -> ShowS
$cshowsPrec :: Int -> Envelope -> ShowS
Show)
applyEnvelope :: Envelope -> SoundEvent -> SoundEvent
applyEnvelope :: Envelope -> SoundEvent -> SoundEvent
applyEnvelope Envelope
envelope SoundEvent
soundEvent = AttackLength
-> AttackLength -> (Int -> [AttackLength]) -> SoundEvent
SoundEvent AttackLength
startTime AttackLength
newEventLength Int -> [AttackLength]
newSamples
where
SoundEvent AttackLength
startTime AttackLength
eventLength Int -> [AttackLength]
samples = SoundEvent
soundEvent
(Envelope AttackLength
attackLength AttackLength
decayLength AttackLength
sustainLevel AttackLength
releaseLength) = Envelope
envelope
newEventLength :: AttackLength
newEventLength = AttackLength
eventLength AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
+ AttackLength
releaseLength
newSamples :: SamplingRate -> [Sample]
newSamples :: Int -> [AttackLength]
newSamples Int
samplingRate = [AttackLength]
appliedSamples [AttackLength] -> [AttackLength] -> [AttackLength]
forall a. [a] -> [a] -> [a]
++ [AttackLength]
releaseSamples
where
appliedSamples :: [AttackLength]
appliedSamples = (AttackLength -> AttackLength -> AttackLength)
-> [AttackLength] -> [AttackLength] -> [AttackLength]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
(*) [AttackLength]
envelopeSteps [AttackLength]
input
input :: [AttackLength]
input = Int -> [AttackLength]
samples Int
samplingRate
releaseSamples :: [AttackLength]
releaseSamples = (AttackLength -> AttackLength -> AttackLength)
-> [AttackLength] -> [AttackLength] -> [AttackLength]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
(*) [AttackLength]
releaseSteps [AttackLength]
releaseInput
releaseInput :: [AttackLength]
releaseInput = Int -> [AttackLength] -> [AttackLength]
forall a. Int -> [a] -> [a]
drop ([AttackLength] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [AttackLength]
envelopeSteps) [AttackLength]
input
releaseSteps :: [AttackLength]
releaseSteps = [AttackLength]
rd
envelopeSteps :: [Double]
envelopeSteps :: [AttackLength]
envelopeSteps = [AttackLength]
ad [AttackLength] -> [AttackLength] -> [AttackLength]
forall a. [a] -> [a] -> [a]
++ [AttackLength]
dd [AttackLength] -> [AttackLength] -> [AttackLength]
forall a. [a] -> [a] -> [a]
++ [AttackLength]
sd
sr :: Double
sr :: AttackLength
sr = Int -> AttackLength
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
samplingRate
ad :: [Step]
ad :: [AttackLength]
ad = AttackLength -> AttackLength -> [AttackLength]
getAttackSteps AttackLength
attackLength AttackLength
sr
dd :: [Step]
dd :: [AttackLength]
dd = AttackLength -> AttackLength -> AttackLength -> [AttackLength]
getDecaySteps AttackLength
decayLength AttackLength
sustainLevel AttackLength
sr
sd :: [Step]
sd :: [AttackLength]
sd = AttackLength
-> AttackLength
-> AttackLength
-> AttackLength
-> AttackLength
-> [AttackLength]
getSustainSteps AttackLength
sustainLevel AttackLength
eventLength AttackLength
attackLength AttackLength
decayLength AttackLength
sr
rd :: [Step]
rd :: [AttackLength]
rd = AttackLength -> AttackLength -> AttackLength -> [AttackLength]
getReleaseSteps AttackLength
sustainLevel AttackLength
releaseLength AttackLength
sr
type SamplingRateConverted = Double
getAttackSteps :: AttackLength -> SamplingRateConverted -> [Step]
getAttackSteps :: AttackLength -> AttackLength -> [AttackLength]
getAttackSteps AttackLength
attackLength AttackLength
samplingRate = [AttackLength
0.0, AttackLength
step .. AttackLength
1.0]
where
step :: AttackLength
step = AttackLength
1.0 AttackLength -> AttackLength -> AttackLength
forall a. Fractional a => a -> a -> a
/ (AttackLength
attackLength AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
* AttackLength
samplingRate)
getDecaySteps :: DecayLength -> SustainLevel -> SamplingRateConverted -> [Step]
getDecaySteps :: AttackLength -> AttackLength -> AttackLength -> [AttackLength]
getDecaySteps AttackLength
0 AttackLength
sustainLevel AttackLength
samplingRate = []
getDecaySteps AttackLength
decayLength AttackLength
1 AttackLength
samplingRate = Int -> AttackLength -> [AttackLength]
forall a. Int -> a -> [a]
replicate (AttackLength -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (AttackLength
decayLength AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
* AttackLength
samplingRate)) AttackLength
1
getDecaySteps AttackLength
decayLength AttackLength
sustainLevel AttackLength
samplingRate = [AttackLength] -> [AttackLength]
forall a. [a] -> [a]
tail [AttackLength
1.0, (AttackLength
1.0 AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
- AttackLength
step) .. AttackLength
sustainLevel]
where
step :: AttackLength
step = (AttackLength
1.0 AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
- AttackLength
sustainLevel) AttackLength -> AttackLength -> AttackLength
forall a. Fractional a => a -> a -> a
/ (AttackLength
decayLength AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
* AttackLength
samplingRate)
getSustainSteps :: SustainLevel -> TotalLength -> AttackLength -> DecayLength -> SamplingRateConverted -> [Step]
getSustainSteps :: AttackLength
-> AttackLength
-> AttackLength
-> AttackLength
-> AttackLength
-> [AttackLength]
getSustainSteps AttackLength
sustainLevel AttackLength
eventLength AttackLength
attackLength AttackLength
decayLength AttackLength
samplingRate = Int -> AttackLength -> [AttackLength]
forall a. Int -> a -> [a]
replicate (AttackLength -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (AttackLength
sustainLength AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
* AttackLength
samplingRate)) AttackLength
sustainLevel
where
sustainLength :: AttackLength
sustainLength = AttackLength
eventLength AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
- AttackLength
attackLength AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
- AttackLength
decayLength
getReleaseSteps :: SustainLevel -> ReleaseLength -> SamplingRateConverted -> [Step]
getReleaseSteps :: AttackLength -> AttackLength -> AttackLength -> [AttackLength]
getReleaseSteps AttackLength
sustainLevel AttackLength
0 AttackLength
samplingRate = []
getReleaseSteps AttackLength
sustainLevel AttackLength
releaseLength AttackLength
samplingRate = [AttackLength] -> [AttackLength]
forall a. [a] -> [a]
tail [AttackLength
sustainLevel, (AttackLength
sustainLevel AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
- AttackLength
step) .. AttackLength
0.0]
where
step :: AttackLength
step = AttackLength
1 AttackLength -> AttackLength -> AttackLength
forall a. Fractional a => a -> a -> a
/ (AttackLength
releaseLength AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
* AttackLength
samplingRate) AttackLength -> AttackLength -> AttackLength
forall a. Num a => a -> a -> a
* AttackLength
sustainLevel