module Synthesizer.Storable.Generate where

import qualified Synthesizer.Storable.Oscillator as Osci
import qualified Synthesizer.Storable.Signal as SigSt

import qualified Algebra.Additive as Additive
import qualified Algebra.RealRing as RealRing
import qualified Algebra.Transcendental as Trans

import Foreign.Storable (Storable, )


{- |
@clickTrack silenceChunkSize barBeepFreq beatBeepFreq beepDur beatsPerBar beatPeriod@
generates click track for one bar.
You may cycle it infinitely or replicate it as often as you want.
-}
clickTrack ::
   (RealRing.C a, Trans.C a, Storable a) =>
   SigSt.ChunkSize ->
   a -> a -> Int -> Int -> Int -> SigSt.T a
clickTrack :: forall a.
(C a, C a, Storable a) =>
ChunkSize -> a -> a -> Int -> Int -> Int -> T a
clickTrack ChunkSize
chunkSize
      a
barBeepFreq a
beatBeepFreq Int
beepDur Int
beatsPerBar Int
beatPeriod =
   let beep :: a -> Vector a
beep a
freq =
          Int -> Vector a -> Vector a
forall a. Storable a => Int -> Vector a -> Vector a
SigSt.take Int
beepDur
             (ChunkSize -> T a -> a -> Vector a
forall a. (C a, C a, Storable a) => ChunkSize -> T a -> a -> T a
Osci.staticSine (Int -> ChunkSize
SigSt.chunkSize Int
beepDur) T a
forall a. C a => a
Additive.zero a
freq)
          Vector a -> Vector a -> Vector a
forall a. Storable a => Vector a -> Vector a -> Vector a
`SigSt.append`
          ChunkSize -> Int -> a -> Vector a
forall a. Storable a => ChunkSize -> Int -> a -> Vector a
SigSt.replicate ChunkSize
chunkSize (Int
beatPeriodInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
beepDur) a
forall a. C a => a
Additive.zero
   in  [Vector a] -> Vector a
forall a. Storable a => [Vector a] -> Vector a
SigSt.concat ([Vector a] -> Vector a) -> [Vector a] -> Vector a
forall a b. (a -> b) -> a -> b
$
          a -> Vector a
forall {a}. (Storable a, C a, C a) => a -> Vector a
beep a
barBeepFreq Vector a -> [Vector a] -> [Vector a]
forall a. a -> [a] -> [a]
:
          Int -> Vector a -> [Vector a]
forall a. Int -> a -> [a]
replicate (Int
beatsPerBarInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (a -> Vector a
forall {a}. (Storable a, C a, C a) => a -> Vector a
beep a
beatBeepFreq)

clickTrackExample :: SigSt.T Float
clickTrackExample :: T Float
clickTrackExample =
   [T Float] -> T Float
forall a. Storable a => [Vector a] -> Vector a
SigSt.concat ([T Float] -> T Float) -> [T Float] -> T Float
forall a b. (a -> b) -> a -> b
$ Int -> T Float -> [T Float]
forall a. Int -> a -> [a]
replicate (Int
3Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
8) (T Float -> [T Float]) -> T Float -> [T Float]
forall a b. (a -> b) -> a -> b
$
   ChunkSize -> Float -> Float -> Int -> Int -> Int -> T Float
forall a.
(C a, C a, Storable a) =>
ChunkSize -> a -> a -> Int -> Int -> Int -> T a
clickTrack ChunkSize
SigSt.defaultChunkSize Float
0.04 Float
0.02 Int
500 Int
4 (Int
84Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
441)