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 =
          forall a. Storable a => Int -> Vector a -> Vector a
SigSt.take Int
beepDur
             (forall a. (C a, C a, Storable a) => ChunkSize -> T a -> a -> T a
Osci.staticSine (Int -> ChunkSize
SigSt.chunkSize Int
beepDur) forall a. C a => a
Additive.zero a
freq)
          forall a. Storable a => Vector a -> Vector a -> Vector a
`SigSt.append`
          forall a. Storable a => ChunkSize -> Int -> a -> Vector a
SigSt.replicate ChunkSize
chunkSize (Int
beatPeriodforall a. Num a => a -> a -> a
-Int
beepDur) forall a. C a => a
Additive.zero
   in  forall a. Storable a => [Vector a] -> Vector a
SigSt.concat forall a b. (a -> b) -> a -> b
$
          forall {a}. (Storable a, C a, C a) => a -> Vector a
beep a
barBeepFreq forall a. a -> [a] -> [a]
:
          forall a. Int -> a -> [a]
replicate (Int
beatsPerBarforall a. Num a => a -> a -> a
-Int
1) (forall {a}. (Storable a, C a, C a) => a -> Vector a
beep a
beatBeepFreq)

clickTrackExample :: SigSt.T Float
clickTrackExample :: T Float
clickTrackExample =
   forall a. Storable a => [Vector a] -> Vector a
SigSt.concat forall a b. (a -> b) -> a -> b
$ forall a. Int -> a -> [a]
replicate (Int
3forall a. Num a => a -> a -> a
*Int
8) forall a b. (a -> b) -> a -> b
$
   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
84forall a. Num a => a -> a -> a
*Int
441)