Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
161 lines (143 sloc) 3.34 KB
{-|
Module : Bang.Music.Operators
Description : The DSL part of the Bang library
Copyright : (c) Benjamin Kovach, 2014
License : MIT
Maintainer : bkovach13@gmail.com
Stability : experimental
Portability : Mac OSX
Defines a number of operators to effectively piece together Bang compositions.
-}
module Bang.Music.Operators where
import Bang.Music.Class
import Bang.Music.Transform
import Bang.Interface.Base
import Data.Foldable(foldMap)
import Data.Monoid
-- |Infix operator for `cappend`
infixr 6 ><
(><) :: Music dur a -> Music dur a -> Music dur a
(><) = cappend
infixr 0 !>
-- |Set the `Tempo` of a composition (default 1)
--
-- Example (play 4 bass drum hits at double speed):
--
-- > 2 !> (4 #> bd)
(!>) :: Rational -> Music a b -> Music a b
(!>) = tempo
infixr 1 #>
-- |Infix operator for 'repl'
--
-- Example (play a bass drum twice):
--
-- > 2 #> bd
(#>) :: Num a => Int -> Music a b -> Music a b
(#>) = repl
infixl 1 >>~
-- |Map a function over a list of compositions and sequentially compose them.
-- Note: This is just 'foldMap' specialized to the list Monoid.
--
-- Example (play 'sn', 't1' and 't2' all twice):
--
-- > (2 #>) >>~ [sn, t1, t2]
(>>~) :: Monoid b => (a -> b) -> [a] -> b
(>>~) = foldMap
-- |Infix operator for 'poly'
--
-- Example (A 3\/4 polyrhythm):
--
-- > (3, 3 #> bd) ~=~ (4, 4 #> sn)
(~=~) :: (Dur, Music Dur b) -> (Dur, Music Dur b) -> Music Dur b
(~=~) = poly
infixl 2 ~=
-- |Infix operator for 'fitL'
--
-- Example (a 3\/4 polyrhythm with duration 3\/4):
--
-- > (3 #> bd) ~= (4 #> sn)
(~=) :: Music Dur b -> Music Dur b -> Music Dur b
(~=) = fitL
infixr 2 =~
-- |Infix operator for 'fitR'
--
-- Example (a 3\/4 polyrhythm with duration 1:
--
-- > (3 #> bd) =~ (4 #> sn)
(=~) :: Music Dur b -> Music Dur b -> Music Dur b
(=~) = fitR
infixr 2 ~~
-- |Infix operator for 'withDuration'
--
-- Example:
--
-- @
-- 2 ~~ mconcat [
-- 16 #> bd
-- , 4 #> sn
-- , wr
-- ]
-- @
(~~) :: Dur -> Music Dur b -> Music Dur b
(~~) = withDuration
infixr 2 <<~
-- |Infix operator for 'takeDur'
--
-- Example (Only play 2 bass drum hits):
--
-- > (1/2) <<~ (4 #> bd)
(<<~) :: Dur -> Music Dur b -> Music Dur b
(<<~) = takeDur
infixr 2 ~>>
-- |Infix operator for 'dropDur'
--
-- Example (play 2 closed hi-hats):
--
-- > (1/2) ~>> ( (2 #> bd) <> (2 #> hc) )
(~>>) :: Dur -> Music Dur b -> Music Dur b
(~>>) = dropDur
infixr 2 <@~
-- |Infix operator for 'hushFor'
--
-- Example (half rest, then two closed hi-hats):
--
-- > (1/2) ~@> ( (2 #> bd) <> (2 #> hc) )
(~@>) :: Dur -> Music Dur b -> Music Dur b
(~@>) = hushFor
infixr 2 ~@>
-- |Infix operator for 'hushFrom'
--
-- Example (two bass drum hits, then a half rest):
--
-- > (1/2) <@~ ( (2 #> bd) <> (2 #> hc) )
(<@~) :: Dur -> Music Dur b -> Music Dur b
(<@~) = hushFrom
infixr 0 <!>
-- |Infix operator for 'normalize'
--
-- Example (Play 12 bass drum hits, then 4 closed hi-hats, then 3 snares, each within a single measure's time):
--
-- @
-- 1 \<!\> [
-- 12 #> bd
-- , 4 #> hc
-- , 3 #> sn
-- ]
-- @
(<!>) :: Dur -> [Music Dur b] -> Music Dur b
(<!>) = normalize
infixr 0 >!<
-- |Infix operator for 'normalizeC'
--
-- Example: (Play 12 bass drum hits, then 4 closed hi-hats, then 3 snares,
-- all concurrently within a single measure's time):
--
-- @
-- 1 >!< [
-- 12 #> bd
-- , 4 #> hc
-- , 3 #> sn
-- ]
-- @
(>!<) :: Dur -> [Music Dur b] -> Music Dur b
(>!<) = normalizeC