-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Haskell Music Theory -- @package hmt @version 0.15 -- | Robert Morris and D. Starr. "The Structure of All-Interval Series". -- Journal of Music Theory, 18:364-389, 1974. module Music.Theory.Z12.Morris_1974 -- | msum . map return. -- --
--   observeAll (fromList [1..7]) == [1..7]
--   
fromList :: MonadPlus m => [a] -> m a -- | MonadPlus all-interval series. -- --
--   [0,1,3,2,9,5,10,4,7,11,8,6] `elem` observeAll (all_interval_m 12)
--   length (observeAll (all_interval_m 12)) == 3856
--   map (length . observeAll . all_interval_m) [4,6,8,10] == [2,4,24,288]
--   
all_interval_m :: MonadPlus m => Int -> m [Int] -- | observeAll of all_interval_m. -- --
--   let r = [[0,1,5,2,4,3],[0,2,1,4,5,3],[0,4,5,2,1,3],[0,5,1,4,2,3]]
--   in all_interval 6 == r
--   
all_interval :: Int -> [[Int]] -- | Z12 set class database. module Music.Theory.Z12.Literature -- | Set class database with descriptors for historically and theoretically -- significant set classes, indexed by Forte name. -- --
--   lookup "6-Z17" sc_db == Just "All-Trichord Hexachord"
--   lookup "7-35" sc_db == Just "diatonic collection (d)"
--   
sc_db :: [(String, String)] -- | Generalised Z-n functions. module Music.Theory.Z lift_unary_Z :: Integral a => a -> (t -> a) -> t -> a lift_binary_Z :: Integral a => a -> (s -> t -> a) -> s -> t -> a z_add :: Integral a => a -> a -> a -> a z_sub :: Integral a => a -> a -> a -> a z_mul :: Integral a => a -> a -> a -> a z_negate :: Integral a => a -> a -> a z_fromInteger :: Integral a => a -> Integer -> a z_signum :: t -> t1 -> t2 z_abs :: t -> t1 -> t2 to_Z :: Integral i => i -> i -> i from_Z :: (Integral i, Num n) => i -> n -- | Z not in set. -- --
--   z_complement 5 [0,2,3] == [1,4]
--   z_complement 12 [0,2,4,5,7,9,11] == [1,3,6,8,10]
--   
z_complement :: (Enum a, Eq a, Num a) => a -> [a] -> [a] z_quot :: Integral i => i -> i -> i -> i z_rem :: Integral c => c -> c -> c -> c z_div :: Integral c => c -> c -> c -> c z_mod :: Integral c => c -> c -> c -> c z_quotRem :: Integral t => t -> t -> t -> (t, t) z_divMod :: Integral t => t -> t -> t -> (t, t) z_toInteger :: Integral i => i -> i -> i -- | Serial (ordered) pitch-class operations on Z. module Music.Theory.Z.SRO -- | Transpose p by n. -- --
--   tn 5 4 [0,1,4] == [4,0,3]
--   tn 12 4 [1,5,6] == [5,9,10]
--   
tn :: (Integral i, Functor f) => i -> i -> f i -> f i -- | Invert p about n. -- --
--   invert 5 0 [0,1,4] == [0,4,1]
--   invert 12 6 [4,5,6] == [8,7,6]
--   invert 12 0 [0,1,3] == [0,11,9]
--   
invert :: (Integral i, Functor f) => i -> i -> f i -> f i -- | Composition of invert about 0 and tn. -- --
--   tni 5 1 [0,1,3] == [1,0,3]
--   tni 12 4 [1,5,6] == [3,11,10]
--   (invert 12 0 . tn  12 4) [1,5,6] == [7,3,2]
--   
tni :: (Integral i, Functor f) => i -> i -> f i -> f i -- | Modulo multiplication. -- --
--   mn 12 11 [0,1,4,9] == tni 12 0 [0,1,4,9]
--   
mn :: (Integral i, Functor f) => i -> i -> f i -> f i -- | T-related sequences of p. -- --
--   length (t_related 12 [0,3,6,9]) == 12
--   
t_related :: (Integral i, Functor f) => i -> f i -> [f i] -- | T/I-related sequences of p. -- --
--   length (ti_related 12 [0,1,3]) == 24
--   length (ti_related 12 [0,3,6,9]) == 24
--   ti_related 12 [0] == map return [0..11]
--   
ti_related :: (Eq (f i), Integral i, Functor f) => i -> f i -> [f i] -- | R/T/I-related sequences of p. -- --
--   length (rti_related 12 [0,1,3]) == 48
--   length (rti_related 12 [0,3,6,9]) == 24
--   
rti_related :: Integral i => i -> [i] -> [[i]] -- | Variant of tn, transpose p so first element is n. -- --
--   tn_to 12 5 [0,1,3] == [5,6,8]
--   map (tn_to 12 0) [[0,1,3],[1,3,0],[3,0,1]]
--   
tn_to :: Integral a => a -> a -> [a] -> [a] -- | Variant of invert, inverse about nth element. -- --
--   map (invert_ix 12 0) [[0,1,3],[3,4,6]] == [[0,11,9],[3,2,0]]
--   map (invert_ix 12 1) [[0,1,3],[3,4,6]] == [[2,1,11],[5,4,2]]
--   
invert_ix :: Integral i => i -> Int -> [i] -> [i] -- | The standard t-matrix of p. -- --
--   tmatrix 12 [0,1,3] == [[0,1,3]
--                         ,[11,0,2]
--                         ,[9,10,0]]
--   
tmatrix :: Integral i => i -> [i] -> [[i]] -- | Ronald C. Read. "Every one a winner or how to avoid isomorphism search -- when cataloguing combinatorial configurations." /Annals of Discrete -- Mathematics/ 2:107–20, 1978. module Music.Theory.Z.Read_1978 -- | Coding. type Code = Int -- | Bit array. type Array = [Bool] -- | Pretty printer for Array. array_pp :: Array -> String -- | Parse PP of Array. -- --
--   parse_array "01001" == [False,True,False,False,True]
--   
parse_array :: String -> Array -- | Generate Code from Array, the coding is most to least -- significant. -- --
--   array_to_code (map toEnum [1,1,0,0,1,0,0,0,1,1,1,0,0]) == 6428
--   
array_to_code :: Array -> Code -- | Inverse of array_to_code. -- --
--   code_to_array 13 6428 == map toEnum [1,1,0,0,1,0,0,0,1,1,1,0,0]
--   
code_to_array :: Int -> Code -> Array -- | Array to set. -- --
--   array_to_set (map toEnum [1,1,0,0,1,0,0,0,1,1,1,0,0]) == [0,1,4,8,9,10]
--   T.encode [0,1,4,8,9,10] == 1811
--   
array_to_set :: Integral i => [Bool] -> [i] -- | Inverse of array_to_set, z is the degree of the array. set_to_array :: Integral i => i -> [i] -> Array -- | array_to_code of set_to_array. -- --
--   set_to_code 12 [0,2,3,5]
--   map (set_to_code 12) (T.ti_related 12 [0,2,3,5])
--   
set_to_code :: Integral i => i -> [i] -> Code -- | Logical complement. array_complement :: Array -> Array -- | The prime form is the maximum encoding. -- --
--   array_is_prime (set_to_array 12 [0,2,3,5]) == False
--   
array_is_prime :: Array -> Bool -- | The augmentation rule adds 1 in each empty slot at end of -- array. -- --
--   map array_pp (array_augment (parse_array "01000")) == ["01100","01010","01001"]
--   
array_augment :: Array -> [Array] -- | Enumerate first half of the set-classes under given prime -- function. The second half can be derived as the complement of the -- first. -- --
--   import Music.Theory.Z12.Forte_1973
--   length scs == 224
--   map (length . scs_n) [0..12] == [1,1,6,12,29,38,50,38,29,12,6,1,1]
--   
-- --
--   let z12 = map (fmap (map array_to_set)) (enumerate_half array_is_prime 12)
--   map (length . snd) z12 == [1,1,6,12,29,38,50]
--   
-- -- This can become slow, edit z to find out. It doesn't matter -- about n. This can be edited so that small n would run -- quickly even for large z. -- --
--   fmap (map array_to_set) (lookup 5 (enumerate_half array_is_prime 16))
--   
enumerate_half :: (Array -> Bool) -> Int -> [(Int, [Array])] -- | Encoder for encode_prime. -- --
--   encode [0,1,3,6,8,9] == 843
--   
encode :: Integral i => [i] -> Code -- | Decoder for encode_prime. -- --
--   decode 12 843 == [0,1,3,6,8,9]
--   
decode :: Integral i => i -> Code -> [i] -- | Binary encoding prime form algorithm, equalivalent to Rahn. -- --
--   encode_prime 12 [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   Music.Theory.Z12.Rahn_1980.rahn_prime [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   
encode_prime :: Integral i => i -> [i] -> [i] -- | http://www.unicode.org/charts/PDF/U1D100.pdf module Music.Theory.Unicode type Unicode_Table = [(Int, String)] unicode :: [Unicode_Table] accidentals :: Unicode_Table notes :: Unicode_Table rests :: Unicode_Table clefs :: Unicode_Table -- | Tuple functions. -- -- Uniform tuples have types T2, T3 etc. and functions -- names are prefixed t2_ etc. -- -- Heterogenous tuples (products) are prefixed p2_ etc. module Music.Theory.Tuple p2_swap :: (s, t) -> (t, s) -- | Uniform two-tuple. type T2 a = (a, a) t2 :: [t] -> T2 t t2_list :: T2 a -> [a] t2_swap :: T2 t -> T2 t t2_map :: (p -> q) -> T2 p -> T2 q t2_zipWith :: (p -> q -> r) -> T2 p -> T2 q -> T2 r t2_infix :: (a -> a -> b) -> T2 a -> b -- | Infix mappend. -- --
--   t2_join ([1,2],[3,4]) == [1,2,3,4]
--   
t2_join :: Monoid m => T2 m -> m t2_concat :: [T2 [a]] -> T2 [a] t2_sort :: Ord t => (t, t) -> (t, t) -- | Left rotation. -- --
--   p3_rotate_left (1,2,3) == (2,3,1)
--   
p3_rotate_left :: (s, t, u) -> (t, u, s) p3_fst :: (a, b, c) -> a p3_snd :: (a, b, c) -> b p3_third :: (a, b, c) -> c type T3 a = (a, a, a) t3 :: [t] -> T3 t t3_rotate_left :: T3 t -> T3 t t3_fst :: T3 t -> t t3_snd :: T3 t -> t t3_third :: T3 t -> t t3_map :: (p -> q) -> T3 p -> T3 q t3_zipWith :: (p -> q -> r) -> T3 p -> T3 q -> T3 r t3_list :: T3 a -> [a] t3_infix :: (a -> a -> a) -> T3 a -> a t3_join :: T3 [a] -> [a] p4_fst :: (a, b, c, d) -> a p4_snd :: (a, b, c, d) -> b p4_third :: (a, b, c, d) -> c p4_fourth :: (a, b, c, d) -> d type T4 a = (a, a, a, a) t4 :: [t] -> T4 t t4_list :: T4 t -> [t] t4_fst :: T4 t -> t t4_snd :: T4 t -> t t4_third :: T4 t -> t t4_fourth :: T4 t -> t t4_map :: (p -> q) -> T4 p -> T4 q t4_zipWith :: (p -> q -> r) -> T4 p -> T4 q -> T4 r t4_infix :: (a -> a -> a) -> T4 a -> a t4_join :: T4 [a] -> [a] p5_fst :: (a, b, c, d, e) -> a p5_snd :: (a, b, c, d, e) -> b p5_third :: (a, b, c, d, e) -> c p5_fourth :: (a, b, c, d, e) -> d p5_fifth :: (a, b, c, d, e) -> e type T5 a = (a, a, a, a, a) t5 :: [t] -> T5 t t5_list :: T5 t -> [t] t5_map :: (p -> q) -> T5 p -> T5 q t5_fst :: T5 t -> t t5_snd :: T5 t -> t t5_fourth :: T5 t -> t t5_fifth :: T5 t -> t t5_infix :: (a -> a -> a) -> T5 a -> a t5_join :: T5 [a] -> [a] p6_fst :: (a, b, c, d, e, f) -> a p6_snd :: (a, b, c, d, e, f) -> b p6_third :: (a, b, c, d, e, f) -> c p6_fourth :: (a, b, c, d, e, f) -> d p6_fifth :: (a, b, c, d, e, f) -> e p6_sixth :: (a, b, c, d, e, f) -> f type T6 a = (a, a, a, a, a, a) t6 :: [t] -> T6 t t6_list :: T6 t -> [t] t6_map :: (p -> q) -> T6 p -> T6 q type T7 a = (a, a, a, a, a, a, a) t7_list :: T7 t -> [t] t7_map :: (p -> q) -> T7 p -> T7 q type T8 a = (a, a, a, a, a, a, a, a) t8_list :: T8 t -> [t] t8_map :: (p -> q) -> T8 p -> T8 q type T9 a = (a, a, a, a, a, a, a, a, a) t9_list :: T9 t -> [t] t9_map :: (p -> q) -> T9 p -> T9 q module Music.Theory.Time.Notation -- | Fractional seconds. type FSEC = Double -- | Minutes, seconds as (min,sec) type MINSEC = (Int, Int) -- | Minutes, seconds, centi-seconds as (min,sec,csec) type MINCSEC = (Int, Int, Int) -- | Fractional seconds to (min,sec). -- --
--   map fsec_to_minsec [59.49,60,60.51] == [(0,59),(1,0),(1,1)]
--   
fsec_to_minsec :: FSEC -> MINSEC -- | MINSEC pretty printer. -- --
--   map (minsec_pp . fsec_to_minsec) [59,61] == ["00:59","01:01"]
--   
minsec_pp :: MINSEC -> String -- | Fractional seconds to (min,sec,csec). -- --
--   map fsec_to_mincsec [1,1.5,4/3] == [(0,1,0),(0,1,50),(0,1,33)]
--   
fsec_to_mincsec :: FSEC -> MINCSEC -- | MINCSEC pretty printer. -- --
--   map (mincsec_pp . fsec_to_mincsec) [1,4/3] == ["00:01.00","00:01.33"]
--   
mincsec_pp :: MINCSEC -> String span_pp :: (t -> String) -> (t, t) -> String module Music.Theory.Time.Duration -- | Duration stored as hours, minutes, seconds and -- milliseconds. data Duration Duration :: Int -> Int -> Int -> Int -> Duration hours :: Duration -> Int minutes :: Duration -> Int seconds :: Duration -> Int milliseconds :: Duration -> Int -- | Convert fractional seconds to integral -- (seconds,milliseconds). -- --
--   s_sms 1.75 == (1,750)
--   
s_sms :: (RealFrac n, Integral i) => n -> (i, i) -- | Inverse of s_sms. -- --
--   sms_s (1,750) == 1.75
--   
sms_s :: Integral i => (i, i) -> Double -- | Read function for Duration tuple. read_duration_tuple :: String -> (Int, Int, Int, Int) -- | Read function for Duration. Allows either -- H:M:S.MS or M:S.MS or S.MS. -- --
--   read_duration "01:35:05.250" == Duration 1 35 5 250
--   read_duration    "35:05.250" == Duration 0 35 5 250
--   read_duration       "05.250" == Duration 0 0 5 250
--   
read_duration :: String -> Duration -- | Show function for Duration. -- --
--   show_duration (Duration 1 35 5 250) == "01:35:05.250"
--   show (Duration 1 15 0 000) == "01:15:00.000"
--   
show_duration :: Duration -> String normalise_minutes :: Duration -> Duration normalise_seconds :: Duration -> Duration normalise_milliseconds :: Duration -> Duration normalise_duration :: Duration -> Duration -- | Extract Duration tuple applying filter function at each element -- --
--   duration_tuple id (Duration 1 35 5 250) == (1,35,5,250)
--   
duration_to_tuple :: (Int -> a) -> Duration -> (a, a, a, a) -- | Inverse of duration_to_tuple. tuple_to_duration :: (a -> Int) -> (a, a, a, a) -> Duration duration_to_hours :: Fractional n => Duration -> n duration_to_minutes :: Fractional n => Duration -> n duration_to_seconds :: Fractional n => Duration -> n hours_to_duration :: RealFrac a => a -> Duration minutes_to_duration :: RealFrac a => a -> Duration seconds_to_duration :: RealFrac a => a -> Duration nil_duration :: Duration negate_duration :: Duration -> Duration duration_diff :: Duration -> Duration -> Duration instance Eq Duration instance Show Duration instance Read Duration module Music.Theory.Tiling.Canon -- | Sequence. type S = [Int] -- | Canon of (period,sequence,multipliers,displacements). type R = (Int, S, [Int], [Int]) -- | Voice. type V = [Int] -- | Tiling (sequence) type T = [[Int]] -- | Cycle at period. -- --
--   take 9 (p_cycle 18 [0,2,5]) == [0,2,5,18,20,23,36,38,41]
--   
p_cycle :: Int -> [Int] -> [Int] -- | Element of (sequence,multiplier,displacement). type E = (S, Int, Int) -- | Resolve sequence from E. -- --
--   e_to_seq ([0,2,5],2,1) == [1,5,11]
--   e_to_seq ([0,1],3,4) == [4,7]
--   e_to_seq ([0],1,2) == [2]
--   
e_to_seq :: E -> [Int] -- | Infer E from sequence. -- --
--   e_from_seq [1,5,11] == ([0,2,5],2,1)
--   e_from_seq [4,7] == ([0,1],3,4)
--   e_from_seq [2] == ([0],1,2)
--   
e_from_seq :: [Int] -> E -- | Set of V from R. r_voices :: R -> [V] -- | concatMap of r_voices. rr_voices :: [R] -> [V] -- | Retrograde of T, the result T is sorted. -- --
--   let r = [[0,7,14],[1,5,9],[2,4,6],[3,8,13],[10,11,12]]
--   in t_retrograde [[0,7,14],[1,6,11],[2,3,4],[5,9,13],[8,10,12]] == r
--   
t_retrograde :: T -> T -- | The normal form of T is the min of t and it's -- t_retrograde. -- --
--   let r = [[0,7,14],[1,5,9],[2,4,6],[3,8,13],[10,11,12]]
--   in t_normal [[0,7,14],[1,6,11],[2,3,4],[5,9,13],[8,10,12]] == r
--   
t_normal :: T -> T -- | Derive set of R from T. -- --
--   let {r = [(21,[0,1,2],[10,8,2,4,7,5,1],[0,1,2,3,5,8,14])]
--       ;t = [[0,10,20],[1,9,17],[2,4,6],[3,7,11],[5,12,19],[8,13,18],[14,15,16]]}
--   in r_from_t t == r
--   
r_from_t :: T -> [R] -- | msum . map return. -- --
--   observeAll (fromList [1..7]) == [1..7]
--   
fromList :: MonadPlus m => [a] -> m a -- | Search for perfect tilings of the sequence S using -- multipliers from m to degree n with k parts. perfect_tilings_m :: MonadPlus m => [S] -> [Int] -> Int -> Int -> m T -- | t_normal of observeAll of perfect_tilings_m. -- --
--   perfect_tilings [[0,1]] [1..3] 6 3 == []
--   
-- --
--   let r = [[[0,7,14],[1,5,9],[2,4,6],[3,8,13],[10,11,12]]]
--   in perfect_tilings [[0,1,2]] [1,2,4,5,7] 15 5 == r
--   
-- --
--   length (perfect_tilings [[0,1,2]] [1..12] 15 5) == 1
--   
-- --
--   let r = [[[0,1],[2,5],[3,7],[4,6]]
--           ,[[0,1],[2,6],[3,5],[4,7]]
--           ,[[0,2],[1,4],[3,7],[5,6]]]
--   in perfect_tilings [[0,1]] [1..4] 8 4 == r
--   
-- --
--   let r = [[[0,1],[2,5],[3,7],[4,9],[6,8]]
--           ,[[0,1],[2,7],[3,5],[4,8],[6,9]]
--           ,[[0,2],[1,4],[3,8],[5,9],[6,7]]
--           ,[[0,2],[1,5],[3,6],[4,9],[7,8]]
--           ,[[0,3],[1,6],[2,4],[5,9],[7,8]]]
--   in perfect_tilings [[0,1]] [1..5] 10 5 == r
--   
-- -- Johnson 2004, p.2 -- --
--   let r = [[0,6,12],[1,8,15],[2,11,20],[3,5,7],[4,9,14],[10,13,16],[17,18,19]]
--   in perfect_tilings [[0,1,2]] [1,2,3,5,6,7,9] 21 7 == [r]
--   
-- --
--   let r = [[0,10,20],[1,9,17],[2,4,6],[3,7,11],[5,12,19],[8,13,18],[14,15,16]]
--   in perfect_tilings [[0,1,2]] [1,2,4,5,7,8,10] 21 7 == [t_retrograde r]
--   
perfect_tilings :: [S] -> [Int] -> Int -> Int -> [T] -- | Variant of elem for ordered sequences, which can therefore -- return False when searching infinite sequences. -- --
--   5 `elemOrd` [0,2..] == False && 10 `elemOrd` [0,2..] == True
--   
elemOrd :: Ord a => a -> [a] -> Bool -- | A .* diagram of n places of V. -- --
--   v_dot_star 18 [0,2..] == "*.*.*.*.*.*.*.*.*."
--   
v_dot_star :: Int -> V -> String -- | A white space and index diagram of n places of V. -- --
--   >>> mapM_ (putStrLn . v_space_ix 9) [[0,2..],[1,3..]]
--   >
--   >  0   2   4   6   8
--   >    1   3   5   7
--   
v_space_ix :: Int -> V -> String -- | Insert | every n places. -- --
--   with_bars 6 (v_dot_star 18 [0,2..]) == "*.*.*.|*.*.*.|*.*.*."
--   
with_bars :: Int -> String -> String -- | Variant with measure length m and number of measures n. -- --
--   v_dot_star_m 6 3 [0,2..] == "*.*.*.|*.*.*.|*.*.*."
--   
v_dot_star_m :: Int -> Int -> V -> String -- | Print .* diagram. v_print :: Int -> [V] -> IO () -- | Variant to print | at measures. v_print_m :: Int -> Int -> [V] -> IO () -- | Variant that discards first k measures. v_print_m_from :: Int -> Int -> Int -> [V] -> IO () -- | Tom Johnson. "Perfect Rhythmic Tilings". Technical report, IRCAM, 24 -- January 2004. MaMuX Lecture. module Music.Theory.Tiling.Johnson_2004 -- | {0,1,2} order 5, p.1 -- --
--   >>> v_print 15 (r_voices p1)
--   >
--   > ..***..........
--   > ........*.*.*..
--   > .....*...*...*.
--   > .*....*....*...
--   > *......*......*
--   
p1 :: R -- | {0,1,2} order 7, p.2 -- --
--   >>> v_print 21 (r_voices p2)
--   >
--   > ..............***....
--   > ..*.*.*..............
--   > ...*...*...*.........
--   > ........*....*....*..
--   > .....*......*......*.
--   > .*.......*.......*...
--   > *.........*.........*
--   
p2 :: R -- | {0,1} order 4, p.3 -- --
--   >>> v_print 8 (r_voices p3)
--   >
--   > *...*...
--   > .**.....
--   > ...*..*.
--   > .....*.*
--   
p3 :: R -- | {0,1} order 5, p.4 -- --
--   >>> mapM_ (v_print 10 . r_voices) p4
--   >
--   > *...*.....
--   > .**.......
--   > ...*....*.
--   > .....*.*..
--   > ......*..*
--   >
--   > *....*....
--   > .**.......
--   > ...*..*...
--   > ....*...*.
--   > .......*.*
--   >
--   > *...*.....
--   > .*....*...
--   > ..**......
--   > .....*..*.
--   > .......*.*
--   
p4 :: [R] -- | Open {1,2,3} order 5, p.4 -- --
--   >>> v_print 18 (r_voices p4_b)
--   >
--   > ...***............
--   > ........*.*.*.....
--   > .........*...*...*
--   > .*....*....*......
--   > *......*......*...
--   
p4_b :: R -- | Tom Johnson. "Tiling in my Music". The Experimental Music -- Yearbook, 1, 2009. module Music.Theory.Tiling.Johnson_2009 -- | Tilework for Clarinet, p.3 -- --
--   >>> v_print 36 (rr_voices p3)
--   >
--   > *.*..*............*.*..*............
--   > .*.*..*............*.*..*...........
--   > ........*.*..*............*.*..*....
--   > ....*..*.*............*..*.*........
--   > ...........*..*.*............*..*.*.
--   > ............*..*.*............*..*.*
--   
p3 :: [R] -- | Tilework for String Quartet, p.5 -- --
--   >>> mapM_ (v_print 24 . r_voices) p5
--   >
--   > ******......******......
--   > ......******......******
--   >
--   > *.****.*....*.****.*....
--   > ......*.****.*....*.****
--   >
--   > **.***..*...**.***..*...
--   > ......**.***..*...**.***
--   >
--   > *..***.**...*..***.**...
--   > ......*..***.**...*..***
--   
p5 :: [R] -- | Extra Perfect (p.7) -- --
--   >>> v_print_m_from 18 6 6 (r_voices p7)
--   >
--   > **.*..|......|......|......|......|......
--   > ......|.*.*..|.*....|......|......|......
--   > ......|......|......|......|.*..*.|....*.
--   > ......|......|...*..|.*....|...*..|......
--   > ......|......|....*.|...*..|......|.*....
--   > ......|*.....|*.....|......|*.....|......
--   > ....*.|......|......|*.....|......|...*..
--   > ......|......|......|....*.|......|*.....
--   
p7 :: R -- | Tilework for Log Drums (2005), p.10 -- --
--   >>> v_print 18 (r_voices p10)
--   >
--   > *.*.*.............
--   > .*...*...*........
--   > ...*...*...*......
--   > ......*...*...*...
--   > ........*...*...*.
--   > .............*.*.*
--   
p10 :: R -- | Self-Similar Melodies (1996), p.11 -- --
--   >>> v_print_m 20 5 (r_voices p11)
--   >
--   > *.....*.....*..*..*.|....*.....*.....*...|..*..*..*.....*.....|*.....*.....*..*..*.|....*.....*.....*...
--   > ....................|*.....*.....*..*..*.|....*.....*.....*...|..*..*..*.....*.....|*.....*.....*..*..*.
--   > ....................|....................|*.....*.....*..*..*.|....*.....*.....*...|..*..*..*.....*.....
--   
p11 :: R module Music.Theory.Z12 -- | Z12 are modulo 12 integers. -- --
--   map signum [-1,0::Z12,1] == [1,0,1]
--   map abs [-1,0::Z12,1] == [11,0,1]
--   
newtype Z12 Z12 :: Int -> Z12 -- | Cyclic Enum instance for Z12. -- --
--   pred (0::Z12) == 11
--   succ (11::Z12) == 0
--   [9::Z12 .. 3] == [9,10,11,0,1,2,3]
--   [9::Z12,11 .. 3] == [9,11,1,3]
--   
-- | Bounded instance for Z12. -- --
--   [minBound::Z12 .. maxBound] == [0::Z12 .. 11]
--   
-- | The Z12 modulo (ie. 12) as a Z12 value. This is -- required when lifting generalised Z functions to Z12. -- It is not the same as writing 12::Z12. -- --
--   z12_modulo == Z12 12
--   z12_modulo /= 12
--   (12::Z12) == 0
--   show z12_modulo == "(Z12 12)"
--   
z12_modulo :: Z12 -- | Basis for Z12 show instance. -- --
--   map show [-1,0::Z12,1,z12_modulo] == ["11","0","1","(Z12 12)"]
--   
z12_showsPrec :: Int -> Z12 -> ShowS -- | Lift unary function over integers to Z12. -- --
--   lift_unary_Z12 (negate) 7 == 5
--   
lift_unary_Z12 :: (Int -> Int) -> Z12 -> Z12 -- | Lift unary function over integers to Z12. -- --
--   map (lift_binary_Z12 (+) 4) [1,5,6] == [5,9,10]
--   
lift_binary_Z12 :: (Int -> Int -> Int) -> Z12 -> Z12 -> Z12 -- | Raise an error if the internal Z12 value is negative. check_negative :: (Int -> Int) -> Z12 -> Z12 -- | Convert integral to Z12. -- --
--   map to_Z12 [-9,-3,0,13] == [3,9,0,1]
--   
to_Z12 :: Integral i => i -> Z12 -- | Convert Z12 to integral. from_Z12 :: Integral i => Z12 -> i -- | Z12 not in set. -- --
--   complement [0,2,4,5,7,9,11] == [1,3,6,8,10]
--   
complement :: [Z12] -> [Z12] instance Eq Z12 instance Ord Z12 instance Integral Z12 instance Real Z12 instance Num Z12 instance Show Z12 instance Bounded Z12 instance Enum Z12 -- | Pitch-class set (unordered) operations on Z12. module Music.Theory.Z12.TTO -- | Map to pitch-class and reduce to set. -- --
--   pcset [1,13] == [1]
--   
pcset :: Integral a => [a] -> [Z12] -- | Transpose by n. -- --
--   tn 4 [1,5,6] == [5,9,10]
--   tn 4 [0,4,8] == [0,4,8]
--   
tn :: Z12 -> [Z12] -> [Z12] -- | Invert about n. -- --
--   invert 6 [4,5,6] == [6,7,8]
--   invert 0 [0,1,3] == [0,9,11]
--   
invert :: Z12 -> [Z12] -> [Z12] -- | Composition of invert about 0 and tn. -- --
--   tni 4 [1,5,6] == [3,10,11]
--   (invert 0 . tn  4) [1,5,6] == [2,3,7]
--   
tni :: Z12 -> [Z12] -> [Z12] -- | Modulo 12 multiplication -- --
--   mn 11 [0,1,4,9] == invert 0 [0,1,4,9]
--   
mn :: Z12 -> [Z12] -> [Z12] -- | M5, ie. mn 5. -- --
--   m5 [0,1,3] == [0,3,5]
--   
m5 :: [Z12] -> [Z12] -- | T-related sets of p. -- --
--   length (t_related [0,1,3]) == 12
--   t_related [0,3,6,9] == [[0,3,6,9],[1,4,7,10],[2,5,8,11]]
--   
t_related :: [Z12] -> [[Z12]] -- | T/I-related set of p. -- --
--   length (ti_related [0,1,3]) == 24
--   ti_related [0,3,6,9] == [[0,3,6,9],[1,4,7,10],[2,5,8,11]]
--   
ti_related :: [Z12] -> [[Z12]] -- | Ronald C. Read. "Every one a winner or how to avoid isomorphism search -- when cataloguing combinatorial configurations." /Annals of Discrete -- Mathematics/ 2:107–20, 1978. module Music.Theory.Z12.Read_1978 type Code = Code -- | Encoder for encode_prime. -- --
--   encode [0,1,3,6,8,9] == 843
--   
encode :: [Z12] -> Code -- | Decoder for encode_prime. -- --
--   decode 843 == [0,1,3,6,8,9]
--   
decode :: Code -> [Z12] -- | Binary encoding prime form algorithm, equalivalent to Rahn. -- --
--   encode_prime [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   Music.Theory.Z12.Rahn_1980.rahn_prime [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   
encode_prime :: [Z12] -> [Z12] -- | Extensions to Data.Maybe. module Music.Theory.Maybe -- | Variant of unzip. -- --
--   let r = ([Just 1,Nothing,Just 3],[Just 'a',Nothing,Just 'c'])
--   in maybe_unzip [Just (1,'a'),Nothing,Just (3,'c')] == r
--   
maybe_unzip :: [Maybe (a, b)] -> ([Maybe a], [Maybe b]) -- | Replace Nothing elements with last Just value. This does -- not alter the length of the list. -- --
--   maybe_latch 1 [Nothing,Just 2,Nothing,Just 4] == [1,2,2,4]
--   
maybe_latch :: a -> [Maybe a] -> [a] -- | Variant requiring initial value is not Nothing. -- --
--   maybe_latch1 [Just 1,Nothing,Nothing,Just 4] == [1,1,1,4]
--   
maybe_latch1 :: [Maybe a] -> [a] -- | map of fmap. -- --
--   maybe_map negate [Nothing,Just 2] == [Nothing,Just (-2)]
--   
maybe_map :: (a -> b) -> [Maybe a] -> [Maybe b] -- | If either is Nothing then False, else eq of -- values. maybe_eq_by :: (t -> u -> Bool) -> Maybe t -> Maybe u -> Bool -- | Join two values, either of which may be missing. maybe_join' :: (s -> t) -> (s -> s -> t) -> Maybe s -> Maybe s -> Maybe t -- | maybe_join' of id maybe_join :: (t -> t -> t) -> Maybe t -> Maybe t -> Maybe t -- | Apply predicate inside Maybe. -- --
--   maybe_predicate even (Just 3) == Nothing
--   
maybe_predicate :: (a -> Bool) -> Maybe a -> Maybe a -- | map of maybe_predicate. -- --
--   let r = [Nothing,Nothing,Nothing,Just 4]
--   in maybe_filter even [Just 1,Nothing,Nothing,Just 4] == r
--   
maybe_filter :: (a -> Bool) -> [Maybe a] -> [Maybe a] -- | Variant of filter that retains Nothing as a placeholder -- for removed elements. -- --
--   filter_maybe even [1..4] == [Nothing,Just 2,Nothing,Just 4]
--   
filter_maybe :: (a -> Bool) -> [a] -> [Maybe a] -- | Math functions. module Music.Theory.Math -- | Real (alias for Double). type R = Double -- | -- http://reference.wolfram.com/mathematica/ref/FractionalPart.html integral_and_fractional_parts :: (Integral i, RealFrac t) => t -> (i, t) -- | Type specialised. integer_and_fractional_parts :: RealFrac t => t -> (Integer, t) -- | -- http://reference.wolfram.com/mathematica/ref/FractionalPart.html -- --
--   import Sound.SC3.Plot {- hsc3-plot -}
--   plotTable1 (map fractional_part [-2.0,-1.99 .. 2.0])
--   
fractional_part :: RealFrac a => a -> a -- | http://reference.wolfram.com/mathematica/ref/SawtoothWave.html -- --
--   plotTable1 (map sawtooth_wave [-2.0,-1.99 .. 2.0])
--   
sawtooth_wave :: RealFrac a => a -> a -- | Pretty printer for Rational that elides denominators of -- 1. -- --
--   map rational_pp [1,3/2,2] == ["1","3/2","2"]
--   
rational_pp :: (Show a, Integral a) => Ratio a -> String -- | Pretty print ratio as : separated integers. -- --
--   map ratio_pp [1,3/2,2] == ["1:1","3:2","2:1"]
--   
ratio_pp :: Rational -> String -- | Predicate that is true if n/d can be simplified, ie. where -- gcd of n and d is not 1. -- --
--   let r = [False,True,False]
--   in map rational_simplifies [(2,3),(4,6),(5,7)] == r
--   
rational_simplifies :: Integral a => (a, a) -> Bool -- | numerator and denominator of rational. rational_nd :: Integral t => Ratio t -> (t, t) -- | Rational as a whole number, or Nothing. rational_whole :: Integral a => Ratio a -> Maybe a -- | Erroring variant. rational_whole_err :: Integral a => Ratio a -> a -- | Variant of showFFloat. The Show instance for floats -- resorts to exponential notation very readily. -- --
--   [show 0.01,realfloat_pp 2 0.01] == ["1.0e-2","0.01"]
--   
realfloat_pp :: RealFloat a => Int -> a -> String -- | Type specialised realfloat_pp. float_pp :: Int -> Float -> String -- | Type specialised realfloat_pp. double_pp :: Int -> Double -> String -- | Show only positive and negative values, always with sign. -- --
--   map num_diff_str [-2,-1,0,1,2] == ["-2","-1","","+1","+2"]
--   map show [-2,-1,0,1,2] == ["-2","-1","0","1","2"]
--   
num_diff_str :: (Num a, Ord a, Show a) => a -> String -- | Clarence Barlow. "Two Essays on Theory". Computer Music -- Journal, 11(1):44-60, 1987. Translated by Henning Lohner. module Music.Theory.Meter.Barlow_1987 traceShow :: a -> b -> b -- | One indexed variant of genericIndex. -- --
--   map (at [11..13]) [1..3] == [11,12,13]
--   
at :: Integral n => [a] -> n -> a -- | Variant of at with boundary rules and specified error message. -- --
--   map (at' 'x' [11..13]) [0..4] == [1,11,12,13,1]
--   at' 'x' [0] 3 == undefined
--   
at' :: (Num a, Show a, Integral n, Show n, Show m) => m -> [a] -> n -> a -- | Variant of mod with input constraints. -- --
--   mod' (-1) 2 == 1
--   
mod' :: (Integral a, Show a) => a -> a -> a -- | Specialised variant of fromIntegral. to_r :: (Integral n, Show n) => n -> R -- | Variant on div with input constraints. div' :: (Integral a, Show a) => String -> a -> a -> a -- | A stratification is a tree of integral subdivisions. type Stratification t = [t] -- | Indispensibilities from stratification. -- --
--   indispensibilities [3,2,2] == [11,0,6,3,9,1,7,4,10,2,8,5]
--   indispensibilities [2,3,2] == [11,0,6,2,8,4,10,1,7,3,9,5]
--   indispensibilities [2,2,3] == [11,0,4,8,2,6,10,1,5,9,3,7]
--   indispensibilities [3,5] == [14,0,9,3,6,12,1,10,4,7,13,2,11,5,8]
--   
indispensibilities :: (Integral n, Show n) => Stratification n -> [n] -- | The indispensibility measure (ψ). -- --
--   map (lower_psi [2] 1) [1..2] == [1,0]
--   map (lower_psi [3] 1) [1..3] == [2,0,1]
--   map (lower_psi [2,2] 2) [1..4] == [3,0,2,1]
--   map (lower_psi [5] 1) [1..5] == [4,0,3,1,2]
--   map (lower_psi [3,2] 2) [1..6] == [5,0,3,1,4,2]
--   map (lower_psi [2,3] 2) [1..6] == [5,0,2,4,1,3]
--   
lower_psi :: (Integral a, Show a) => Stratification a -> a -> a -> a -- | The first nth primes, reversed. -- --
--   reverse_primes 14 == [43,41,37,31,29,23,19,17,13,11,7,5,3,2]
--   
reverse_primes :: (Integral n, Show n) => n -> [n] -- | Generate prime stratification for n. -- --
--   map prime_stratification [2,3,5,7,11] == [[2],[3],[5],[7],[11]]
--   map prime_stratification [6,8,9,12] == [[3,2],[2,2,2],[3,3],[3,2,2]]
--   map prime_stratification [22,10,4,1] == [[11,2],[5,2],[2,2],[]]
--   map prime_stratification [18,16,12] == [[3,3,2],[2,2,2,2],[3,2,2]]
--   
prime_stratification :: (Integral n, Show n) => n -> Stratification n -- | Fundamental indispensibilities for prime numbers (Ψ). -- --
--   map (upper_psi 2) [1..2] == [1,0]
--   map (upper_psi 3) [1..3] == [2,0,1]
--   map (upper_psi 5) [1..5] == [4,0,3,1,2]
--   map (upper_psi 7) [1..7] == [6,0,4,2,5,1,3]
--   map (upper_psi 11) [1..11] == [10,0,6,4,9,1,7,3,8,2,5]
--   map (upper_psi 13) [1..13] == [12,0,7,4,10,1,8,5,11,2,9,3,6]
--   
upper_psi :: (Integral a, Show a) => a -> a -> a -- | Table such that each subsequent row deletes the least indispensibile -- pulse. -- --
--   thinning_table [3,2] == [[True,True,True,True,True,True]
--                           ,[True,False,True,True,True,True]
--                           ,[True,False,True,False,True,True]
--                           ,[True,False,True,False,True,False]
--                           ,[True,False,False,False,True,False]
--                           ,[True,False,False,False,False,False]]
--   
thinning_table :: (Integral n, Show n) => Stratification n -> [[Bool]] -- | Trivial pretty printer for thinning_table. -- --
--   putStrLn (thinning_table_pp [3,2])
--   putStrLn (thinning_table_pp [2,3])
--   
-- --
--   ******   ******
--   *.****   *.****
--   *.*.**   *.**.*
--   *.*.*.   *..*.*
--   *...*.   *..*..
--   *.....   *.....
--   
thinning_table_pp :: (Integral n, Show n) => Stratification n -> String -- | Scale values against length of list minus one. -- --
--   relative_to_length [0..5] == [0.0,0.2,0.4,0.6,0.8,1.0]
--   
relative_to_length :: (Real a, Fractional b) => [a] -> [b] -- | Variant of indispensibilities that scales value to lie in -- (0,1). -- -- relative_indispensibilities [3,2] == [1,0,0.6,0.2,0.8,0.4] relative_indispensibilities :: (Integral n, Show n) => Stratification n -> [R] -- | Align two meters (given as stratifications) to least common multiple -- of their degrees. The indispensibilities function is given as -- an argument so that it may be relative if required. This generates -- Table 7 (p.58). -- --
--   let r = [(5,5),(0,0),(2,3),(4,1),(1,4),(3,2)]
--   in align_meters indispensibilities [2,3] [3,2] == r
--   
-- --
--   let r = [(1,1),(0,0),(0.4,0.6),(0.8,0.2),(0.2,0.8),(0.6,0.4)]
--   in align_meters relative_indispensibilities [2,3] [3,2] == r
--   
-- --
--   align_meters indispensibilities [2,2,3] [3,5]
--   align_meters relative_indispensibilities [2,2,3] [3,5]
--   
align_meters :: (t -> [b]) -> t -> t -> [(b, b)] -- | Type pairing a stratification and a tempo. type S_MM t = ([t], t) -- | Variant of div that requires mod be 0. whole_div :: Integral a => a -> a -> a -- | Variant of quot that requires rem be 0. whole_quot :: Integral a => a -> a -> a -- | Rule to prolong stratification of two S_MM values such that -- pulse at the deeper level are aligned. (Paragraph 2, p.58) -- --
--   let x = ([2,2,2],1)
--   in prolong_stratifications x x == (fst x,fst x)
--   
-- --
--   let r = ([2,5,3,3,2],[3,2,5,5])
--   in prolong_stratifications ([2,5],50) ([3,2],60) == r
--   
-- --
--   prolong_stratifications ([2,2,3],5) ([3,5],4) == ([2,2,3],[3,5])
--   
prolong_stratifications :: (Integral n, Show n) => S_MM n -> S_MM n -> ([n], [n]) -- | Arithmetic mean (average) of a list. -- --
--   mean [0..5] == 2.5
--   
mean :: Fractional a => [a] -> a -- | Square of n. -- --
--   square 5 == 25
--   
square :: Num a => a -> a -- | Composition of prolong_stratifications and align_meters. -- --
--   align_s_mm indispensibilities ([2,2,3],5) ([3,5],4)
--   
align_s_mm :: (Integral n, Show n) => ([n] -> [t]) -> S_MM n -> S_MM n -> [(t, t)] -- | An attempt at Equation 5 of the CMJ paper. When n is -- h-1 the output is incorrect (it is the product of the correct -- values for n at h-1 and h). -- --
--   map (upper_psi' 5) [1..5] /= [4,0,3,1,2]
--   map (upper_psi' 7) [1..7] /= [6,0,4,2,5,1,3]
--   map (upper_psi' 11) [1..11] /= [10,0,6,4,9,1,7,3,8,2,5]
--   map (upper_psi' 13) [1..13] /= [12,0,7,4,10,1,8,5,11,2,9,3,6]
--   
upper_psi' :: (Integral a, Show a) => a -> a -> a -- | The MPS limit equation given on p.58. -- --
--   mps_limit 3 == 21 + 7/9
--   
mps_limit :: Floating a => a -> a -- | The square of the product of the input sequence is summed, then -- divided by the square of the sequence length. -- --
--   mean_square_product [(0,0),(1,1),(2,2),(3,3)] == 6.125
--   mean_square_product [(2,3),(4,5)] == (6^2 + 20^2) / 2^2
--   
mean_square_product :: Fractional n => [(n, n)] -> n -- | An incorrect attempt at the description in paragraph two of p.58 of -- the CMJ paper. -- --
--   let p ~= q = abs (p - q) < 1e-4
--   metrical_affinity [2,3] 1 [3,2] 1 ~= 0.0324
--   metrical_affinity [2,2,3] 20 [3,5] 16 ~= 0.0028
--   
metrical_affinity :: (Integral n, Show n) => [n] -> n -> [n] -> n -> R -- | An incorrect attempt at Equation 6 of the CMJ paper, see -- omega_z. -- --
--   let p ~= q = abs (p - q) < 1e-4
--   metrical_affinity' [2,2,2] 1 [2,2,2] 1 ~= 1.06735
--   metrical_affinity' [2,2,2] 1 [2,2,3] 1 ~= 0.57185
--   metrical_affinity' [2,2,2] 1 [2,3,2] 1 ~= 0.48575
--   metrical_affinity' [2,2,2] 1 [3,2,2] 1 ~= 0.45872
--   
-- --
--   metrical_affinity' [3,2,2] 3 [2,2,3] 2 ~= 0.10282
--   
metrical_affinity' :: (Integral t, Show t) => [t] -> t -> [t] -> t -> R -- | Common music notation note and alteration values. module Music.Theory.Pitch.Note -- | Enumeration of common music notation note names (C to -- B). data Note_T C :: Note_T D :: Note_T E :: Note_T F :: Note_T G :: Note_T A :: Note_T B :: Note_T -- | Transform Note_T to pitch-class number. -- --
--   map note_to_pc [C,E,G] == [0,4,7]
--   
note_to_pc :: Integral i => Note_T -> i -- | Modal transposition of Note_T value. -- --
--   note_t_transpose C 2 == E
--   
note_t_transpose :: Note_T -> Int -> Note_T -- | Enumeration of common music notation note alterations. data Alteration_T DoubleFlat :: Alteration_T ThreeQuarterToneFlat :: Alteration_T Flat :: Alteration_T QuarterToneFlat :: Alteration_T Natural :: Alteration_T QuarterToneSharp :: Alteration_T Sharp :: Alteration_T ThreeQuarterToneSharp :: Alteration_T DoubleSharp :: Alteration_T -- | Generic form. generic_alteration_to_diff :: Integral i => Alteration_T -> Maybe i -- | Transform Alteration_T to semitone alteration. Returns -- Nothing for non-semitone alterations. -- --
--   map alteration_to_diff [Flat,QuarterToneSharp] == [Just (-1),Nothing]
--   
alteration_to_diff :: Alteration_T -> Maybe Int -- | Is Alteration_T 12-ET. alteration_is_12et :: Alteration_T -> Bool -- | Transform Alteration_T to semitone alteration. -- --
--   map alteration_to_diff_err [Flat,Sharp] == [-1,1]
--   
alteration_to_diff_err :: Integral i => Alteration_T -> i -- | Transform Alteration_T to fractional semitone alteration, ie. -- allow quarter tones. -- --
--   alteration_to_fdiff QuarterToneSharp == 0.5
--   
alteration_to_fdiff :: Fractional n => Alteration_T -> n -- | Transform fractional semitone alteration to Alteration_T, ie. -- allow quarter tones. -- --
--   map fdiff_to_alteration [-0.5,0.5] == [Just QuarterToneFlat
--                                         ,Just QuarterToneSharp]
--   
fdiff_to_alteration :: (Fractional n, Eq n) => n -> Maybe Alteration_T -- | Raise Alteration_T by a quarter tone where possible. -- --
--   alteration_raise_quarter_tone Flat == Just QuarterToneFlat
--   alteration_raise_quarter_tone DoubleSharp == Nothing
--   
alteration_raise_quarter_tone :: Alteration_T -> Maybe Alteration_T -- | Lower Alteration_T by a quarter tone where possible. -- --
--   alteration_lower_quarter_tone Sharp == Just QuarterToneSharp
--   alteration_lower_quarter_tone DoubleFlat == Nothing
--   
alteration_lower_quarter_tone :: Alteration_T -> Maybe Alteration_T -- | Edit Alteration_T by a quarter tone where possible, -- -0.5 lowers, 0 retains, 0.5 raises. -- --
--   import Data.Ratio
--   alteration_edit_quarter_tone (-1 % 2) Flat == Just ThreeQuarterToneFlat
--   
alteration_edit_quarter_tone :: (Fractional n, Eq n) => n -> Alteration_T -> Maybe Alteration_T -- | Simplify Alteration_T to standard 12ET by deleting quarter -- tones. -- --
--   Data.List.nub (map alteration_clear_quarter_tone [minBound..maxBound])
--   
alteration_clear_quarter_tone :: Alteration_T -> Alteration_T -- | Unicode has entries for Musical Symbols in the range -- U+1D100 through U+1D1FF. The 3/4 symbols -- are non-standard, here they correspond to MUSICAL SYMBOL FLAT -- DOWN and MUSICAL SYMBOL SHARP UP. -- --
--   map alteration_symbol [minBound .. maxBound] == "𝄫𝄭♭𝄳♮𝄲♯𝄰𝄪"
--   
alteration_symbol :: Alteration_T -> Char -- | The ISO ASCII spellings for alterations. Naturals as written -- as the empty string. -- --
--   mapMaybe alteration_iso_m [Flat .. Sharp] == ["b","","#"]
--   
alteration_iso_m :: Alteration_T -> Maybe String -- | The ISO ASCII spellings for alterations. alteration_iso :: Alteration_T -> String -- | The Tonhöhe ASCII spellings for alterations. -- -- See http://www.musiccog.ohio-state.edu/Humdrum/guide04.html and -- http://lilypond.org/doc/v2.16/Documentation/notation/writing-pitches -- --
--   map alteration_tonh [Flat .. Sharp] == ["es","eh","","ih","is"]
--   
alteration_tonh :: Alteration_T -> String -- | Generalised alteration, given as a rational semitone difference and a -- string representation of the alteration. type Alteration_T' = (Rational, String) -- | Transform Alteration_T to Alteration_T'. -- --
--   let r = [(-1,"♭"),(0,"♮"),(1,"♯")]
--   in map alteration_t' [Flat,Natural,Sharp] == r
--   
alteration_t' :: Alteration_T -> Alteration_T' -- | Function to spell a PitchClass. type Spelling n = n -> (Note_T, Alteration_T) instance Eq Note_T instance Enum Note_T instance Bounded Note_T instance Ord Note_T instance Show Note_T instance Eq Alteration_T instance Enum Alteration_T instance Bounded Alteration_T instance Ord Alteration_T instance Show Alteration_T -- | Spelling rules for common music notation. module Music.Theory.Pitch.Spelling -- | Variant of Spelling for incomplete functions. type Spelling_M i = i -> Maybe (Note_T, Alteration_T) -- | Spelling for natural (♮) notes only. -- --
--   map pc_spell_natural_m [0,1] == [Just (C,Natural),Nothing]
--   
pc_spell_natural_m :: Integral i => Spelling_M i -- | Erroring variant of pc_spell_natural_m. -- --
--   map pc_spell_natural [0,5,7] == [(C,Natural),(F,Natural),(G,Natural)]
--   
pc_spell_natural :: Integral i => Spelling i -- | Use spelling from simplest key-signature. Note that this is ambiguous -- for 8, which could be either G Sharp (♯) in A Major or -- A Flat (♭) in E Flat (♭) Major. -- --
--   map pc_spell_ks [6,8] == [(F,Sharp),(A,Flat)]
--   
pc_spell_ks :: Integral i => Spelling i -- | Use always sharp (♯) spelling. -- --
--   map pc_spell_sharp [6,8] == [(F,Sharp),(G,Sharp)]
--   Data.List.nub (map (snd . pc_spell_sharp) [1,3,6,8,10]) == [Sharp]
--   octpc_to_pitch pc_spell_sharp (4,6) == Pitch F Sharp 4
--   
pc_spell_sharp :: Integral i => Spelling i -- | Use always flat (♭) spelling. -- --
--   map pc_spell_flat [6,8] == [(G,Flat),(A,Flat)]
--   Data.List.nub (map (snd . pc_spell_flat) [1,3,6,8,10]) == [Flat]
--   
pc_spell_flat :: Integral i => Spelling i -- | Either module Music.Theory.Either -- | Maybe Left of Either. fromLeft :: Either a b -> Maybe a -- | Maybe Right of Either. fromRight :: Either a b -> Maybe b -- | Data.Function related functions. module Music.Theory.Function -- | && of predicates. predicate_and :: (t -> Bool) -> (t -> Bool) -> t -> Bool -- | all of predicates. -- --
--   let r = [False,False,True,False,True,False]
--   in map (predicate_all [(> 0),(< 5),even]) [0..5] == r
--   
predicate_all :: [t -> Bool] -> t -> Bool -- | || of predicates. predicate_or :: (t -> Bool) -> (t -> Bool) -> t -> Bool -- | any of predicates. -- --
--   let r = [True,False,True,False,True,True]
--   in map (predicate_any [(== 0),(== 5),even]) [0..5] == r
--   
predicate_any :: [t -> Bool] -> t -> Bool -- | fmap . fmap, ie. (t -> c) -> (a -> b -- -> t) -> a -> b -> c. (.:) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b) -- | fmap . .:, ie. (t -> d) -> (a -> b -- -> c -> t) -> a -> b -> c -> d. (.::) :: (Functor f, Functor g, Functor h) => (a -> b) -> f (g (h a)) -> f (g (h b)) -- | fmap . .::. (.:::) :: (Functor f, Functor g, Functor h, Functor i) => (a -> b) -> f (g (h (i a))) -> f (g (h (i b))) -- | fmap . .:::. (.::::) :: (Functor f, Functor g, Functor h, Functor i, Functor j) => (a -> b) -> f (g (h (i (j a)))) -> f (g (h (i (j b)))) -- | fmap . .::::. (.:::::) :: (Functor f, Functor g, Functor h, Functor i, Functor j, Functor k) => (a -> b) -> f (g (h (i (j (k a))))) -> f (g (h (i (j (k b))))) -- | Common music notation duration model. module Music.Theory.Duration -- | Common music notation durational model data Duration Duration :: Integer -> Integer -> Rational -> Duration -- | division of whole note division :: Duration -> Integer -- | number of dots dots :: Duration -> Integer -- | tuplet modifier multiplier :: Duration -> Rational -- | Are multipliers equal? duration_meq :: Duration -> Duration -> Bool -- | Compare durations with equal multipliers. duration_compare_meq :: Duration -> Duration -> Maybe Ordering -- | Erroring variant of duration_compare_meq. duration_compare_meq_err :: Duration -> Duration -> Ordering -- | Ord instance in terms of duration_compare_meq_err. order_pair :: Ordering -> (t, t) -> (t, t) -- | Sort a pair of equal type values using given comparison function. -- --
--   sort_pair compare ('b','a') == ('a','b')
--   
sort_pair :: (t -> t -> Ordering) -> (t, t) -> (t, t) sort_pair_m :: (t -> t -> Maybe Ordering) -> (t, t) -> Maybe (t, t) -- | True if neither duration is dotted. no_dots :: (Duration, Duration) -> Bool -- | Sum undotted divisions, input is required to be sorted. sum_dur_undotted :: (Integer, Integer) -> Maybe Duration -- | Sum dotted divisions, input is required to be sorted. -- --
--   sum_dur_dotted (4,1,4,1) == Just (Duration 2 1 1)
--   sum_dur_dotted (4,0,2,1) == Just (Duration 1 0 1)
--   sum_dur_dotted (8,1,4,0) == Just (Duration 4 2 1)
--   sum_dur_dotted (16,0,4,2) == Just (Duration 2 0 1)
--   
sum_dur_dotted :: (Integer, Integer, Integer, Integer) -> Maybe Duration -- | Sum durations. Not all durations can be summed, and the present -- algorithm is not exhaustive. -- --
--   import Music.Theory.Duration.Name
--   sum_dur quarter_note eighth_note == Just dotted_quarter_note
--   sum_dur dotted_quarter_note eighth_note == Just half_note
--   sum_dur quarter_note dotted_eighth_note == Just double_dotted_quarter_note
--   
sum_dur :: Duration -> Duration -> Maybe Duration -- | Erroring variant of sum_dur. sum_dur' :: Duration -> Duration -> Duration -- | Give MusicXML type for division. -- --
--   map whole_note_division_to_musicxml_type [2,4] == ["half","quarter"]
--   
whole_note_division_to_musicxml_type :: Integer -> String -- | Variant of whole_note_division_to_musicxml_type extracting -- division from Duration. -- --
--   duration_to_musicxml_type quarter_note == "quarter"
--   
duration_to_musicxml_type :: Duration -> String -- | Give Lilypond notation for Duration. Note that the -- duration multiplier is not written. -- --
--   import Music.Theory.Duration.Name
--   map duration_to_lilypond_type [half_note,dotted_quarter_note] == ["2","4."]
--   
duration_to_lilypond_type :: Duration -> String -- | Calculate number of beams at notated division. -- --
--   whole_note_division_to_beam_count 32 == Just 3
--   
whole_note_division_to_beam_count :: Integer -> Maybe Integer -- | Calculate number of beams at Duration. -- --
--   map duration_beam_count [half_note,sixteenth_note] == [0,2]
--   
duration_beam_count :: Duration -> Integer whole_note_division_pp :: Integer -> Maybe Char duration_pp :: Duration -> Maybe String -- | Duration to **recip notation. -- -- http://humdrum.org/Humdrum/representations/recip.rep.html -- --
--   let d = map (\z -> Duration z 0 1) [0,1,2,4,8,16,32]
--   in map duration_recip_pp d == ["0","1","2","4","8","16","32"]
--   
-- --
--   let d = [Duration 1 1 (1/3),Duration 4 1 1,Duration 4 1 (2/3)]
--   in map duration_recip_pp d == ["3.","4.","6."]
--   
duration_recip_pp :: Duration -> String instance Eq Duration instance Show Duration instance Ord Duration -- | Names for common music notation durations. module Music.Theory.Duration.Name breve :: Duration thirtysecond_note :: Duration sixteenth_note :: Duration eighth_note :: Duration quarter_note :: Duration half_note :: Duration whole_note :: Duration dotted_breve :: Duration dotted_thirtysecond_note :: Duration dotted_sixteenth_note :: Duration dotted_eighth_note :: Duration dotted_quarter_note :: Duration dotted_half_note :: Duration dotted_whole_note :: Duration double_dotted_breve :: Duration double_dotted_thirtysecond_note :: Duration double_dotted_sixteenth_note :: Duration double_dotted_eighth_note :: Duration double_dotted_quarter_note :: Duration double_dotted_half_note :: Duration double_dotted_whole_note :: Duration -- | Rational quarter-note notation for durations. module Music.Theory.Duration.RQ -- | Rational Quarter-Note type RQ = Rational -- | Rational quarter note to duration value. It is a mistake to hope this -- could handle tuplets directly since, for instance, a 3:2 -- dotted note will be of the same duration as a plain undotted note. -- --
--   rq_to_duration (3/4) == Just dotted_eighth_note
--   
rq_to_duration :: RQ -> Maybe Duration -- | Is RQ a cmn duration. -- --
--   map rq_is_cmn [1/4,1/5,1/8,3/32] == [True,False,True,False]
--   
rq_is_cmn :: RQ -> Bool -- | Variant of rq_to_duration with error message. rq_to_duration_err :: Show a => a -> RQ -> Duration -- | Convert a whole note division integer to an RQ value. -- --
--   map whole_note_division_to_rq [1,2,4,8] == [4,2,1,1/2]
--   
whole_note_division_to_rq :: Integer -> RQ -- | Apply dots to an RQ duration. -- --
--   map (rq_apply_dots 1) [1,2] == [3/2,7/4]
--   
rq_apply_dots :: RQ -> Integer -> RQ -- | Convert Duration to RQ value, see rq_to_duration -- for partial inverse. -- --
--   let d = [half_note,dotted_quarter_note,dotted_whole_note]
--   in map duration_to_rq d == [2,3/2,6]
--   
duration_to_rq :: Duration -> RQ -- | compare function for Duration via duration_to_rq. -- --
--   half_note `duration_compare_rq` quarter_note == GT
--   
duration_compare_rq :: Duration -> Duration -> Ordering -- | RQ modulo. -- --
--   map (rq_mod (5/2)) [3/2,3/4,5/2] == [1,1/4,0]
--   
rq_mod :: RQ -> RQ -> RQ -- | Is p divisible by q, ie. is the denominator of -- p/q == 1. -- --
--   map (rq_divisible_by (3%2)) [1%2,1%3] == [True,False]
--   
rq_divisible_by :: RQ -> RQ -> Bool -- | Is RQ a whole number (ie. is denominator == -- 1. -- --
--   map rq_is_integral [1,3/2,2] == [True,False,True]
--   
rq_is_integral :: RQ -> Bool -- | Return numerator of RQ if denominator == -- 1. -- --
--   map rq_integral [1,3/2,2] == [Just 1,Nothing,Just 2]
--   
rq_integral :: RQ -> Maybe Integer -- | Derive the tuplet structure of a set of RQ values. -- --
--   rq_derive_tuplet_plain [1/2] == Nothing
--   rq_derive_tuplet_plain [1/2,1/2] == Nothing
--   rq_derive_tuplet_plain [1/4,1/4] == Nothing
--   rq_derive_tuplet_plain [1/3,2/3] == Just (3,2)
--   rq_derive_tuplet_plain [1/2,1/3,1/6] == Just (6,4)
--   rq_derive_tuplet_plain [1/3,1/6] == Just (6,4)
--   rq_derive_tuplet_plain [2/5,3/5] == Just (5,4)
--   rq_derive_tuplet_plain [1/3,1/6,2/5,1/10] == Just (30,16)
--   
-- --
--   map rq_derive_tuplet_plain [[1/3,1/6],[2/5,1/10]] == [Just (6,4)
--                                                        ,Just (10,8)]
--   
rq_derive_tuplet_plain :: [RQ] -> Maybe (Integer, Integer) -- | Derive the tuplet structure of a set of RQ values. -- --
--   rq_derive_tuplet [1/4,1/8,1/8] == Nothing
--   rq_derive_tuplet [1/3,2/3] == Just (3,2)
--   rq_derive_tuplet [1/2,1/3,1/6] == Just (3,2)
--   rq_derive_tuplet [2/5,3/5] == Just (5,4)
--   rq_derive_tuplet [1/3,1/6,2/5,1/10] == Just (15,8)
--   
rq_derive_tuplet :: [RQ] -> Maybe (Integer, Integer) -- | Remove tuplet multiplier from value, ie. to give notated duration. -- This seems odd but is neccessary to avoid ambiguity. Ie. is 1 -- a quarter note or a 3:2 tuplet dotted-quarter-note etc. -- --
--   map (rq_un_tuplet (3,2)) [1,2/3,1/2,1/3] == [3/2,1,3/4,1/2]
--   
rq_un_tuplet :: (Integer, Integer) -> RQ -> RQ -- | If an RQ duration is un-representable by a single cmn -- duration, give tied notation. -- --
--   catMaybes (map rq_to_cmn [1..9]) == [(4,1),(4,3),(8,1)]
--   
-- --
--   map rq_to_cmn [5/4,5/8] == [Just (1,1/4),Just (1/2,1/8)]
--   
rq_to_cmn :: RQ -> Maybe (RQ, RQ) -- | Predicate to determine if a segment can be notated either without a -- tuplet or with a single tuplet. -- --
--   rq_can_notate [1/2,1/4,1/4] == True
--   rq_can_notate [1/3,1/6] == True
--   rq_can_notate [2/5,1/10] == True
--   rq_can_notate [1/3,1/6,2/5,1/10] == False
--   rq_can_notate [4/7,1/7,6/7,3/7] == True
--   rq_can_notate [4/7,1/7,2/7] == True
--   
rq_can_notate :: [RQ] -> Bool -- | Duration annotations. module Music.Theory.Duration.Annotation -- | Standard music notation durational model annotations data D_Annotation Tie_Right :: D_Annotation Tie_Left :: D_Annotation Begin_Tuplet :: (Integer, Integer, Duration) -> D_Annotation End_Tuplet :: D_Annotation -- | Annotated Duration. type Duration_A = (Duration, [D_Annotation]) begin_tuplet :: D_Annotation -> Maybe (Integer, Integer, Duration) da_begin_tuplet :: Duration_A -> Maybe (Integer, Integer, Duration) begins_tuplet :: D_Annotation -> Bool -- | Does Duration_A begin a tuplet? da_begins_tuplet :: Duration_A -> Bool -- | Does Duration_A end a tuplet? da_ends_tuplet :: Duration_A -> Bool -- | Is Duration_A tied to the the right? da_tied_right :: Duration_A -> Bool -- | Annotate a sequence of Duration_A as a tuplet. -- --
--   import Music.Theory.Duration.Name
--   da_tuplet (3,2) [(quarter_note,[Tie_Left]),(eighth_note,[Tie_Right])]
--   
da_tuplet :: (Integer, Integer) -> [Duration_A] -> [Duration_A] -- | Transform predicates into Ordering predicate such that if -- f holds then LT, if g holds then GT else -- EQ. -- --
--   map (begin_end_cmp (== '{') (== '}')) "{a}" == [LT,EQ,GT]
--   
begin_end_cmp :: (t -> Bool) -> (t -> Bool) -> t -> Ordering -- | Variant of begin_end_cmp, predicates are constructed by -- ==. -- --
--   map (begin_end_cmp_eq '{' '}') "{a}" == [LT,EQ,GT]
--   
begin_end_cmp_eq :: Eq t => t -> t -> t -> Ordering -- | Given an Ordering predicate where LT opens a group, -- GT closes a group, and EQ continues current group, -- construct tree from list. -- --
--   let {l = "a {b {c d} e f} g h i"
--       ;t = group_tree (begin_end_cmp_eq '{' '}') l}
--   in catMaybes (flatten t) == l
--   
-- --
--   let d = putStrLn . drawTree . fmap show
--   in d (group_tree (begin_end_cmp_eq '(' ')') "a(b(cd)ef)ghi")
--   
group_tree :: (a -> Ordering) -> [a] -> Tree (Maybe a) -- | Group tuplets into a Tree. Branch nodes have label -- Nothing, leaf nodes label Just Duration_A. -- --
--   import Music.Theory.Duration.Name.Abbreviation
--   
-- --
--   let d = [(q,[])
--           ,(e,[Begin_Tuplet (3,2,e)])
--           ,(s,[Begin_Tuplet (3,2,s)]),(s,[]),(s,[End_Tuplet])
--           ,(e,[End_Tuplet])
--           ,(q,[])]
--   in catMaybes (flatten (da_group_tuplets d)) == d
--   
da_group_tuplets :: [Duration_A] -> Tree (Maybe Duration_A) -- | Variant of break that places separator at left. -- --
--   break_left (== 3) [1..6] == ([1..3],[4..6])
--   break_left (== 3) [1..3] == ([1..3],[])
--   
break_left :: (a -> Bool) -> [a] -> ([a], [a]) -- | Variant of break_left that balances begin & end predicates. -- --
--   break_left (== ')') "test (sep) _) balanced"
--   sep_balanced True (== '(') (== ')') "test (sep) _) balanced"
--   sep_balanced False (== '(') (== ')') "(test (sep) _) balanced"
--   
sep_balanced :: Bool -> (a -> Bool) -> (a -> Bool) -> [a] -> ([a], [a]) -- | Group non-nested tuplets, ie. groups nested tuplets at one level. da_group_tuplets_nn :: [Duration_A] -> [Either Duration_A [Duration_A]] -- | Keep right variant of zipWith, unused rhs values are returned. -- --
--   zip_with_kr (,) [1..3] ['a'..'e'] == ([(1,'a'),(2,'b'),(3,'c')],"de")
--   
zip_with_kr :: (a -> b -> c) -> [a] -> [b] -> ([c], [b]) -- | Keep right variant of zip, unused rhs values are returned. -- --
--   zip_kr [1..4] ['a'..'f'] == ([(1,'a'),(2,'b'),(3,'c'),(4,'d')],"ef")
--   
zip_kr :: [a] -> [b] -> ([(a, b)], [b]) -- | zipWith variant that adopts the shape of the lhs. -- --
--   let {p = [Left 1,Right [2,3],Left 4]
--       ;q = "abcd"}
--   in nn_reshape (,) p q == [Left (1,'a'),Right [(2,'b'),(3,'c')],Left (4,'d')]
--   
nn_reshape :: (a -> b -> c) -> [Either a [a]] -> [b] -> [Either c [c]] -- | Replace elements at Traversable with result of joining with -- elements from list. adopt_shape :: Traversable t => (a -> b -> c) -> [b] -> t a -> t c -- | Variant of adopt_shape that considers only Just elements -- at Traversable. -- --
--   let {s = "a(b(cd)ef)ghi"
--       ;t = group_tree (begin_end_cmp_eq '(' ')') s}
--   in adopt_shape_m (,) [1..13] t
--   
adopt_shape_m :: Traversable t => (a -> b -> c) -> [b] -> t (Maybe a) -> t (Maybe c) -- | Does a have Tie_Left and Tie_Right? d_annotated_tied_lr :: [D_Annotation] -> (Bool, Bool) -- | Does d have Tie_Left and Tie_Right? duration_a_tied_lr :: Duration_A -> (Bool, Bool) instance Eq D_Annotation instance Show D_Annotation -- | Time Signatures. module Music.Theory.Time_Signature -- | A Time Signature is a (numerator,denominator) pair. type Time_Signature = (Integer, Integer) -- | Tied, non-multiplied durations to fill a whole measure. -- --
--   ts_whole_note (3,8) == [dotted_quarter_note]
--   ts_whole_note (2,2) == [whole_note]
--   
ts_whole_note :: Time_Signature -> [Duration] -- | Duration of measure in RQ. -- --
--   map ts_whole_note_rq [(3,8),(2,2)] == [3/2,4]
--   
ts_whole_note_rq :: Time_Signature -> RQ -- | Duration, in RQ, of a measure of indicated -- Time_Signature. -- --
--   map ts_rq [(3,4),(5,8)] == [3,5/2]
--   
ts_rq :: Time_Signature -> RQ -- | Time_Signature derived from whole note duration in RQ -- form. -- --
--   map rq_to_ts [4,3/2,7/4,6] == [(4,4),(3,8),(7,16),(6,4)]
--   
rq_to_ts :: Rational -> Time_Signature -- | Uniform division of time signature. -- --
--   ts_divisions (3,4) == [1,1,1]
--   ts_divisions (3,8) == [1/2,1/2,1/2]
--   ts_divisions (2,2) == [2,2]
--   ts_divisions (1,1) == [4]
--   
ts_divisions :: Time_Signature -> [RQ] -- | Convert a duration to a pulse count in relation to the indicated time -- signature. -- --
--   ts_duration_pulses (3,8) quarter_note == 2
--   
ts_duration_pulses :: Time_Signature -> Duration -> Rational -- | Rewrite time signature to indicated denominator. -- --
--   ts_rewrite 8 (3,4) == (6,8)
--   
ts_rewrite :: Integer -> Time_Signature -> Time_Signature -- | Sum time signatures. -- --
--   ts_sum [(3,16),(1,2)] == (11,16)
--   
ts_sum :: [Time_Signature] -> Time_Signature -- | A composite time signature is a sequence of Time_Signatures. type Composite_Time_Signature = [Time_Signature] -- | The RQ is the sum of ts_rq of the elements. -- --
--   cts_rq [(3,4),(1,8)] == 3 + 1/2
--   
cts_rq :: Composite_Time_Signature -> RQ -- | The divisions are the concat of the ts_divisions of the -- elements. -- --
--   cts_divisions [(3,4),(1,8)] == [1,1,1,1/2]
--   
cts_divisions :: Composite_Time_Signature -> [RQ] -- | Pulses are 1-indexed, RQ locations are 0-indexed. -- --
--   map (cts_pulse_to_rq [(2,4),(1,8),(1,4)]) [1 .. 4] == [0,1,2,2 + 1/2]
--   
cts_pulse_to_rq :: Composite_Time_Signature -> Int -> RQ -- | Variant that gives the window of the pulse (ie. the start -- location and the duration). -- --
--   let r = [(0,1),(1,1),(2,1/2),(2 + 1/2,1)]
--   in map (cts_pulse_to_rqw [(2,4),(1,8),(1,4)]) [1 .. 4] == r
--   
cts_pulse_to_rqw :: Composite_Time_Signature -> Int -> (RQ, RQ) -- | A rational time signature is a Composite_Time_Signature where -- the parts are Rational. type Rational_Time_Signature = [(Rational, Rational)] -- | The sum of the RQ of the elements. -- --
--   rts_rq [(3,4),(1,8)] == 3 + 1/2
--   rts_rq [(3/2,4),(1/2,8)] == 3/2 + 1/4
--   
rts_rq :: Rational_Time_Signature -> RQ -- | The divisions of the elements. -- --
--   rts_divisions [(3,4),(1,8)] == [1,1,1,1/2]
--   rts_divisions [(3/2,4),(1/2,8)] == [1,1/2,1/4]
--   
rts_divisions :: Rational_Time_Signature -> [[RQ]] rts_derive :: [RQ] -> Rational_Time_Signature -- | Pulses are 1-indexed, RQ locations are 0-indexed. -- --
--   map (rts_pulse_to_rq [(2,4),(1,8),(1,4)]) [1 .. 4] == [0,1,2,2 + 1/2]
--   map (rts_pulse_to_rq [(3/2,4),(1/2,8),(1/4,4)]) [1 .. 4] == [0,1,3/2,7/4]
--   
rts_pulse_to_rq :: Rational_Time_Signature -> Int -> RQ -- | Variant that gives the window of the pulse (ie. the start -- location and the duration). -- --
--   let r = [(0,1),(1,1),(2,1/2),(2 + 1/2,1)]
--   in map (rts_pulse_to_rqw [(2,4),(1,8),(1,4)]) [1 .. 4] == r
--   
rts_pulse_to_rqw :: Rational_Time_Signature -> Int -> (RQ, RQ) -- | Abbreviated names for Duration values when written as literals. -- There are letter names where w is whole_note and -- so on, and numerical names where _4 is -- quarter_note and so on. In both cases a ' extension -- means a dot so that e'' is a double dotted -- eighth_note. -- --
--   zipWith duration_compare_meq [e,e,e,e'] [e,s,q,e] == [EQ,GT,LT,GT]
--   zipWith sum_dur [e,q,q'] [e,e,e] == [Just q,Just q',Just h]
--   zipWith sum_dur' [e,q,q'] [e,e,e] == [q,q',h]
--   
module Music.Theory.Duration.Name.Abbreviation w :: Duration s :: Duration e :: Duration q :: Duration h :: Duration w' :: Duration s' :: Duration e' :: Duration q' :: Duration h' :: Duration w'' :: Duration s'' :: Duration e'' :: Duration q'' :: Duration h'' :: Duration _1 :: Duration _32 :: Duration _16 :: Duration _8 :: Duration _4 :: Duration _2 :: Duration _1' :: Duration _32' :: Duration _16' :: Duration _8' :: Duration _4' :: Duration _2' :: Duration _1'' :: Duration _32'' :: Duration _16'' :: Duration _8'' :: Duration _4'' :: Duration _2'' :: Duration -- | Common music notation tempo indications. module Music.Theory.Tempo_Marking -- | A tempo marking is in terms of a common music notation -- Duration. type Tempo_Marking = (Duration, Rational) -- | Duration of a RQ value, in seconds, given indicated tempo. -- --
--   rq_to_seconds (quarter_note,90) 1 == 60/90
--   
rq_to_seconds :: Tempo_Marking -> RQ -> Rational -- | The duration, in seconds, of a pulse at the indicated time signature -- and tempo marking. -- --
--   import Music.Theory.Duration.Name
--   pulse_duration (6,8) (quarter_note,60) == 1/2
--   
pulse_duration :: Time_Signature -> Tempo_Marking -> Rational -- | The duration, in seconds, of a measure at the indicated time signaure -- and tempo marking. -- --
--   measure_duration (3,4) (quarter_note,90) == 2
--   measure_duration (6,8) (quarter_note,120) == 3/2
--   
measure_duration :: Time_Signature -> Tempo_Marking -> Rational -- | Fractional variant of measure_duration. measure_duration_f :: Fractional c => Time_Signature -> Tempo_Marking -> c -- | Italian terms and markings from Wittner metronome (W.-Germany). -- http://wittner-gmbh.de/ metronome_table_wittner :: Num n => [(String, (n, n))] -- | Italian terms and markings from Nikko Seiki metronome (Japan). -- http://nikkoseiki.com/ metronome_table_nikko :: Num n => [(String, (n, n))] -- | Lookup metronome mark in table. -- --
--   mm_name metronome_table_nikko 72 == Just "Andante"
--   
mm_name :: (Num a, Ord a) => [(String, (a, a))] -> a -> Maybe String -- | Set operations on lists. module Music.Theory.Set.List -- | Remove duplicate elements with nub and then sort. -- --
--   set_l [3,3,3,2,2,1] == [1,2,3]
--   
set :: Ord a => [a] -> [a] -- | Size of powerset of set of cardinality n, ie. 2 -- ^ n. -- --
--   map n_powerset [6..9] == [64,128,256,512]
--   
n_powerset :: Integral n => n -> n -- | Powerset, ie. set of all subsets. -- --
--   sort (powerset [1,2]) == [[],[1],[1,2],[2]]
--   map length (map (\n -> powerset [1..n]) [6..9]) == [64,128,256,512]
--   
powerset :: [a] -> [[a]] -- | Two element subsets. -- --
--   pairs [1,2,3] == [(1,2),(1,3),(2,3)]
--   
pairs :: [a] -> [(a, a)] -- | Three element subsets. -- --
--   triples [1..4] == [(1,2,3),(1,2,4),(1,3,4),(2,3,4)]
--   
-- --
--   let f n = genericLength (triples [1..n]) == nk_combinations n 3
--   in all f [1..15]
--   
triples :: [a] -> [(a, a, a)] -- | Set expansion (ie. to multiset of degree n). -- --
--   expand_set 4 [1,2,3] == [[1,1,2,3],[1,2,2,3],[1,2,3,3]]
--   
expand_set :: Ord a => Int -> [a] -> [[a]] -- | All distinct multiset partitions, see partitions. -- --
--   partitions "aab" == [["aab"],["a","ab"],["b","aa"],["b","a","a"]]
--   
-- --
--   partitions "abc" == [["abc"]
--                       ,["bc","a"],["b","ac"],["c","ab"]
--                       ,["c","b","a"]]
--   
partitions :: Eq a => [a] -> [[[a]]] -- | Cartesian product of two sets. -- --
--   let r = [('a',1),('a',2),('b',1),('b',2),('c',1),('c',2)]
--   in cartesian_product "abc" [1,2] == r
--   
cartesian_product :: [a] -> [b] -> [(a, b)] -- | Set operations on Sets. module Music.Theory.Set.Set set :: Ord a => [a] -> Set a powerset :: Ord a => Set a -> Set (Set a) pairs :: Ord a => Set a -> Set (a, a) -- | Godfried T. Toussaint et. al. "The distance geometry of music" -- Journal of Computational Geometry: Theory and Applications -- Volume 42, Issue 5, July, 2009 -- (http://dx.doi.org/10.1016/j.comgeo.2008.04.005) module Music.Theory.Bjorklund -- | Bjorklund's algorithm to construct a binary sequence of n bits -- with k ones such that the k ones are distributed as -- evenly as possible among the (n - k) zeroes. -- --
--   bjorklund (5,9) == [True,False,True,False,True,False,True,False,True]
--   xdot (bjorklund (5,9)) == "x.x.x.x.x"
--   
-- --
--   let es = [(2,3),(2,5)
--            ,(3,4),(3,5),(3,8)
--            ,(4,7),(4,9),(4,12),(4,15)
--            ,(5,6),(5,7),(5,8),(5,9),(5,11),(5,12),(5,13),(5,16)
--            ,(6,7),(6,13)
--            ,(7,8),(7,9),(7,10),(7,12),(7,15),(7,16),(7,17),(7,18)
--            ,(8,17),(8,19)
--            ,(9,14),(9,16),(9,22),(9,23)
--            ,(11,12),(11,24)
--            ,(13,24)
--            ,(15,34)]
--   in map (\e -> let e' = bjorklund e in (e,xdot e',iseq_str e')) es
--   
-- --
--   [((2,3),"xx.","(12)")
--   ,((2,5),"x.x..","(23)")
--   ,((3,4),"xxx.","(112)")
--   ,((3,5),"x.x.x","(221)")
--   ,((3,8),"x..x..x.","(332)")
--   ,((4,7),"x.x.x.x","(2221)")
--   ,((4,9),"x.x.x.x..","(2223)")
--   ,((4,12),"x..x..x..x..","(3333)")
--   ,((4,15),"x...x...x...x..","(4443)")
--   ,((5,6),"xxxxx.","(11112)")
--   ,((5,7),"x.xx.xx","(21211)")
--   ,((5,8),"x.xx.xx.","(21212)")
--   ,((5,9),"x.x.x.x.x","(22221)")
--   ,((5,11),"x.x.x.x.x..","(22223)")
--   ,((5,12),"x..x.x..x.x.","(32322)")
--   ,((5,13),"x..x.x..x.x..","(32323)")
--   ,((5,16),"x..x..x..x..x...","(33334)")
--   ,((6,7),"xxxxxx.","(111112)")
--   ,((6,13),"x.x.x.x.x.x..","(222223)")
--   ,((7,8),"xxxxxxx.","(1111112)")
--   ,((7,9),"x.xxx.xxx","(2112111)")
--   ,((7,10),"x.xx.xx.xx","(2121211)")
--   ,((7,12),"x.xx.x.xx.x.","(2122122)")
--   ,((7,15),"x.x.x.x.x.x.x..","(2222223)")
--   ,((7,16),"x..x.x.x..x.x.x.","(3223222)")
--   ,((7,17),"x..x.x..x.x..x.x.","(3232322)")
--   ,((7,18),"x..x.x..x.x..x.x..","(3232323)")
--   ,((8,17),"x.x.x.x.x.x.x.x..","(22222223)")
--   ,((8,19),"x..x.x.x..x.x.x..x.","(32232232)")
--   ,((9,14),"x.xx.xx.xx.xx.","(212121212)")
--   ,((9,16),"x.xx.x.x.xx.x.x.","(212221222)")
--   ,((9,22),"x..x.x..x.x..x.x..x.x.","(323232322)")
--   ,((9,23),"x..x.x..x.x..x.x..x.x..","(323232323)")
--   ,((11,12),"xxxxxxxxxxx.","(11111111112)")
--   ,((11,24),"x..x.x.x.x.x..x.x.x.x.x.","(32222322222)")
--   ,((13,24),"x.xx.x.x.x.x.xx.x.x.x.x.","(2122222122222)")
--   ,((15,34),"x..x.x.x.x..x.x.x.x..x.x.x.x..x.x.","(322232223222322)")]
--   
bjorklund :: (Int, Int) -> [Bool] -- | xdot notation for pattern. -- --
--   xdot (bjorklund (5,9)) == "x.x.x.x.x"
--   
xdot :: [Bool] -> String -- | The iseq of a pattern is the distance between True -- values. -- --
--   iseq (bjorklund (5,9)) == [2,2,2,2,1]
--   
iseq :: [Bool] -> [Int] -- | iseq of pattern as compact string. -- --
--   iseq_str (bjorklund (5,9)) == "(22221)"
--   
iseq_str :: [Bool] -> String -- | List functions. module Music.Theory.List -- | Bracket sequence with left and right values. -- --
--   bracket ('<','>') "1,2,3" == "<1,2,3>"
--   
bracket :: (a, a) -> [a] -> [a] -- | Variant where brackets are sequences. -- --
--   bracket_l ("<:",":>") "1,2,3" == "<:1,2,3:>"
--   
bracket_l :: ([a], [a]) -> [a] -> [a] -- | Generic form of rotate_left. genericRotate_left :: Integral i => i -> [a] -> [a] -- | Left rotation. -- --
--   rotate_left 1 [1..3] == [2,3,1]
--   rotate_left 3 [1..5] == [4,5,1,2,3]
--   
rotate_left :: Int -> [a] -> [a] -- | Generic form of rotate_right. genericRotate_right :: Integral n => n -> [a] -> [a] -- | Right rotation. -- --
--   rotate_right 1 [1..3] == [3,1,2]
--   
rotate_right :: Int -> [a] -> [a] -- | Rotate left by n mod #p places. -- --
--   rotate 1 [1..3] == [2,3,1]
--   rotate 8 [1..5] == [4,5,1,2,3]
--   
rotate :: Integral n => n -> [a] -> [a] -- | Rotate right by n places. -- --
--   rotate_r 8 [1..5] == [3,4,5,1,2]
--   
rotate_r :: Integral n => n -> [a] -> [a] -- | All rotations. -- --
--   rotations [0,1,3] == [[0,1,3],[1,3,0],[3,0,1]]
--   
rotations :: [a] -> [[a]] -- | Generic form of adj2. genericAdj2 :: Integral n => n -> [t] -> [(t, t)] -- | Adjacent elements of list, at indicated distance, as pairs. -- --
--   adj2 1 [1..5] == [(1,2),(2,3),(3,4),(4,5)]
--   adj2 2 [1..4] == [(1,2),(3,4)]
--   adj2 3 [1..5] == [(1,2),(4,5)]
--   
adj2 :: Int -> [t] -> [(t, t)] -- | Append first element to end of list. -- --
--   close [1..3] == [1,2,3,1]
--   
close :: [a] -> [a] -- | adj2 . close. -- --
--   adj2_cyclic 1 [1..3] == [(1,2),(2,3),(3,1)]
--   
adj2_cyclic :: Int -> [t] -> [(t, t)] -- | Interleave elements of p and q. -- --
--   interleave [1..3] [4..6] == [1,4,2,5,3,6]
--   interleave ".+-" "abc" == ".a+b-c"
--   interleave [1..3] [] == []
--   
interleave :: [b] -> [b] -> [b] -- | Variant that continues with the longer input. -- --
--   interleave_continue ".+-" "abc" == ".a+b-c"
--   interleave_continue [1..3] [] == [1..3]
--   interleave_continue [] [1..3] == [1..3]
--   
interleave_continue :: [a] -> [a] -> [a] -- | interleave of rotate_left by i and j. -- --
--   interleave_rotations 9 3 [1..13] == [10,4,11,5,12,6,13,7,1,8,2,9,3,10,4,11,5,12,6,13,7,1,8,2,9,3]
--   
interleave_rotations :: Int -> Int -> [b] -> [b] -- | Count occurences of elements in list. -- --
--   histogram "hohoh" == [('h',3),('o',2)]
--   
histogram :: (Ord a, Integral i) => [a] -> [(a, i)] -- | List segments of length i at distance j. -- --
--   segments 2 1 [1..5] == [[1,2],[2,3],[3,4],[4,5]]
--   segments 2 2 [1..5] == [[1,2],[3,4]]
--   
segments :: Int -> Int -> [a] -> [[a]] -- | foldl1 intersect. -- --
--   intersect_l [[1,2],[1,2,3],[1,2,3,4]] == [1,2]
--   
intersect_l :: Eq a => [[a]] -> [a] -- | foldl1 union. -- --
--   sort (union_l [[1,3],[2,3],[3]]) == [1,2,3]
--   
union_l :: Eq a => [[a]] -> [a] -- | Intersection of adjacent elements of list at distance n. -- --
--   adj_intersect 1 [[1,2],[1,2,3],[1,2,3,4]] == [[1,2],[1,2,3]]
--   
adj_intersect :: Eq a => Int -> [[a]] -> [[a]] -- | List of cycles at distance n. -- --
--   cycles 2 [1..6] == [[1,3,5],[2,4,6]]
--   cycles 3 [1..9] == [[1,4,7],[2,5,8],[3,6,9]]
--   cycles 4 [1..8] == [[1,5],[2,6],[3,7],[4,8]]
--   
cycles :: Int -> [a] -> [[a]] -- | Given accesors for key and value collate input. -- --
--   let r = [('A',"a"),('B',"bd"),('C',"ce"),('D',"f")]
--   in collate_on fst snd (zip "ABCBCD" "abcdef")
--   
collate_on :: (Eq k, Ord k) => (a -> k) -> (a -> v) -> [a] -> [(k, [v])] -- | collate_on of fst and snd. -- --
--   collate (zip [1,2,1] "abc") == [(1,"ac"),(2,"b")]
--   
collate :: Ord a => [(a, b)] -> [(a, [b])] -- | Make assoc list with given key. -- --
--   with_key 'a' [1..3] == [('a',1),('a',2),('a',3)]
--   
with_key :: k -> [v] -> [(k, v)] -- | Intervals to values, zero is n. -- --
--   dx_d 5 [1,2,3] == [5,6,8,11]
--   
dx_d :: Num a => a -> [a] -> [a] -- | Variant that takes initial value and separates final value. This is an -- appropriate function for mapAccumL. -- --
--   dx_d' 5 [1,2,3] == (11,[5,6,8])
--   dx_d' 0 [1,1,1] == (3,[0,1,2])
--   
dx_d' :: Num t => t -> [t] -> (t, [t]) -- | Integrate, ie. pitch class segment to interval sequence. -- --
--   d_dx [5,6,8,11] == [1,2,3]
--   d_dx [] == []
--   
d_dx :: Num a => [a] -> [a] -- | Elements of p not in q. -- --
--   [1,2,3] `difference` [1,2] == [3]
--   
difference :: Eq a => [a] -> [a] -> [a] -- | Is p a subset of q, ie. is intersect of p -- and q == p. -- --
--   is_subset [1,2] [1,2,3] == True
--   
is_subset :: Eq a => [a] -> [a] -> Bool -- | Is p a superset of q, ie. flip is_subset. -- --
--   is_superset [1,2,3] [1,2] == True
--   
is_superset :: Eq a => [a] -> [a] -> Bool -- | Is p a subsequence of q, ie. synonym for -- isInfixOf. -- --
--   subsequence [1,2] [1,2,3] == True
--   
subsequence :: Eq a => [a] -> [a] -> Bool -- | Variant of elemIndices that requires e to be unique in -- p. -- --
--   elem_index_unique 'a' "abcda" == undefined
--   
elem_index_unique :: Eq a => a -> [a] -> Int -- | Basis of find_bounds. There is an option to consider the last -- element specially, and if equal to the last span is given. find_bounds' :: Bool -> (t -> s -> Ordering) -> [(t, t)] -> s -> Maybe (t, t) -- | Find adjacent elements of list that bound element under given -- comparator. -- --
--   let {f = find_bounds True compare [1..5]
--       ;r = [Nothing,Just (1,2),Just (3,4),Just (4,5)]}
--   in map f [0,1,3.5,5] == r
--   
find_bounds :: Bool -> (t -> s -> Ordering) -> [t] -> s -> Maybe (t, t) -- | Variant of drop from right of list. -- --
--   dropRight 1 [1..9] == [1..8]
--   
dropRight :: Int -> [a] -> [a] -- | Variant of dropWhile from right of list. -- --
--   dropWhileRight Data.Char.isDigit "A440" == "A"
--   
dropWhileRight :: (a -> Bool) -> [a] -> [a] -- | Apply f at first element, and g at all other elements. -- --
--   at_head negate id [1..5] == [-1,2,3,4,5]
--   
at_head :: (a -> b) -> (a -> b) -> [a] -> [b] -- | Apply f at all but last element, and g at last element. -- --
--   at_last (* 2) negate [1..4] == [2,4,6,-4]
--   
at_last :: (a -> b) -> (a -> b) -> [a] -> [b] -- | Separate list into an initial list and a last element tuple. -- --
--   separate_last [1..5] == ([1..4],5)
--   
separate_last :: [a] -> ([a], a) -- | Replace directly repeated elements with Nothing. -- --
--   indicate_repetitions "abba" == [Just 'a',Just 'b',Nothing,Just 'a']
--   
indicate_repetitions :: Eq a => [a] -> [Maybe a] -- | groupBy does not make adjacent comparisons, it compares each -- new element to the start of the group. This function is the adjacent -- variant. -- --
--   groupBy (<) [1,2,3,2,4,1,5,9] == [[1,2,3,2,4],[1,5,9]]
--   adjacent_groupBy (<) [1,2,3,2,4,1,5,9] == [[1,2,3],[2,4],[1,5,9]]
--   
adjacent_groupBy :: (a -> a -> Bool) -> [a] -> [[a]] -- | groupBy on structure of Maybe, ie. all -- Just compare equal. -- --
--   let r = [[Just 1],[Nothing,Nothing],[Just 4,Just 5]]
--   in group_just [Just 1,Nothing,Nothing,Just 4,Just 5] == r
--   
group_just :: [Maybe a] -> [[Maybe a]] -- | Predicate to determine if all elements of the list are ==. all_eq :: Eq n => [n] -> Bool -- | groupBy of sortBy. -- --
--   let r = [[('1','a'),('1','c')],[('2','d')],[('3','b'),('3','e')]]
--   in sort_group_on fst (zip "13123" "abcde") == r
--   
sort_group_on :: Ord b => (a -> b) -> [a] -> [[a]] -- | Maybe cons element onto list. -- --
--   Nothing `mcons` "something" == "something"
--   Just 's' `mcons` "omething" == "something"
--   
mcons :: Maybe a -> [a] -> [a] -- | Comparison function type. type Compare_F a = a -> a -> Ordering -- | If f compares EQ, defer to g. two_stage_compare :: Compare_F a -> Compare_F a -> Compare_F a -- | Invert Ordering. ordering_invert :: Ordering -> Ordering -- | Sort sequence a based on ordering of sequence b. -- --
--   sort_to "abc" [1,3,2] == "acb"
--   sort_to "adbce" [1,4,2,3,5] == "abcde"
--   
sort_to :: Ord i => [e] -> [i] -> [e] -- | flip of sort_to. -- --
--   sort_on [1,4,2,3,5] "adbce" == "abcde"
--   
sort_on :: Ord i => [i] -> [e] -> [e] -- | sortBy of two_stage_compare. sort_by_two_stage :: (Ord b, Ord c) => (a -> b) -> (a -> c) -> [a] -> [a] -- | Given a comparison function, merge two ascending lists. -- --
--   mergeBy compare [1,3,5] [2,4] == [1..5]
--   
merge_by :: Compare_F a -> [a] -> [a] -> [a] -- | mergeBy of two_stage_compare. merge_by_two_stage :: Ord b => (a -> b) -> Compare_F c -> (a -> c) -> [a] -> [a] -> [a] -- | mergeBy compare. merge :: Ord a => [a] -> [a] -> [a] -- | Merge list of sorted lists given comparison function. Note that this -- is not equal to mergeAll. merge_set_by :: (a -> a -> Ordering) -> [[a]] -> [a] -- | merge_set_by of compare. -- --
--   merge_set [[1,3,5,7,9],[2,4,6,8],[10]] == [1..10]
--   
merge_set :: Ord a => [[a]] -> [a] -- | merge_by variant that joins (resolves) equal elements. -- --
--   let {left p _ = p
--       ;right _ q = q
--       ;cmp = compare `on` fst
--       ;p = zip [1,3,5] "abc"
--       ;q = zip [1,2,3] "ABC"
--       ;left_r = [(1,'a'),(2,'B'),(3,'b'),(5,'c')]
--       ;right_r = [(1,'A'),(2,'B'),(3,'C'),(5,'c')]}
--   in merge_by_resolve left cmp p q == left_r &&
--      merge_by_resolve right cmp p q == right_r
--   
merge_by_resolve :: (a -> a -> a) -> Compare_F a -> [a] -> [a] -> [a] -- | Apply f to both elements of a two-tuple, ie. bimap -- f f. bimap1 :: (t -> u) -> (t, t) -> (u, u) -- | Basic temporal sequence functions. module Music.Theory.Time.Seq -- | Sequence of elements with uniform duration. type Useq t a = (t, [a]) -- | Duration sequence. The duration is the forward duration of the -- value, if it has other durations they must be encoded at a. type Dseq t a = [(t, a)] -- | Inter-offset sequence. The duration is the interval before the -- value. To indicate the duration of the final value a must have -- an nil (end of sequence) value. type Iseq t a = [(t, a)] -- | Pattern sequence. The duration is a triple of logical, -- sounding and forward durations. type Pseq t a = [((t, t, t), a)] -- | Time-point sequence. To express holes a must have a -- empty value. To indicate the duration of the final value -- a must have an nil (end of sequence) value. type Tseq t a = [(t, a)] -- | Window sequence. The temporal field is (time,duration). -- Holes exist where t(n) + d(n) < t(n+1). -- Overlaps exist where the same relation is >. type Wseq t a = [((t, t), a)] pseq_zip :: [t] -> [t] -> [t] -> [a] -> Pseq t a wseq_zip :: [t] -> [t] -> [a] -> Wseq t a -- | Given functions for deriving start and end times calculate time span -- of sequence. -- --
--   seq_tspan id id [] == (0,0)
--   seq_tspan id id (zip [0..9] ['a'..]) == (0,9)
--   
seq_tspan :: Num n => (t -> n) -> (t -> n) -> [(t, a)] -> (n, n) tseq_tspan :: Num t => Tseq t a -> (t, t) wseq_tspan :: Num t => Wseq t a -> (t, t) dseq_dur :: Num t => Dseq t a -> t iseq_dur :: Num t => Iseq t a -> t pseq_dur :: Num t => Pseq t a -> t -- | The interval of tseq_tspan. -- --
--   tseq_dur (zip [0..] "abcde|") == 5
--   
tseq_dur :: Num t => Tseq t a -> t -- | The interval of wseq_tspan. -- --
--   wseq_dur (zip (zip [0..] (repeat 2)) "abcde") == 6
--   
wseq_dur :: Num t => Wseq t a -> t -- | Keep only elements in the indicated temporal window. -- --
--   let r = [((5,1),'e'),((6,1),'f'),((7,1),'g'),((8,1),'h')]
--   in wseq_twindow (5,9) (zip (zip [1..10] (repeat 1)) ['a'..]) == r
--   
wseq_twindow :: (Num t, Ord t) => (t, t) -> Wseq t a -> Wseq t a dseq_append :: Dseq t a -> Dseq t a -> Dseq t a iseq_append :: Iseq t a -> Iseq t a -> Iseq t a pseq_append :: Pseq t a -> Pseq t a -> Pseq t a -- | Merge comparing only on time. tseq_merge :: Ord t => Tseq t a -> Tseq t a -> Tseq t a -- | Merge, where times are equal compare values. tseq_merge_by :: Ord t => Compare_F a -> Tseq t a -> Tseq t a -> Tseq t a -- | Merge, where times are equal apply f to form a single value. -- --
--   let {p = zip [1,3,5] "abc"
--       ;q = zip [1,2,3] "ABC"
--       ;left_r = [(1,'a'),(2,'B'),(3,'b'),(5,'c')]
--       ;right_r = [(1,'A'),(2,'B'),(3,'C'),(5,'c')]}
--   in tseq_merge_resolve (\x _ -> x) p q == left_r &&
--      tseq_merge_resolve (\_ x -> x) p q == right_r
--   
tseq_merge_resolve :: Ord t => (a -> a -> a) -> Tseq t a -> Tseq t a -> Tseq t a wseq_merge :: Ord t => Wseq t a -> Wseq t a -> Wseq t a tseq_lookup_window_by :: (t -> t -> Ordering) -> Tseq t e -> t -> (Maybe (t, e), Maybe (t, e)) tseq_lookup_active_by :: (t -> t -> Ordering) -> Tseq t e -> t -> Maybe e tseq_lookup_active :: Ord t => Tseq t e -> t -> Maybe e tseq_lookup_active_by_def :: e -> (t -> t -> Ordering) -> Tseq t e -> t -> e tseq_lookup_active_def :: Ord t => e -> Tseq t e -> t -> e data Interpolation_T None :: Interpolation_T Linear :: Interpolation_T -- | Variant of Tseq where nodes have an Intepolation_T -- value. type Lseq t a = Tseq (t, Interpolation_T) a -- | Linear interpolation. lerp :: (Fractional t, Real t, Fractional e) => (t, e) -> (t, e) -> t -> e -- | Temporal map. lseq_tmap :: (t -> t') -> Lseq t a -> Lseq t' a -- | This can give Nothing if t precedes the Lseq or -- if t is after the final element of Lseq and that element -- has an interpolation type other than None. lseq_lookup :: (Fractional t, Real t, Fractional e) => (t -> t -> Ordering) -> Lseq t e -> t -> Maybe e -- | erroring variant. lseq_lookup_err :: (Fractional t, Real t, Fractional e) => (t -> t -> Ordering) -> Lseq t e -> t -> e seq_tmap :: (t -> t') -> [(t, a)] -> [(t', a)] seq_map :: (b -> c) -> [(a, b)] -> [(a, c)] -- | Map t and e simultaneously. seq_bimap :: (t -> t') -> (e -> e') -> [(t, e)] -> [(t', e')] seq_tfilter :: (t -> Bool) -> [(t, a)] -> [(t, a)] seq_filter :: (b -> Bool) -> [(a, b)] -> [(a, b)] seq_find :: (a -> Bool) -> [(t, a)] -> Maybe (t, a) -- | mapMaybe variant. seq_map_maybe :: (p -> Maybe q) -> [(t, p)] -> [(t, q)] -- | Variant of catMaybes. seq_cat_maybes :: [(t, Maybe q)] -> [(t, q)] -- | If value is unchanged, according to f, replace with -- Nothing. -- --
--   let r = [(1,'s'),(2,'t'),(4,'r'),(6,'i'),(7,'n'),(9,'g')]
--   in seq_cat_maybes (seq_changed_by (==) (zip [1..] "sttrrinng")) == r
--   
seq_changed_by :: (a -> a -> Bool) -> [(t, a)] -> [(t, Maybe a)] -- | seq_changed_by ==. seq_changed :: Eq a => [(t, a)] -> [(t, Maybe a)] -- | Apply f at time points of Wseq. wseq_tmap_st :: (t -> t) -> Wseq t a -> Wseq t a -- | Apply f at durations of elements of Wseq. wseq_tmap_dur :: (t -> t) -> Wseq t a -> Wseq t a -- | Given a function that determines a voice for a value, partition -- a sequence into voices. seq_partition :: Ord v => (a -> v) -> [(t, a)] -> [(v, [(t, a)])] -- | Type specialised seq_partition. -- --
--   let {p = zip [0,1,3,5] (zip (repeat 0) "abcd")
--       ;q = zip [2,4,6,7] (zip (repeat 1) "ABCD")
--       ;sq = tseq_merge p q}
--   in tseq_partition fst sq == [(0,p),(1,q)]
--   
tseq_partition :: Ord v => (a -> v) -> Tseq t a -> [(v, Tseq t a)] wseq_partition :: Ord v => (a -> v) -> Wseq t a -> [(v, Wseq t a)] -- | Given a decision predicate and a join function, recursively join -- adjacent elements. -- --
--   coalesce_f undefined undefined [] == []
--   coalesce_f (==) const "abbcccbba" == "abcba"
--   coalesce_f (==) (+) [1,2,2,3,3,3] == [1,4,6,3]
--   
coalesce_f :: (t -> t -> Bool) -> (t -> t -> t) -> [t] -> [t] -- | coalesce_f using mappend for the join function. coalesce_m :: Monoid t => (t -> t -> Bool) -> [t] -> [t] -- | Form of coalesce_f where the decision predicate is on the -- element, and a join function sums the times. -- --
--   let r = [(1,'a'),(2,'b'),(3,'c'),(2,'d'),(1,'e')]
--   in seq_coalesce (==) const (useq_to_dseq (1,"abbcccdde")) == r
--   
seq_coalesce :: Num t => (a -> a -> Bool) -> (a -> a -> a) -> [(t, a)] -> [(t, a)] dseq_coalesce :: Num t => (a -> a -> Bool) -> (a -> a -> a) -> Dseq t a -> Dseq t a -- | Given equality predicate, simplify sequence by summing -- durations of adjacent equal elements. This is a special case of -- dseq_coalesce where the join function is const. -- The implementation is simpler and non-recursive. -- --
--   let {d = useq_to_dseq (1,"abbcccdde")
--       ;r = dseq_coalesce (==) const d}
--   in dseq_coalesce' (==) d == r
--   
dseq_coalesce' :: Num t => (a -> a -> Bool) -> Dseq t a -> Dseq t a iseq_coalesce :: Num t => (a -> a -> Bool) -> (a -> a -> a) -> Iseq t a -> Iseq t a seq_tcoalesce :: (t -> t -> Bool) -> (a -> a -> a) -> [(t, a)] -> [(t, a)] tseq_tcoalesce :: Eq t => (a -> a -> a) -> Tseq t a -> Tseq t a wseq_tcoalesce :: ((t, t) -> (t, t) -> Bool) -> (a -> a -> a) -> Wseq t a -> Wseq t a -- | Post-process groupBy of cmp on fst. -- --
--   let r = [(0,"a"),(1,"bc"),(2,"de"),(3,"f")]
--   in group_f (==) (zip [0,1,1,2,2,3] ['a'..]) == r
--   
group_f :: (Eq t, Num t) => (t -> t -> Bool) -> [(t, a)] -> [(t, [a])] -- | Group values at equal time points. -- --
--   let r = [(0,"a"),(1,"bc"),(2,"de"),(3,"f")]
--   in tseq_group (zip [0,1,1,2,2,3] ['a'..]) == r
--   
tseq_group :: (Eq t, Num t) => Tseq t a -> Tseq t [a] -- | Group values where the inter-offset time is 0 to the left. -- --
--   let r = [(0,"a"),(1,"bcd"),(1,"ef")]
--   in iseq_group (zip [0,1,0,0,1,0] ['a'..]) == r
--   
iseq_group :: (Eq t, Num t) => Iseq t a -> Iseq t [a] -- | Set durations so that there are no gaps or overlaps. -- --
--   let r = wseq_zip [0,3,5] [3,2,1] "abc"
--   in wseq_fill_dur (wseq_zip [0,3,5] [2,1,1] "abc") == r
--   
wseq_fill_dur :: Num t => Wseq t a -> Wseq t a dseq_lcm :: Dseq Rational e -> Integer -- | Scale by lcm so that all durations are integral. dseq_set_whole :: [Dseq Rational e] -> [Dseq Integer e] -- | Given a a default value, a Tseq sq and a list of -- time-points t, generate a Tseq that is a union of the -- timepoints at sq and t where times in t not at -- sq are given the current value, or def if there -- is no value. -- --
--   tseq_latch 'a' [(2,'b'),(4,'c')] [1..5] == zip [1..5] "abbcc"
--   
tseq_latch :: Ord t => a -> Tseq t a -> [t] -> Tseq t a -- | Transform Wseq to Tseq by discaring durations. wseq_discard_dur :: Wseq t a -> Tseq t a -- | Edit durations to ensure that notes don't overlap. If the same note is -- played simultaneously delete shorter note. If a note extends into a -- later note shorten duration (apply d_fn to iot). wseq_remove_overlaps :: (Eq e, Ord t, Num t) => (e -> e -> Bool) -> (t -> t) -> Wseq t e -> Wseq t e -- | Unjoin elements (assign equal time stamps to all elements). seq_unjoin :: [(t, [e])] -> [(t, e)] -- | Type specialised. wseq_unjoin :: Wseq t [e] -> Wseq t e -- | Container for values that have on and off modes. data On_Off a On :: a -> On_Off a Off :: a -> On_Off a -- | Structural comparison at On_Off, On compares less than -- Off. cmp_on_off :: On_Off a -> On_Off b -> Ordering -- | Translate container types. either_to_on_off :: Either a a -> On_Off a -- | Translate container types. on_off_to_either :: On_Off a -> Either a a -- | Convert Wseq to Tseq transforming elements to On -- and Off parts. When merging, off elements precede -- on elements at equal times. -- --
--   let {sq = [((0,5),'a'),((2,2),'b')]
--       ;r = [(0,On 'a'),(2,On 'b'),(4,Off 'b'),(5,Off 'a')]}
--   in wseq_on_off sq == r
--   
-- --
--   let {sq = [((0,1),'a'),((1,1),'b'),((2,1),'c')]
--       ;r = [(0,On 'a'),(1,Off 'a')
--            ,(1,On 'b'),(2,Off 'b')
--            ,(2,On 'c'),(3,Off 'c')]}
--   in wseq_on_off sq == r
--   
wseq_on_off :: (Num t, Ord t) => Wseq t a -> Tseq t (On_Off a) -- | on_off_to_either of wseq_on_off. wseq_on_off_either :: (Num t, Ord t) => Wseq t a -> Tseq t (Either a a) -- | Variant that applies on and off functions to nodes. -- --
--   let {sq = [((0,5),'a'),((2,2),'b')]
--       ;r = [(0,'A'),(2,'B'),(4,'b'),(5,'a')]}
--   in wseq_on_off_f Data.Char.toUpper id sq == r
--   
wseq_on_off_f :: (Ord t, Num t) => (a -> b) -> (a -> b) -> Wseq t a -> Tseq t b -- | Inverse of wseq_on_off given a predicate function for locating -- the off node of an on node. -- --
--   let {sq = [(0,On 'a'),(2,On 'b'),(4,Off 'b'),(5,Off 'a')]
--       ;r = [((0,5),'a'),((2,2),'b')]}
--   in tseq_on_off_to_wseq (==) sq == r
--   
tseq_on_off_to_wseq :: Num t => (a -> a -> Bool) -> Tseq t (On_Off a) -> Wseq t a useq_to_dseq :: Useq t a -> Dseq t a -- | The conversion requires a start time and a nil value used as an -- eof marker. Productive given indefinite input sequence. -- --
--   let r = zip [0,1,3,6,8,9] "abcde|"
--   in dseq_to_tseq 0 '|' (zip [1,2,3,2,1] "abcde") == r
--   
-- --
--   let {d = zip [1,2,3,2,1] "abcde"
--       ;r = zip [0,1,3,6,8,9,10] "abcdeab"}
--   in take 7 (dseq_to_tseq 0 undefined (cycle d)) == r
--   
dseq_to_tseq :: Num t => t -> a -> Dseq t a -> Tseq t a -- | Variant where the nil is take as the last element of the -- sequence. -- --
--   let r = zip [0,1,3,6,8,9] "abcdee"
--   in dseq_to_tseq_last 0 (zip [1,2,3,2,1] "abcde") == r
--   
dseq_to_tseq_last :: Num t => t -> Dseq t a -> Tseq t a -- | The conversion requires a start time and does not consult the -- logical duration. -- --
--   let p = pseq_zip (repeat undefined) (cycle [1,2]) (cycle [1,1,2]) "abcdef"
--   in pseq_to_wseq 0 p == wseq_zip [0,1,2,4,5,6] (cycle [1,2]) "abcdef"
--   
pseq_to_wseq :: Num t => t -> Pseq t a -> Wseq t a -- | The last element of Tseq is required to be an eof marker -- that has no duration and is not represented in the Dseq. -- --
--   let r = zip [1,2,3,2,1] "abcde"
--   in tseq_to_dseq undefined (zip [0,1,3,6,8,9] "abcde|") == r
--   
-- --
--   let r = zip [1,2,3,2,1] "-abcd"
--   in tseq_to_dseq '-' (zip [1,3,6,8,9] "abcd|") == r
--   
tseq_to_dseq :: (Ord t, Num t) => a -> Tseq t a -> Dseq t a -- | The last element of Tseq is required to be an eof marker -- that has no duration and is not represented in the Wseq. The -- duration of each value is either derived from the value, if an -- dur function is given, or else the inter-offset time. -- --
--   let r = wseq_zip [0,1,3,6,8] [1,2,3,2,1] "abcde"
--   in tseq_to_wseq Nothing (zip [0,1,3,6,8,9] "abcde|") == r
--   
-- --
--   let r = wseq_zip [0,1,3,6,8] (map fromEnum "abcde") "abcde"
--   in tseq_to_wseq (Just fromEnum) (zip [0,1,3,6,8,9] "abcde|") == r
--   
tseq_to_wseq :: Num t => Maybe (a -> t) -> Tseq t a -> Wseq t a tseq_to_iseq :: Num t => Tseq t a -> Dseq t a -- | Requires start time. -- --
--   let r = zip (zip [0,1,3,6,8,9] [1,2,3,2,1]) "abcde"
--   in dseq_to_wseq 0 (zip [1,2,3,2,1] "abcde") == r
--   
dseq_to_wseq :: Num t => t -> Dseq t a -> Wseq t a -- | Inverse of dseq_to_wseq. The empty value is used to fill -- holes in Wseq. If values overlap at Wseq durations are -- truncated. -- --
--   let w = wseq_zip [0,1,3,6,8,9] [1,2,3,2,1] "abcde"
--   in wseq_to_dseq '-' w == zip [1,2,3,2,1] "abcde"
--   
-- --
--   let w = wseq_zip [3,10] [6,2] "ab"
--   in wseq_to_dseq '-' w == zip [3,6,1,2] "-a-b"
--   
-- --
--   let w = wseq_zip [0,1] [2,2] "ab"
--   in wseq_to_dseq '-' w == zip [1,2] "ab"
--   
-- --
--   let w = wseq_zip [0,0,0] [2,2,2] "abc"
--   in wseq_to_dseq '-' w == zip [0,0,2] "abc"
--   
wseq_to_dseq :: (Num t, Ord t) => a -> Wseq t a -> Dseq t a -- | Given a list of Dseq (measures) convert to a list of -- Tseq and the end time of the overall sequence. -- --
--   let r = [[(0,'a'),(1,'b'),(3,'c')],[(4,'d'),(7,'e'),(9,'f')]]
--   in dseql_to_tseql 0 [zip [1,2,1] "abc",zip [3,2,1] "def"] == (10,r)
--   
dseql_to_tseql :: Num t => t -> [Dseq t a] -> (t, [Tseq t a]) dseq_tmap :: (t -> t') -> Dseq t a -> Dseq t' a pseq_tmap :: ((t, t, t) -> (t', t', t')) -> Pseq t a -> Pseq t' a tseq_tmap :: (t -> t') -> Dseq t a -> Dseq t' a tseq_bimap :: (t -> t') -> (e -> e') -> Tseq t e -> Tseq t' e' wseq_tmap :: ((t, t) -> (t', t')) -> Wseq t a -> Wseq t' a dseq_map :: (a -> b) -> Dseq t a -> Dseq t b pseq_map :: (a -> b) -> Pseq t a -> Pseq t b tseq_map :: (a -> b) -> Tseq t a -> Tseq t b wseq_map :: (a -> b) -> Wseq t a -> Wseq t b dseq_tfilter :: (t -> Bool) -> Dseq t a -> Dseq t a iseq_tfilter :: (t -> Bool) -> Iseq t a -> Iseq t a pseq_tfilter :: ((t, t, t) -> Bool) -> Pseq t a -> Pseq t a tseq_tfilter :: (t -> Bool) -> Tseq t a -> Tseq t a wseq_tfilter :: ((t, t) -> Bool) -> Wseq t a -> Wseq t a dseq_filter :: (a -> Bool) -> Dseq t a -> Dseq t a iseq_filter :: (a -> Bool) -> Iseq t a -> Iseq t a pseq_filter :: (a -> Bool) -> Pseq t a -> Pseq t a tseq_filter :: (a -> Bool) -> Tseq t a -> Tseq t a wseq_filter :: (a -> Bool) -> Wseq t a -> Wseq t a wseq_map_maybe :: (a -> Maybe b) -> Wseq t a -> Wseq t b wseq_cat_maybes :: Wseq t (Maybe a) -> Wseq t a instance Eq Interpolation_T instance Enum Interpolation_T instance Show Interpolation_T instance Eq a => Eq (On_Off a) instance Show a => Show (On_Off a) -- | Regular array data as markdown (MD) tables. module Music.Theory.Array.MD -- | Append k to the right of l until result has n -- places. pad_right :: a -> Int -> [a] -> [a] -- | Append k to each row of tbl as required to be regular -- (all rows equal length). make_regular :: a -> [[a]] -> [[a]] -- | Delete trailing Char where isSpace holds. delete_trailing_whitespace :: [Char] -> [Char] -- | Optional header row then data rows. type MD_Table t = (Maybe [String], [[t]]) -- | Join second table to right of initial table. md_table_join :: MD_Table a -> MD_Table a -> MD_Table a -- | Add a row number column at the front of the table. md_number_rows :: MD_Table String -> MD_Table String -- | Markdown table, perhaps with header. Table is in row order. Options -- are: pad_left. -- --
--   md_table_opt False (Nothing,[["a","bc","def"],["ghij","klm","no","p"]])
--   
md_table_opt :: Bool -> MD_Table String -> [String] md_table' :: MD_Table String -> [String] -- | curry of md_table'. md_table :: Maybe [String] -> [[String]] -> [String] -- | Variant relying on Show instances. -- --
--   md_table_show Nothing [[1..4],[5..8],[9..12]]
--   
md_table_show :: Show t => Maybe [String] -> [[t]] -> [String] -- | Variant in column order (ie. transpose). -- --
--   md_table_column_order [["a","bc","def"],["ghij","klm","no"]]
--   
md_table_column_order :: Maybe [String] -> [[String]] -> [String] -- | Two-tuple show variant. md_table_p2 :: (Show a, Show b) => Maybe [String] -> ([a], [b]) -> [String] -- | Three-tuple show variant. md_table_p3 :: (Show a, Show b, Show c) => Maybe [String] -> ([a], [b], [c]) -> [String] -- | Matrix form, ie. header in both first row and first column, in each -- case displaced by one location which is empty. -- --
--   let t = md_matrix "" (map return "abc") (map (map show) [[1,2,3],[2,3,1],[3,1,2]])
--   
-- --
--   >>> putStrLn $ unlines $ md_table' t
--   - - - -
--     a b c
--   a 1 2 3
--   b 2 3 1
--   c 3 1 2
--   - - - -
--   
md_matrix :: a -> [a] -> [[a]] -> MD_Table a -- | Variant for String tables where nil is the empty string -- and the header cells are in bold. md_matrix_bold :: [String] -> [[String]] -> MD_Table String -- | Tom Johnson. "Networks". In Conference on Mathematics and Computation -- in Music, Berlin, May 2007. module Music.Theory.Block_Design.Johnson_2007 data Design i Design :: [i] -> [[i]] -> Design i c_7_3_1 :: Num i => [i] b_7_3_1 :: (Ord i, Num i) => ([[i]], [[i]]) d_7_3_1 :: (Enum n, Ord n, Num n) => (Design n, Design n) n_7_3_1 :: Num i => [(i, i)] p_9_3_1 :: Num i => [[i]] b_13_4_1 :: (Enum i, Num i, Ord i) => ([[i]], [[i]]) d_13_4_1 :: (Enum n, Ord n, Num n) => (Design n, Design n) n_13_4_1 :: Num i => [(i, i)] b_12_4_3 :: Integral i => [[i]] n_12_4_3 :: Num i => [(i, i)] -- | Common music notation pitch values. module Music.Theory.Pitch -- | Pitch classes are modulo twelve integers. type PitchClass = Int -- | Octaves are integers, the octave of middle C is 4. type Octave = Int -- | Octave and PitchClass duple. type Octave_PitchClass i = (i, i) type OctPC = (Octave, PitchClass) -- | Common music notation pitch value. data Pitch Pitch :: Note_T -> Alteration_T -> Octave -> Pitch note :: Pitch -> Note_T alteration :: Pitch -> Alteration_T octave :: Pitch -> Octave -- | Generalised pitch, given by a generalised alteration. data Pitch' Pitch' :: Note_T -> Alteration_T' -> Octave -> Pitch' -- | Pretty printer for Pitch'. pitch'_pp :: Pitch' -> String -- | Pitch' printed without octave. pitch'_class_pp :: Pitch' -> String -- | Simplify Pitch to standard 12ET by deleting quarter tones. -- --
--   let p = Pitch A QuarterToneSharp 4
--   in alteration (pitch_clear_quarter_tone p) == Sharp
--   
pitch_clear_quarter_tone :: Pitch -> Pitch -- | Pitch to Octave and PitchClass notation. -- --
--   pitch_to_octpc (Pitch F Sharp 4) == (4,6)
--   
pitch_to_octpc :: Integral i => Pitch -> Octave_PitchClass i -- | Is Pitch 12-ET. pitch_is_12et :: Pitch -> Bool -- | Pitch to midi note number notation. -- --
--   pitch_to_midi (Pitch A Natural 4) == 69
--   
pitch_to_midi :: Integral i => Pitch -> i -- | Pitch to fractional midi note number notation. -- --
--   pitch_to_fmidi (Pitch A QuarterToneSharp 4) == 69.5
--   
pitch_to_fmidi :: Fractional n => Pitch -> n -- | Extract PitchClass of Pitch -- --
--   pitch_to_pc (Pitch A Natural 4) == 9
--   pitch_to_pc (Pitch F Sharp 4) == 6
--   
pitch_to_pc :: Pitch -> PitchClass -- | Pitch comparison, implemented via pitch_to_fmidi. -- --
--   pitch_compare (Pitch A Natural 4) (Pitch A QuarterToneSharp 4) == LT
--   
pitch_compare :: Pitch -> Pitch -> Ordering -- | Given Spelling function translate from OctPC notation to -- Pitch. octpc_to_pitch :: Integral i => Spelling i -> Octave_PitchClass i -> Pitch -- | Normalise OctPC value, ie. ensure PitchClass is in -- (0,11). -- --
--   octpc_nrm (4,16) == (5,4)
--   
octpc_nrm :: Integral i => Octave_PitchClass i -> Octave_PitchClass i -- | Transpose OctPC value. -- --
--   octpc_trs 7 (4,9) == (5,4)
--   octpc_trs (-11) (4,9) == (3,10)
--   
octpc_trs :: Integral i => i -> Octave_PitchClass i -> Octave_PitchClass i -- | OctPC value to integral midi note number. -- --
--   octpc_to_midi (4,9) == 69
--   
octpc_to_midi :: Integral i => Octave_PitchClass i -> i -- | fromIntegral of octpc_to_midi. octpc_to_fmidi :: (Integral i, Num n) => Octave_PitchClass i -> n -- | Inverse of octpc_to_midi. -- --
--   midi_to_octpc 69 == (4,9)
--   
midi_to_octpc :: Integral i => i -> Octave_PitchClass i -- | Enumerate range, inclusive. -- --
--   octpc_range ((3,8),(4,1)) == [(3,8),(3,9),(3,10),(3,11),(4,0),(4,1)]
--   
octpc_range :: (OctPC, OctPC) -> [OctPC] -- | Midi note number to Pitch. -- --
--   let r = ["C4","E♭4","F♯4"]
--   in map (pitch_pp . midi_to_pitch pc_spell_ks) [60,63,66] == r
--   
midi_to_pitch :: Integral i => Spelling i -> i -> Pitch -- | Fractional midi note number to Pitch. -- --
--   import Music.Theory.Pitch.Spelling
--   pitch_pp (fmidi_to_pitch pc_spell_ks 65.5) == "F𝄲4"
--   pitch_pp (fmidi_to_pitch pc_spell_ks 66.5) == "F𝄰4"
--   pitch_pp (fmidi_to_pitch pc_spell_ks 67.5) == "A𝄭4"
--   pitch_pp (fmidi_to_pitch pc_spell_ks 69.5) == "B𝄭4"
--   
fmidi_to_pitch :: RealFrac n => Spelling Int -> n -> Pitch -- | Composition of pitch_to_fmidi and then fmidi_to_pitch. -- --
--   import Music.Theory.Pitch.Name as T
--   import Music.Theory.Pitch.Spelling as T
--   
-- --
--   pitch_tranpose T.pc_spell_ks 2 T.ees5 == T.f5
--   
pitch_tranpose :: RealFrac n => Spelling Int -> n -> Pitch -> Pitch -- | Set octave of p2 so that it nearest to p1. -- --
--   import Music.Theory.Pitch.Name as T
--   
-- --
--   let {r = ["B1","C2","C#2"];f = pitch_in_octave_nearest T.cis2}
--   in map (pitch_pp_iso . f) [T.b4,T.c4,T.cis4] == r
--   
pitch_in_octave_nearest :: Pitch -> Pitch -> Pitch -- | Raise Note_T of Pitch, account for octave transposition. -- --
--   pitch_note_raise (Pitch B Natural 3) == Pitch C Natural 4
--   
pitch_note_raise :: Pitch -> Pitch -- | Lower Note_T of Pitch, account for octave transposition. -- --
--   pitch_note_lower (Pitch C Flat 4) == Pitch B Flat 3
--   
pitch_note_lower :: Pitch -> Pitch -- | Rewrite Pitch to not use 3/4 tone alterations, ie. -- re-spell to 1/4 alteration. -- --
--   let {p = Pitch A ThreeQuarterToneFlat 4
--       ;q = Pitch G QuarterToneSharp 4}
--   in pitch_rewrite_threequarter_alteration p == q
--   
pitch_rewrite_threequarter_alteration :: Pitch -> Pitch -- | Apply function to octave of PitchClass. -- --
--   pitch_edit_octave (+ 1) (Pitch A Natural 4) == Pitch A Natural 5
--   
pitch_edit_octave :: (Octave -> Octave) -> Pitch -> Pitch -- | Midi note number to cycles per second. -- --
--   map midi_to_cps [60,69] == [261.6255653005986,440.0]
--   
midi_to_cps :: (Integral i, Floating f) => i -> f -- | Fractional midi note number to cycles per second. -- --
--   map fmidi_to_cps [69,69.1] == [440.0,442.5488940698553]
--   
fmidi_to_cps :: Floating a => a -> a -- | fmidi_to_cps of pitch_to_fmidi. pitch_to_cps :: Floating n => Pitch -> n -- | Frequency (cycles per second) to midi note number, ie. -- round of cps_to_fmidi. -- --
--   map cps_to_midi [261.6,440] == [60,69]
--   
cps_to_midi :: (Integral i, Floating f, RealFrac f) => f -> i -- | Frequency (cycles per second) to fractional midi note number. -- --
--   cps_to_fmidi 440 == 69
--   cps_to_fmidi (fmidi_to_cps 60.25) == 60.25
--   
cps_to_fmidi :: Floating a => a -> a -- | Midi note number with cents detune. type Midi_Detune = (Int, Double) -- | Frequency (in hertz) to Midi_Detune. -- --
--   map (fmap round . cps_to_midi_detune) [440.00,508.35] == [(69,0),(71,50)]
--   
cps_to_midi_detune :: Double -> Midi_Detune -- | Inverse of cps_to_midi_detune. midi_detune_to_cps :: Midi_Detune -> Double -- | midi_to_cps of octpc_to_midi. -- --
--   octpc_to_cps (4,9) == 440
--   
octpc_to_cps :: (Integral i, Floating n) => Octave_PitchClass i -> n -- | midi_to_octpc of cps_to_midi. cps_to_octpc :: (Floating f, RealFrac f, Integral i) => f -> Octave_PitchClass i -- | Slight generalisation of ISO pitch representation. Allows octave to be -- elided, pitch names to be lower case, and double sharps written as -- ##. -- -- See http://www.musiccog.ohio-state.edu/Humdrum/guide04.html -- --
--   let r = [Pitch C Natural 4,Pitch A Flat 5,Pitch F DoubleSharp 6]
--   in mapMaybe (parse_iso_pitch_oct 4) ["C","Ab5","f##6",""] == r
--   
parse_iso_pitch_oct :: Octave -> String -> Maybe Pitch -- | Variant of parse_iso_pitch_oct requiring octave. parse_iso_pitch :: String -> Maybe Pitch -- | Pretty printer for Pitch (unicode, see -- alteration_symbol). -- --
--   pitch_pp (Pitch E Flat 4) == "E♭4"
--   pitch_pp (Pitch F QuarterToneSharp 3) == "F𝄲3"
--   
pitch_pp :: Pitch -> String -- | Pitch printed without octave. pitch_class_pp :: Pitch -> String -- | Sequential list of n pitch class names starting from k. -- --
--   pitch_class_names_12et 11 2 == ["B","C"]
--   
pitch_class_names_12et :: Integral n => n -> n -> [String] -- | Pretty printer for Pitch (ISO, ASCII, see -- alteration_iso). -- --
--   pitch_pp_iso (Pitch E Flat 4) == "Eb4"
--   pitch_pp_iso (Pitch F DoubleSharp 3) == "Fx3"
--   
pitch_pp_iso :: Pitch -> String -- | Pretty printer for Pitch (ASCII, see alteration_tonh). -- --
--   pitch_pp_hly (Pitch E Flat 4) == "ees4"
--   pitch_pp_hly (Pitch F QuarterToneSharp 3) == "fih3"
--   pitch_pp_hly (Pitch B Natural 6) == "b6"
--   
pitch_pp_hly :: Pitch -> String -- | Pretty printer for Pitch (Tonhöhe, see alteration_tonh). -- --
--   pitch_pp_tonh (Pitch E Flat 4) == "Es4"
--   pitch_pp_tonh (Pitch F QuarterToneSharp 3) == "Fih3"
--   pitch_pp_tonh (Pitch B Natural 6) == "H6"
--   
pitch_pp_tonh :: Pitch -> String instance Eq Pitch instance Show Pitch instance Eq Pitch' instance Show Pitch' instance Ord Pitch -- | Constants names for Pitch values. eses indicates double -- flat, eseh three quarter tone flat, es flat, eh -- quarter tone flat, ih quarter tone sharp, is sharp, -- isih three quarter tone sharp and isis double sharp. module Music.Theory.Pitch.Name a0 :: Pitch b0 :: Pitch bes0 :: Pitch ais0 :: Pitch bis0 :: Pitch c1 :: Pitch b1 :: Pitch a1 :: Pitch g1 :: Pitch f1 :: Pitch e1 :: Pitch d1 :: Pitch ces1 :: Pitch bes1 :: Pitch aes1 :: Pitch ges1 :: Pitch fes1 :: Pitch ees1 :: Pitch des1 :: Pitch cis1 :: Pitch bis1 :: Pitch ais1 :: Pitch gis1 :: Pitch fis1 :: Pitch eis1 :: Pitch dis1 :: Pitch c2 :: Pitch b2 :: Pitch a2 :: Pitch g2 :: Pitch f2 :: Pitch e2 :: Pitch d2 :: Pitch ces2 :: Pitch bes2 :: Pitch aes2 :: Pitch ges2 :: Pitch fes2 :: Pitch ees2 :: Pitch des2 :: Pitch cis2 :: Pitch bis2 :: Pitch ais2 :: Pitch gis2 :: Pitch fis2 :: Pitch eis2 :: Pitch dis2 :: Pitch cisis2 :: Pitch bisis2 :: Pitch aisis2 :: Pitch gisis2 :: Pitch fisis2 :: Pitch eisis2 :: Pitch disis2 :: Pitch ceseh2 :: Pitch beseh2 :: Pitch aeseh2 :: Pitch geseh2 :: Pitch feseh2 :: Pitch eeseh2 :: Pitch deseh2 :: Pitch ceh2 :: Pitch beh2 :: Pitch aeh2 :: Pitch geh2 :: Pitch feh2 :: Pitch eeh2 :: Pitch deh2 :: Pitch cih2 :: Pitch bih2 :: Pitch aih2 :: Pitch gih2 :: Pitch fih2 :: Pitch eih2 :: Pitch dih2 :: Pitch cisih2 :: Pitch bisih2 :: Pitch aisih2 :: Pitch gisih2 :: Pitch fisih2 :: Pitch eisih2 :: Pitch disih2 :: Pitch c3 :: Pitch b3 :: Pitch a3 :: Pitch g3 :: Pitch f3 :: Pitch e3 :: Pitch d3 :: Pitch ces3 :: Pitch bes3 :: Pitch aes3 :: Pitch ges3 :: Pitch fes3 :: Pitch ees3 :: Pitch des3 :: Pitch cis3 :: Pitch bis3 :: Pitch ais3 :: Pitch gis3 :: Pitch fis3 :: Pitch eis3 :: Pitch dis3 :: Pitch ceses3 :: Pitch beses3 :: Pitch aeses3 :: Pitch geses3 :: Pitch feses3 :: Pitch eeses3 :: Pitch deses3 :: Pitch cisis3 :: Pitch bisis3 :: Pitch aisis3 :: Pitch gisis3 :: Pitch fisis3 :: Pitch eisis3 :: Pitch disis3 :: Pitch ceseh3 :: Pitch beseh3 :: Pitch aeseh3 :: Pitch geseh3 :: Pitch feseh3 :: Pitch eeseh3 :: Pitch deseh3 :: Pitch ceh3 :: Pitch beh3 :: Pitch aeh3 :: Pitch geh3 :: Pitch feh3 :: Pitch eeh3 :: Pitch deh3 :: Pitch cih3 :: Pitch bih3 :: Pitch aih3 :: Pitch gih3 :: Pitch fih3 :: Pitch eih3 :: Pitch dih3 :: Pitch cisih3 :: Pitch bisih3 :: Pitch aisih3 :: Pitch gisih3 :: Pitch fisih3 :: Pitch eisih3 :: Pitch disih3 :: Pitch c4 :: Pitch b4 :: Pitch a4 :: Pitch g4 :: Pitch f4 :: Pitch e4 :: Pitch d4 :: Pitch ces4 :: Pitch bes4 :: Pitch aes4 :: Pitch ges4 :: Pitch fes4 :: Pitch ees4 :: Pitch des4 :: Pitch cis4 :: Pitch bis4 :: Pitch ais4 :: Pitch gis4 :: Pitch fis4 :: Pitch eis4 :: Pitch dis4 :: Pitch ceses4 :: Pitch beses4 :: Pitch aeses4 :: Pitch geses4 :: Pitch feses4 :: Pitch eeses4 :: Pitch deses4 :: Pitch cisis4 :: Pitch bisis4 :: Pitch aisis4 :: Pitch gisis4 :: Pitch fisis4 :: Pitch eisis4 :: Pitch disis4 :: Pitch ceseh4 :: Pitch beseh4 :: Pitch aeseh4 :: Pitch geseh4 :: Pitch feseh4 :: Pitch eeseh4 :: Pitch deseh4 :: Pitch ceh4 :: Pitch beh4 :: Pitch aeh4 :: Pitch geh4 :: Pitch feh4 :: Pitch eeh4 :: Pitch deh4 :: Pitch cih4 :: Pitch bih4 :: Pitch aih4 :: Pitch gih4 :: Pitch fih4 :: Pitch eih4 :: Pitch dih4 :: Pitch cisih4 :: Pitch bisih4 :: Pitch aisih4 :: Pitch gisih4 :: Pitch fisih4 :: Pitch eisih4 :: Pitch disih4 :: Pitch c5 :: Pitch b5 :: Pitch a5 :: Pitch g5 :: Pitch f5 :: Pitch e5 :: Pitch d5 :: Pitch ces5 :: Pitch bes5 :: Pitch aes5 :: Pitch ges5 :: Pitch fes5 :: Pitch ees5 :: Pitch des5 :: Pitch cis5 :: Pitch bis5 :: Pitch ais5 :: Pitch gis5 :: Pitch fis5 :: Pitch eis5 :: Pitch dis5 :: Pitch ceses5 :: Pitch beses5 :: Pitch aeses5 :: Pitch geses5 :: Pitch feses5 :: Pitch eeses5 :: Pitch deses5 :: Pitch cisis5 :: Pitch bisis5 :: Pitch aisis5 :: Pitch gisis5 :: Pitch fisis5 :: Pitch eisis5 :: Pitch disis5 :: Pitch ceseh5 :: Pitch beseh5 :: Pitch aeseh5 :: Pitch geseh5 :: Pitch feseh5 :: Pitch eeseh5 :: Pitch deseh5 :: Pitch ceh5 :: Pitch beh5 :: Pitch aeh5 :: Pitch geh5 :: Pitch feh5 :: Pitch eeh5 :: Pitch deh5 :: Pitch cih5 :: Pitch bih5 :: Pitch aih5 :: Pitch gih5 :: Pitch fih5 :: Pitch eih5 :: Pitch dih5 :: Pitch cisih5 :: Pitch bisih5 :: Pitch aisih5 :: Pitch gisih5 :: Pitch fisih5 :: Pitch eisih5 :: Pitch disih5 :: Pitch c6 :: Pitch b6 :: Pitch a6 :: Pitch g6 :: Pitch f6 :: Pitch e6 :: Pitch d6 :: Pitch ces6 :: Pitch bes6 :: Pitch aes6 :: Pitch ges6 :: Pitch fes6 :: Pitch ees6 :: Pitch des6 :: Pitch cis6 :: Pitch bis6 :: Pitch ais6 :: Pitch gis6 :: Pitch fis6 :: Pitch eis6 :: Pitch dis6 :: Pitch ceseh6 :: Pitch beseh6 :: Pitch aeseh6 :: Pitch geseh6 :: Pitch feseh6 :: Pitch eeseh6 :: Pitch deseh6 :: Pitch ceh6 :: Pitch beh6 :: Pitch aeh6 :: Pitch geh6 :: Pitch feh6 :: Pitch eeh6 :: Pitch deh6 :: Pitch cih6 :: Pitch bih6 :: Pitch aih6 :: Pitch gih6 :: Pitch fih6 :: Pitch eih6 :: Pitch dih6 :: Pitch cisih6 :: Pitch bisih6 :: Pitch aisih6 :: Pitch gisih6 :: Pitch fisih6 :: Pitch eisih6 :: Pitch disih6 :: Pitch c7 :: Pitch b7 :: Pitch a7 :: Pitch g7 :: Pitch f7 :: Pitch e7 :: Pitch d7 :: Pitch ces7 :: Pitch bes7 :: Pitch aes7 :: Pitch ges7 :: Pitch fes7 :: Pitch ees7 :: Pitch des7 :: Pitch cis7 :: Pitch bis7 :: Pitch ais7 :: Pitch gis7 :: Pitch fis7 :: Pitch eis7 :: Pitch dis7 :: Pitch c8 :: Pitch d8 :: Pitch cis8 :: Pitch -- | Common music notation clefs. module Music.Theory.Clef -- | Clef enumeration type. data Clef_T Bass :: Clef_T Tenor :: Clef_T Alto :: Clef_T Treble :: Clef_T Percussion :: Clef_T -- | Clef with octave offset. data Clef i Clef :: Clef_T -> i -> Clef i clef_t :: Clef i -> Clef_T clef_octave :: Clef i -> i -- | Give clef range as a Pitch pair indicating the notes below and -- above the staff. -- --
--   map clef_range [Treble,Bass] == [Just (d4,g5),Just (f2,b3)]
--   clef_range Percussion == Nothing
--   
clef_range :: Clef_T -> Maybe (Pitch, Pitch) -- | Suggest a Clef given a Pitch. -- --
--   map clef_suggest [c2,c4] == [Clef Bass (-1),Clef Treble 0]
--   
clef_suggest :: Integral i => Pitch -> Clef i -- | Set clef_octave to 0. clef_zero :: Integral i => Clef i -> Clef i -- | Set clef_octave to be no further than r from 0. clef_restrict :: Integral i => i -> Clef i -> Clef i instance Eq Clef_T instance Ord Clef_T instance Show Clef_T instance Eq i => Eq (Clef i) instance Ord i => Ord (Clef i) instance Show i => Show (Clef i) module Music.Theory.Instrument.Choir -- | Voice types. data Voice Bass :: Voice Tenor :: Voice Alto :: Voice Soprano :: Voice -- | Single character abbreviation for Voice. voice_abbrev :: Voice -> Char -- | Standard Clef for Voice. voice_clef :: Integral i => Voice -> Clef i -- | Table giving ranges for Voices. type Voice_Rng_Tbl = [(Voice, (Pitch, Pitch))] -- | More or less standard choir ranges, inclusive. voice_rng_tbl_std :: Voice_Rng_Tbl -- | More conservative ranges, inclusive. voice_rng_tbl_safe :: Voice_Rng_Tbl -- | Erroring variant. lookup_err :: Eq a => a -> [(a, b)] -> b -- | Lookup voice range table. voice_rng :: Voice_Rng_Tbl -> Voice -> (Pitch, Pitch) -- | Lookup voice_rng_tbl_std. voice_rng_std :: Voice -> (Pitch, Pitch) -- | Lookup voice_rng_tbl_safe. voice_rng_safe :: Voice -> (Pitch, Pitch) -- | Is p >= l and <= r. in_range_inclusive :: Ord a => a -> (a, a) -> Bool -- | Is p in range for v, (std & safe). -- --
--   map (in_voice_rng T.c4) [Bass .. Soprano]
--   
in_voice_rng :: Pitch -> Voice -> (Bool, Bool) -- | Given tbl list Voices that can sing Pitch. possible_voices :: Voice_Rng_Tbl -> Pitch -> [Voice] -- | std variant. possible_voices_std :: Pitch -> [Voice] -- | safe variant. possible_voices_safe :: Pitch -> [Voice] -- | Enumeration of SATB voices. satb :: [Voice] -- | Names of satb. satb_name :: [String] -- | voice_abbrev of satb as Strings. satb_abbrev :: [String] -- | Voice & part number. type Part = (Voice, Int) -- | k part choir, ordered by voice. ch_satb_seq :: Int -> [Part] -- | ch_satb_seq grouped in parts. -- --
--   map (map part_nm) (ch_parts 8)
--   
ch_parts :: Int -> [[Part]] -- | Abreviated name for part. -- --
--   part_nm (Soprano,1) == "S1"
--   
part_nm :: Part -> String -- | k SATB choirs, grouped by choir. -- --
--   k_ch_groups 2
--   
k_ch_groups :: Int -> [[Part]] -- | concat of k_ch_groups. k_ch_groups' :: Int -> [Part] -- | Two k part SATB choirs in score order. -- --
--   map part_nm (concat (dbl_ch_parts 8))
--   
dbl_ch_parts :: Int -> [[Part]] -- | voice_clef for Parts. mk_clef_seq :: [Part] -> [Clef Int] instance Eq Voice instance Ord Voice instance Enum Voice instance Bounded Voice instance Show Voice -- | Common music notation intervals. module Music.Theory.Interval -- | Interval type or degree. data Interval_T Unison :: Interval_T Second :: Interval_T Third :: Interval_T Fourth :: Interval_T Fifth :: Interval_T Sixth :: Interval_T Seventh :: Interval_T -- | Interval quality. data Interval_Q Diminished :: Interval_Q Minor :: Interval_Q Perfect :: Interval_Q Major :: Interval_Q Augmented :: Interval_Q -- | Common music notation interval. An Ordering of LT -- indicates an ascending interval, GT a descending interval, and -- EQ a unison. data Interval Interval :: Interval_T -> Interval_Q -> Ordering -> Octave -> Interval interval_type :: Interval -> Interval_T interval_quality :: Interval -> Interval_Q interval_direction :: Interval -> Ordering interval_octave :: Interval -> Octave -- | Interval type between Note_T values. -- --
--   map (interval_ty C) [E,B] == [Third,Seventh]
--   
interval_ty :: Note_T -> Note_T -> Interval_T -- | Table of interval qualities. For each Interval_T gives directed -- semitone interval counts for each allowable Interval_Q. For -- lookup function see interval_q, for reverse lookup see -- interval_q_reverse. interval_q_tbl :: Integral n => [(Interval_T, [(n, Interval_Q)])] -- | Lookup Interval_Q for given Interval_T and semitone -- count. -- --
--   interval_q Unison 11 == Just Diminished
--   interval_q Third 5 == Just Augmented
--   interval_q Fourth 5 == Just Perfect
--   interval_q Unison 3 == Nothing
--   
interval_q :: Interval_T -> Int -> Maybe Interval_Q -- | Lookup semitone difference of Interval_T with -- Interval_Q. -- --
--   interval_q_reverse Third Minor == Just 3
--   interval_q_reverse Unison Diminished == Just 11
--   
interval_q_reverse :: Interval_T -> Interval_Q -> Maybe Int -- | Semitone difference of Interval. -- --
--   interval_semitones (interval (Pitch C Sharp 4) (Pitch E Sharp 5)) == 16
--   interval_semitones (interval (Pitch C Natural 4) (Pitch D Sharp 3)) == -9
--   
interval_semitones :: Interval -> Int -- | Inclusive set of Note_T within indicated interval. This is not -- equal to enumFromTo which is not circular. -- --
--   note_span E B == [E,F,G,A,B]
--   note_span B D == [B,C,D]
--   enumFromTo B D == []
--   
note_span :: Note_T -> Note_T -> [Note_T] -- | Invert Ordering, ie. GT becomes LT and vice -- versa. -- --
--   map invert_ordering [LT,EQ,GT] == [GT,EQ,LT]
--   
invert_ordering :: Ordering -> Ordering -- | Determine Interval between two Pitches. -- --
--   interval (Pitch C Sharp 4) (Pitch D Flat 4) == Interval Second Diminished EQ 0
--   interval (Pitch C Sharp 4) (Pitch E Sharp 5) == Interval Third Major LT 1
--   
interval :: Pitch -> Pitch -> Interval -- | Apply invert_ordering to interval_direction of -- Interval. -- --
--   invert_interval (Interval Third Major LT 1) == Interval Third Major GT 1
--   
invert_interval :: Interval -> Interval -- | The signed difference in semitones between two Interval_Q -- values when applied to the same Interval_T. Can this be written -- correctly without knowing the Interval_T? -- --
--   quality_difference_m Minor Augmented == Just 2
--   quality_difference_m Augmented Diminished == Just (-3)
--   quality_difference_m Major Perfect == Nothing
--   
quality_difference_m :: Interval_Q -> Interval_Q -> Maybe Int -- | Erroring variant of quality_difference_m. quality_difference :: Interval_Q -> Interval_Q -> Int -- | Transpose a Pitch by an Interval. -- --
--   transpose (Interval Third Diminished LT 0) (Pitch C Sharp 4) == Pitch E Flat 4
--   
pitch_transpose :: Interval -> Pitch -> Pitch -- | Make leftwards (perfect fourth) and and rightwards (perfect fifth) -- circles from Pitch. -- --
--   let c = circle_of_fifths (Pitch F Sharp 4)
--   in map pitch_to_pc (snd c) == [6,1,8,3,10,5,12,7,2,9,4,11]
--   
circle_of_fifths :: Pitch -> ([Pitch], [Pitch]) -- | Parse a positive integer into interval type and octave displacement. -- --
--   mapMaybe parse_interval_type (map show [1 .. 15])
--   
parse_interval_type :: String -> Maybe (Interval_T, Octave) -- | Parse interval quality notation. -- --
--   mapMaybe parse_interval_quality "dmPMA" == [minBound .. maxBound]
--   
parse_interval_quality :: Char -> Maybe Interval_Q -- | Degree of interval type and octave displacement. Inverse of -- parse_interval_type. -- --
--   map interval_type_degree [(Third,0),(Second,1),(Unison,2)] == [3,9,15]
--   
interval_type_degree :: (Interval_T, Octave) -> Int -- | Inverse of 'parse_interval_quality. interval_quality_pp :: Interval_Q -> Char -- | Parse standard common music interval notation. -- --
--   let i = mapMaybe parse_interval (words "P1 d2 m2 M2 A3 P8 +M9 -M2")
--   in unwords (map interval_pp i) == "P1 d2 m2 M2 A3 P8 M9 -M2"
--   
-- --
--   mapMaybe (fmap interval_octave . parse_interval) (words "d1 d8 d15") == [-1,0,1]
--   
parse_interval :: String -> Maybe Interval -- | Pretty printer for intervals, inverse of parse_interval. interval_pp :: Interval -> String -- | Standard names for the intervals within the octave, divided into -- perfect, major and minor at the left, and diminished and augmented at -- the right. -- --
--   let {bimap f (p,q) = (f p,f q)
--       ;f = mapMaybe (fmap interval_semitones . parse_interval)}
--   in bimap f std_interval_names
--   
std_interval_names :: ([String], [String]) instance Eq Interval_T instance Enum Interval_T instance Bounded Interval_T instance Ord Interval_T instance Show Interval_T instance Eq Interval_Q instance Enum Interval_Q instance Bounded Interval_Q instance Ord Interval_Q instance Show Interval_Q instance Eq Interval instance Show Interval -- | Constants names for ascending Interval values. module Music.Theory.Interval.Name perfect_fourth :: Interval major_seventh :: Interval perfect_fifth :: Interval -- | Spelling rules for Interval values. module Music.Theory.Interval.Spelling -- | Simplest spelling for semitone intervals. This is ambiguous for -- 6 which could be either aug.4 or dim.5. -- --
--   i_to_interval 6 == Interval Fourth Augmented LT 0
--   map i_to_interval [0..11]
--   
i_to_interval :: Int -> Interval -- | Perform some interval simplifications. For non-tonal music some -- spellings are poor, ie. (f,g#). -- --
--   interval_simplify (Interval Second Augmented LT 0) == Interval Third Minor LT 0
--   interval_simplify (Interval Seventh Augmented GT 0) == Interval Unison Perfect GT 1
--   
interval_simplify :: Interval -> Interval -- | Common music keys. module Music.Theory.Key -- | Enumeration of common music notation modes. data Mode_T Minor_Mode :: Mode_T Major_Mode :: Mode_T -- | A common music notation key is a Note_T, Alteration_T, -- Mode_T triple. type Key = (Note_T, Alteration_T, Mode_T) -- | Distance along circle of fifths path of indicated Key. A -- positive number indicates the number of sharps, a negative number the -- number of flats. -- --
--   key_fifths (A,Natural,Minor_Mode) == 0
--   key_fifths (A,Natural,Major_Mode) == 3
--   key_fifths (C,Natural,Minor_Mode) == -3
--   
key_fifths :: Key -> Int instance Eq Mode_T instance Ord Mode_T instance Show Mode_T -- | Spelling for chromatic clusters. module Music.Theory.Pitch.Spelling.Cluster -- | Spelling table for chromatic clusters. -- --
--   let f (p,q) = p == sort (map (snd . pitch_to_octpc) q)
--   in all f spell_cluster_c4_table == True
--   
spell_cluster_c4_table :: [([PitchClass], [Pitch])] -- | Spelling for chromatic clusters. Sequence must be ascending. Pitch -- class 0 maps to c4, if there is no 0 then all -- notes are in octave 4. -- --
--   let f = fmap (map pitch_pp) . spell_cluster_c4
--   in map f [[11,0],[11]] == [Just ["B3","C4"],Just ["B4"]]
--   
-- --
--   fmap (map pitch_pp) (spell_cluster_c4 [10,11]) == Just ["A♯4","B4"]
--   
spell_cluster_c4 :: [PitchClass] -> Maybe [Pitch] -- | Variant of spell_cluster_c4 that runs pitch_edit_octave. -- An octave of 4 is the identitiy, 3 an octave below, -- 5 an octave above. -- --
--   fmap (map pitch_pp) (spell_cluster_c 3 [11,0]) == Just ["B2","C3"]
--   fmap (map pitch_pp) (spell_cluster_c 3 [10,11]) == Just ["A♯3","B3"]
--   
spell_cluster_c :: Octave -> [PitchClass] -> Maybe [Pitch] -- | Variant of spell_cluster_c4 that runs pitch_edit_octave -- so that the left-most note is in the octave given by f. -- --
--   import Data.Maybe
--   
-- --
--   let {f n = if n >= 11 then 3 else 4
--       ;g = map pitch_pp .fromJust . spell_cluster_f f
--       ;r = [["B3","C4"],["B3"],["C4"],["A♯4","B4"]]}
--   in map g [[11,0],[11],[0],[10,11]] == r
--   
spell_cluster_f :: (PitchClass -> Octave) -> [PitchClass] -> Maybe [Pitch] -- | Variant of spell_cluster_c4 that runs pitch_edit_octave -- so that the left-most note is in octave o. -- --
--   fmap (map pitch_pp) (spell_cluster_left 3 [11,0]) == Just ["B3","C4"]
--   fmap (map pitch_pp) (spell_cluster_left 3 [10,11]) == Just ["A♯3","B3"]
--   
spell_cluster_left :: Octave -> [PitchClass] -> Maybe [Pitch] -- | Permutation functions. module Music.Theory.Permutations -- | Factorial function. -- --
--   (factorial 13,maxBound::Int)
--   
factorial :: (Ord a, Num a) => a -> a -- | Number of k element permutations of a set of n elements. -- --
--   (nk_permutations 4 3,nk_permutations 13 3) == (24,1716)
--   
nk_permutations :: Integral a => a -> a -> a -- | Number of nk permutations where n == k. -- --
--   map n_permutations [1..8] == [1,2,6,24,120,720,5040,40320]
--   n_permutations 16 `div` 1000000 == 20922789
--   
n_permutations :: Integral a => a -> a -- | Generate the permutation from p to q, ie. the -- permutation that, when applied to p, gives q. -- --
--   apply_permutation (permutation [0,1,3] [1,0,3]) [0,1,3] == [1,0,3]
--   
permutation :: Eq a => [a] -> [a] -> Permute -- | Apply permutation f to p. -- --
--   let p = permutation [1..4] [4,3,2,1]
--   in apply_permutation p [1..4] == [4,3,2,1]
--   
apply_permutation :: Eq a => Permute -> [a] -> [a] -- | Composition of apply_permutation and from_cycles. -- --
--   apply_permutation_c [[0,3],[1,2]] [1..4] == [4,3,2,1]
--   apply_permutation_c [[0,2],[1],[3,4]] [1..5] == [3,2,1,5,4]
--   apply_permutation_c [[0,1,4],[2,3]] [1..5] == [2,5,4,3,1]
--   apply_permutation_c [[0,1,3],[2,4]] [1..5] == [2,4,5,1,3]
--   
apply_permutation_c :: Eq a => [[Int]] -> [a] -> [a] -- | True if the inverse of p is p. -- --
--   non_invertible (permutation [0,1,3] [1,0,3]) == True
--   
-- --
--   let p = permutation [1..4] [4,3,2,1]
--   in non_invertible p == True && P.cycles p == [[0,3],[1,2]]
--   
non_invertible :: Permute -> Bool -- | Generate a permutation from the cycles c. -- --
--   apply_permutation (from_cycles [[0,1,2,3]]) [1..4] == [2,3,4,1]
--   
from_cycles :: [[Int]] -> Permute -- | Generate all permutations of size n. -- --
--   map one_line (permutations_n 3) == [[1,2,3],[1,3,2]
--                                      ,[2,1,3],[2,3,1]
--                                      ,[3,1,2],[3,2,1]]
--   
permutations_n :: Int -> [Permute] -- | Composition of q then p. -- --
--   let {p = from_cycles [[0,2],[1],[3,4]]
--       ;q = from_cycles [[0,1,4],[2,3]]
--       ;r = p `compose` q}
--   in apply_permutation r [1,2,3,4,5] == [2,4,5,1,3]
--   
compose :: Permute -> Permute -> Permute -- | Two line notation of p. -- --
--   two_line (permutation [0,1,3] [1,0,3]) == ([1,2,3],[2,1,3])
--   
two_line :: Permute -> ([Int], [Int]) -- | One line notation of p. -- --
--   one_line (permutation [0,1,3] [1,0,3]) == [2,1,3]
--   
-- --
--   map one_line (permutations_n 3) == [[1,2,3],[1,3,2]
--                                      ,[2,1,3],[2,3,1]
--                                      ,[3,1,2],[3,2,1]]
--   
one_line :: Permute -> [Int] -- | Variant of one_line that produces a compact string. -- --
--   one_line_compact (permutation [0,1,3] [1,0,3]) == "213"
--   
-- --
--   let p = permutations_n 3
--   in unwords (map one_line_compact p) == "123 132 213 231 312 321"
--   
one_line_compact :: Permute -> String -- | Multiplication table of symmetric group n. -- --
--   unlines (map (unwords . map one_line_compact) (multiplication_table 3))
--   
-- --
--   ==> 123 132 213 231 312 321
--       132 123 312 321 213 231
--       213 231 123 132 321 312
--       231 213 321 312 123 132
--       312 321 132 123 231 213
--       321 312 231 213 132 123
--   
multiplication_table :: Int -> [[Permute]] -- | Combination functions. module Music.Theory.Combinations -- | Number of k element combinations of a set of n elements. -- --
--   (nk_combinations 6 3,nk_combinations 13 3) == (20,286)
--   
nk_combinations :: Integral a => a -> a -> a -- | k element subsets of s. -- --
--   combinations 3 [1..4] == [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
--   length (combinations 3 [1..5]) == nk_combinations 5 3
--   
combinations :: Integral t => t -> [a] -> [[a]] -- | List permutation functions. module Music.Theory.Permutations.List -- | Generate all permutations. -- --
--   permutations [0,3] == [[0,3],[3,0]]
--   length (permutations [1..5]) == P.n_permutations 5
--   
permutations :: Eq a => [a] -> [[a]] -- | Generate all distinct permutations of a multi-set. -- --
--   multiset_permutations [0,1,1] == [[0,1,1],[1,1,0],[1,0,1]]
--   
multiset_permutations :: Ord a => [a] -> [[a]] -- | Polansky, Larry and Bassein, Richard "Possible and Impossible Melody: -- Some Formal Aspects of Contour" Journal of Music Theory 36/2, -- 1992 (pp.259-284) (http://www.jstor.org/pss/843933) module Music.Theory.Contour.Polansky_1992 -- | Replace the ith value at ns with x. -- --
--   replace "test" 2 'n' == "tent"
--   
replace :: Integral i => [a] -> i -> a -> [a] -- | Are all elements equal. -- --
--   all_equal "aaa" == True
--   
all_equal :: Eq a => [a] -> Bool -- | Compare adjacent elements (p.262) left to right. -- --
--   compare_adjacent [0,1,3,2] == [LT,LT,GT]
--   
compare_adjacent :: Ord a => [a] -> [Ordering] -- | Construct set of n - 1 adjacent indices, left -- right order. -- --
--   adjacent_indices 5 == [(0,1),(1,2),(2,3),(3,4)]
--   
adjacent_indices :: Integral i => i -> [(i, i)] -- | All (i,j) indices, in half matrix order. -- --
--   all_indices 4 == [(0,1),(0,2),(0,3),(1,2),(1,3),(2,3)]
--   
all_indices :: Integral i => i -> [(i, i)] -- | Generic variant of fromEnum (p.263). genericFromEnum :: (Integral i, Enum e) => e -> i -- | Generic variant of toEnum (p.263). genericToEnum :: (Integral i, Enum e) => i -> e -- | Specialised genericFromEnum. ord_to_int :: Integral a => Ordering -> a -- | Specialised genericToEnum. int_to_ord :: Integral a => a -> Ordering -- | Invert Ordering. -- --
--   map ord_invert [LT,EQ,GT] == [GT,EQ,LT]
--   
ord_invert :: Ordering -> Ordering -- | A list notation for matrices. type Matrix a = [[a]] -- | Apply f to construct Matrix from sequence. -- --
--   matrix_f (,) [1..3] == [[(1,1),(1,2),(1,3)]
--                          ,[(2,1),(2,2),(2,3)]
--                          ,[(3,1),(3,2),(3,3)]]
--   
matrix_f :: (a -> a -> b) -> [a] -> Matrix b -- | Construct matrix_f with compare (p.263). -- --
--   contour_matrix [1..3] == [[EQ,LT,LT],[GT,EQ,LT],[GT,GT,EQ]]
--   
contour_matrix :: Ord a => [a] -> Matrix Ordering -- | Half matrix notation for contour. data Contour_Half_Matrix Contour_Half_Matrix :: Int -> Matrix Ordering -> Contour_Half_Matrix contour_half_matrix_n :: Contour_Half_Matrix -> Int contour_half_matrix_m :: Contour_Half_Matrix -> Matrix Ordering -- | Half Matrix of contour given comparison function f. -- --
--   half_matrix_f (flip (-)) [2,10,6,7] == [[8,4,5],[-4,-3],[1]]
--   half_matrix_f (flip (-)) [5,0,3,2] == [[-5,-2,-3],[3,2],[-1]]
--   half_matrix_f compare [5,0,3,2] == [[GT,GT,GT],[LT,LT],[GT]]
--   
half_matrix_f :: (a -> a -> b) -> [a] -> Matrix b -- | Construct Contour_Half_Matrix (p.264) contour_half_matrix :: Ord a => [a] -> Contour_Half_Matrix -- | Show function for Contour_Half_Matrix. contour_half_matrix_str :: Contour_Half_Matrix -> String -- | Description notation of contour. data Contour_Description Contour_Description :: Int -> Map (Int, Int) Ordering -> Contour_Description contour_description_n :: Contour_Description -> Int contour_description_m :: Contour_Description -> Map (Int, Int) Ordering -- | Construct Contour_Description of contour (p.264). -- --
--   let c = [[3,2,4,1],[3,2,1,4]]
--   in map (show.contour_description) c == ["202 02 2","220 20 0"]
--   
contour_description :: Ord a => [a] -> Contour_Description -- | Show function for Contour_Description (p.264). contour_description_str :: Contour_Description -> String -- | Convert from Contour_Half_Matrix notation to -- Contour_Description. half_matrix_to_description :: Contour_Half_Matrix -> Contour_Description -- | Ordering from ith to jth element of sequence described -- at d. -- --
--   contour_description_ix (contour_description "abdc") (0,3) == LT
--   
contour_description_ix :: Contour_Description -> (Int, Int) -> Ordering -- | True if contour is all descending, equal or ascending. -- --
--   let c = ["abc","bbb","cba"]
--   in map (uniform.contour_description) c == [True,True,True]
--   
uniform :: Contour_Description -> Bool -- | True if contour does not containt any EQ elements. -- --
--   let c = ["abc","bbb","cba"]
--   map (no_equalities.contour_description) c == [True,False,True]
--   
no_equalities :: Contour_Description -> Bool -- | Set of all contour descriptions. -- --
--   map (length.all_contours) [3,4,5] == [27,729,59049]
--   
all_contours :: Int -> [Contour_Description] -- | A sequence of orderings (i,j) and (j,k) may imply -- ordering for (i,k). -- --
--   map implication [(LT,EQ),(EQ,EQ),(EQ,GT)] == [Just LT,Just EQ,Just GT]
--   
implication :: (Ordering, Ordering) -> Maybe Ordering -- | List of all violations at a Contour_Description (p.266). violations :: Contour_Description -> [(Int, Int, Int, Ordering)] -- | Is the number of violations zero. is_possible :: Contour_Description -> Bool -- | All possible contour descriptions -- --
--   map (length.possible_contours) [3,4,5] == [13,75,541]
--   
possible_contours :: Int -> [Contour_Description] -- | All impossible contour descriptions -- --
--   map (length.impossible_contours) [3,4,5] == [14,654,58508]
--   
impossible_contours :: Int -> [Contour_Description] -- | Calculate number of contours of indicated degree (p.263). -- --
--   map contour_description_lm [2..7] == [1,3,6,10,15,21]
--   
-- --
--   let r = [3,27,729,59049,14348907]
--   in map (\n -> 3 ^ n) (map contour_description_lm [2..6]) == r
--   
contour_description_lm :: Integral a => a -> a -- | Truncate a Contour_Description to have at most n -- elements. -- --
--   let c = contour_description [3,2,4,1]
--   in contour_truncate c 3 == contour_description [3,2,4]
--   
contour_truncate :: Contour_Description -> Int -> Contour_Description -- | Is Contour_Description p a prefix of q. -- --
--   let {c = contour_description [3,2,4,1]
--       ;d = contour_description [3,2,4]}
--   in d `contour_is_prefix_of` c == True
--   
contour_is_prefix_of :: Contour_Description -> Contour_Description -> Bool -- | Are Contour_Descriptions p and q equal at column -- n. -- --
--   let {c = contour_description [3,2,4,1,5]
--       ;d = contour_description [3,2,4,1]}
--   in map (contour_eq_at c d) [0..4] == [True,True,True,True,False]
--   
contour_eq_at :: Contour_Description -> Contour_Description -> Int -> Bool -- | Derive an Integral contour that would be described by -- Contour_Description. Diverges for impossible contours. -- --
--   draw_contour (contour_description "abdc") == [0,1,3,2]
--   
draw_contour :: Integral i => Contour_Description -> [i] -- | Invert Contour_Description. -- --
--   let c = contour_description "abdc"
--   in draw_contour (contour_description_invert c) == [3,2,0,1]
--   
contour_description_invert :: Contour_Description -> Contour_Description -- | Function to perhaps generate an element and a new state from an -- initial state. This is the function provided to unfoldr. type Build_f st e = st -> Maybe (e, st) -- | Function to test is a partial sequence conforms to the target -- sequence. type Conforms_f e = Int -> [e] -> Bool -- | Transform a Build_f to produce at most n elements. -- --
--   let f i = Just (i,succ i)
--   in unfoldr (build_f_n f) (5,'a') == "abcde"
--   
build_f_n :: Build_f st e -> Build_f (Int, st) e -- | Attempt to construct a sequence of n elements given a -- Build_f to generate possible elements, a Conforms_f that -- the result sequence must conform to at each step, an Int to -- specify the maximum number of elements to generate when searching for -- a solution, and an initial state. -- --
--   let {b_f i = Just (i,i+1)
--       ;c_f i x = odd (sum x `div` i)}
--   in build_sequence 6 b_f c_f 20 0 == (Just [1,2,6,11,15,19],20)
--   
build_sequence :: Int -> Build_f st e -> Conforms_f e -> Int -> st -> (Maybe [e], st) -- | Attempt to construct a sequence that has a specified contour. The -- arguments are a Build_f to generate possible elements, a -- Contour_Description that the result sequence must conform to, -- an Int to specify the maximum number of elements to generate -- when searching for a solution, and an initial state. -- --
--   import System.Random
--   
-- --
--   let {f = Just . randomR ('a','z')
--       ;c = contour_description "atdez"
--       ;st = mkStdGen 2347}
--   in fst (build_contour f c 1024 st) == Just "nvruy"
--   
build_contour :: Ord e => Build_f st e -> Contour_Description -> Int -> st -> (Maybe [e], st) -- | A variant on build_contour that retries a specified number of -- times using the final state of the failed attempt as the state for the -- next try. -- --
--   let {f = Just . randomR ('a','z')
--       ;c = contour_description "atdezjh"
--       ;st = mkStdGen 2347}
--   in fst (build_contour_retry f c 64 8 st) == Just "nystzvu"
--   
build_contour_retry :: Ord e => Build_f st e -> Contour_Description -> Int -> Int -> st -> (Maybe [e], st) -- | A variant on build_contour_retry that returns the set of all -- sequences constructed. -- --
--   let {f = Just . randomR ('a','z')
--       ;c = contour_description "atdezjh"
--       ;st = mkStdGen 2347}
--   in length (build_contour_set f c 64 64 st) == 60
--   
build_contour_set :: Ord e => Build_f st e -> Contour_Description -> Int -> Int -> st -> [[e]] -- | Variant of build_contour_set that halts when an generated -- sequence is a duplicate of an already generated sequence. -- --
--   let {f = randomR ('a','f')
--       ;c = contour_description "cafe"
--       ;st = mkStdGen 2346836
--       ;r = build_contour_set_nodup f c 64 64 st}
--   in filter ("c" `isPrefixOf`) r == ["cafe","cbed","caed"]
--   
build_contour_set_nodup :: Ord e => Build_f st e -> Contour_Description -> Int -> Int -> st -> [[e]] -- | Example from p.262 (quarter-note durations) -- --
--   ex_1 == [2,3/2,1/2,1,2]
--   compare_adjacent ex_1 == [GT,GT,LT,LT]
--   show (contour_half_matrix ex_1) == "2221 220 00 0"
--   draw_contour (contour_description ex_1) == [3,2,0,1,3]
--   
-- --
--   let d = contour_description_invert (contour_description ex_1)
--   in (show d,is_possible d) == ("0001 002 22 2",True)
--   
ex_1 :: [Rational] -- | Example on p.265 (pitch) -- --
--   ex_2 == [0,5,3]
--   show (contour_description ex_2) == "00 2"
--   
ex_2 :: [Integer] -- | Example on p.265 (pitch) -- --
--   ex_3 == [12,7,6,7,8,7]
--   show (contour_description ex_3) == "22222 2101 000 01 2"
--   contour_description_ix (contour_description ex_3) (0,5) == GT
--   is_possible (contour_description ex_3) == True
--   
ex_3 :: [Integer] -- | Example on p.266 (impossible) -- --
--   show ex_4 == "2221 220 00 1"
--   is_possible ex_4 == False
--   violations ex_4 == [(0,3,4,GT),(1,3,4,GT)]
--   
ex_4 :: Contour_Description instance Eq Contour_Half_Matrix instance Eq Contour_Description instance Show Contour_Description instance Show Contour_Half_Matrix -- | Symetric Group S4 as related to the composition "Nomos Alpha" by -- Iannis Xenakis. In particular in relation to the discussion in -- "Towards a Philosophy of Music", Formalized Music pp. 219 -- -- 221 module Music.Theory.Xenakis.S4 -- | Labels for elements of the symmetric group P4. data Label A :: Label B :: Label C :: Label D :: Label D2 :: Label E :: Label E2 :: Label G :: Label G2 :: Label I :: Label L :: Label L2 :: Label Q1 :: Label Q2 :: Label Q3 :: Label Q4 :: Label Q5 :: Label Q6 :: Label Q7 :: Label Q8 :: Label Q9 :: Label Q10 :: Label Q11 :: Label Q12 :: Label -- | Initial half of Seq (ie. #4). The complete Seq is formed -- by appending the complement of the Half_Seq. type Half_Seq = [Int] -- | Complete sequence (ie. #8). type Seq = [Int] -- | Complement of a Half_Seq. -- --
--   map complement [[4,1,3,2],[6,7,8,5]] == [[8,5,7,6],[2,3,4,1]]
--   
complement :: Half_Seq -> Half_Seq -- | Form Seq from Half_Seq. -- --
--   full_seq [3,2,4,1] == [3,2,4,1,7,6,8,5]
--   label_of (full_seq [3,2,4,1]) == G2
--   label_of (full_seq [1,4,2,3]) == L
--   
full_seq :: Half_Seq -> Seq -- | Lower Half_Seq, ie. complement or id. -- --
--   map lower [[4,1,3,2],[6,7,8,5]] == [[4,1,3,2],[2,3,4,1]]
--   
lower :: Half_Seq -> Half_Seq -- | Application of Label p on q. -- --
--   l_on Q1 I == Q1
--   l_on D A == G
--   [l_on L L,l_on E D,l_on D E] == [L2,C,B]
--   
l_on :: Label -> Label -> Label -- | Seq of Label, inverse of label_of. -- --
--   seq_of Q1 == [8,7,5,6,4,3,1,2]
--   
seq_of :: Label -> Seq -- | Half_Seq of Label, ie. half_seq . -- seq_of. -- --
--   half_seq_of Q1 == [8,7,5,6]
--   
half_seq_of :: Label -> Seq -- | Half_Seq of Seq, ie. take 4. -- --
--   complement (half_seq (seq_of Q7)) == [3,4,2,1]
--   
half_seq :: Seq -> Half_Seq -- | Reverse table lookup. -- --
--   reverse_lookup 'b' (zip [1..] ['a'..]) == Just 2
--   lookup 2 (zip [1..] ['a'..]) == Just 'b'
--   
reverse_lookup :: Eq a => a -> [(b, a)] -> Maybe b -- | Label of Seq, inverse of seq_of. -- --
--   label_of [8,7,5,6,4,3,1,2] == Q1
--   label_of (seq_of Q4) == Q4
--   
label_of :: Seq -> Label -- | True if two Half_Seqs are complementary, ie. form a -- Seq. -- --
--   complementary [4,2,1,3] [8,6,5,7] == True
--   
complementary :: Half_Seq -> Half_Seq -> Bool -- | Relation between to Half_Seq values as a -- (complementary,permutation) pair. type Rel = (Bool, Permute) -- | Determine Rel of Half_Seqs. -- --
--   relate [1,4,2,3] [1,3,4,2] == (False,P.listPermute 4 [0,3,1,2])
--   relate [1,4,2,3] [8,5,6,7] == (True,P.listPermute 4 [1,0,2,3])
--   
relate :: Half_Seq -> Half_Seq -> Rel -- | Rel from Label p to q. -- --
--   relate_l L L2 == (False,P.listPermute 4 [0,3,1,2])
--   
relate_l :: Label -> Label -> Rel -- | relate adjacent Half_Seq, see also relations_l. relations :: [Half_Seq] -> [Rel] -- | relate adjacent Labels. -- --
--   relations_l [L2,L,A] == [(False,P.listPermute 4 [0,2,3,1])
--                           ,(False,P.listPermute 4 [2,0,1,3])]
--   
relations_l :: [Label] -> [Rel] -- | Apply Rel to Half_Seq. -- --
--   apply_relation (False,P.listPermute 4 [0,3,1,2]) [1,4,2,3] == [1,3,4,2]
--   
apply_relation :: Rel -> Half_Seq -> Half_Seq -- | Apply sequence of Rel to initial Half_Seq. apply_relations :: [Rel] -> Half_Seq -> [Half_Seq] -- | Variant of apply_relations. -- --
--   apply_relations_l (relations_l [L2,L,A,Q1]) L2 == [L2,L,A,Q1]
--   
apply_relations_l :: [Rel] -> Label -> [Label] -- | Enumeration of set of faces of a cube. data Face F_Back :: Face F_Front :: Face F_Right :: Face F_Left :: Face F_Bottom :: Face F_Top :: Face -- | Table indicating set of faces of cubes as drawn in Fig. VIII-6 -- (p.220). -- --
--   lookup [1,4,6,7] faces == Just F_Left
--   reverse_lookup F_Right faces == Just [2,3,5,8]
--   
faces :: [([Int], Face)] -- | Fig. VIII-6. Hexahedral (Octahedral) Group (p. 220) -- --
--   length viii_6_l == 24
--   take 7 viii_6_l == [L2,L,A,Q1,Q7,Q3,Q9]
--   
viii_6_l :: [Label] -- | Fig. VIII-7 (p.221) -- --
--   map (take 4) (take 4 viii_7) == [[I,A,B,C]
--                                   ,[A,I,C,B]
--                                   ,[B,C,I,A]
--                                   ,[C,B,A,I]]
--   
viii_7 :: [[Label]] -- | Fig. VIII-6/b Labels (p.221) -- --
--   length viii_6b_l == length viii_6_l
--   take 8 viii_6b_l == [I,A,B,C,D2,D,E2,E]
--   
viii_6b_l :: [Label] -- | Fig. VIII-6/b Half_Seq. -- --
--   viii_6b_p' == map half_seq_of viii_6b_l
--   nub (map (length . nub) viii_6b_p') == [4]
--   
viii_6b_p' :: [Half_Seq] -- | Variant of viii_6b with Half_Seq. viii_6b' :: [(Label, Half_Seq)] -- | Fig. VIII-6/b. -- --
--   map (viii_6b !!) [0,8,16] == [(I,[1,2,3,4,5,6,7,8])
--                                ,(G2,[3,2,4,1,7,6,8,5])
--                                ,(Q8,[6,8,5,7,2,4,1,3])]
--   
viii_6b :: [(Label, Seq)] -- | The sequence of Rel to give viii_6_l from L2. -- --
--   apply_relations_l viii_6_relations L2 == viii_6_l
--   length (nub viii_6_relations) == 14
--   
viii_6_relations :: [Rel] -- | The sequence of Rel to give viii_6b_l from I. -- --
--   apply_relations_l viii_6b_relations I == viii_6b_l
--   length (nub viii_6b_relations) == 10
--   
viii_6b_relations :: [Rel] instance Eq Label instance Ord Label instance Enum Label instance Bounded Label instance Show Label instance Eq Face instance Enum Face instance Bounded Face instance Ord Face instance Show Face -- | Functions to generate a click track from a metric structure. module Music.Theory.Duration.CT -- | 1-indexed. type Measure = Int -- | 1-indexed. type Pulse = Int -- | Transform measures given as RQ divisions to absolute RQ -- locations. mdv abbreviates measure divisions. -- --
--   mdv_to_mrq [[1,2,1],[3,2,1]] == [[0,1,3],[4,7,9]]
--   
mdv_to_mrq :: [[RQ]] -> [[RQ]] -- | Lookup function for (Measure,Pulse) indexed structure. mp_lookup_err :: [[a]] -> (Measure, Pulse) -> a -- | Comparison for (Measure,Pulse) indices. mp_compare :: (Measure, Pulse) -> (Measure, Pulse) -> Ordering -- | Latch measures (ie. make measures contiguous, hold previous value). -- --
--   unzip (ct_ext 10 'a' [(3,'b'),(8,'c')]) == ([1..10],"aabbbbbccc")
--   
ct_ext :: Int -> a -> [(Measure, a)] -> [(Measure, a)] -- | Variant that requires a value at measure one (first measure). ct_ext1 :: Int -> [(Measure, a)] -> [(Measure, a)] -- | rts_divisions of ct_ext1. ct_dv_seq :: Int -> Tseq Measure Rational_Time_Signature -> [(Measure, [[RQ]])] -- | ct_dv_seq without measures numbers. ct_mdv_seq :: Int -> Tseq Measure Rational_Time_Signature -> [[RQ]] -- | mdv_to_mrq of ct_mdv_seq. ct_rq :: Int -> Tseq Measure Rational_Time_Signature -> [[RQ]] ct_mp_lookup :: [[RQ]] -> (Measure, Pulse) -> RQ ct_m_to_rq :: [[RQ]] -> [(Measure, t)] -> [(RQ, t)] -- | Latch rehearsal mark sequence, only indicating marks. Initial mark is -- .. -- --
--   ct_mark_seq 2 [] == [(1,Just '.'),(2,Nothing)]
--   
-- --
--   let r = [(1,Just '.'),(3,Just 'A'),(8,Just 'B')]
--   in filter (isJust . snd) (ct_mark_seq 10 [(3,'A'),(8,'B')]) == r
--   
ct_mark_seq :: Int -> Tseq Measure Char -> Tseq Measure (Maybe Char) -- | Indicate measures prior to marks. -- --
--   ct_pre_mark [] == []
--   ct_pre_mark [(1,'A')] == []
--   ct_pre_mark [(3,'A'),(8,'B')] == [(2,Just ()),(7,Just ())]
--   
ct_pre_mark :: [(Measure, a)] -> [(Measure, Maybe ())] -- | Contiguous pre-mark sequence. -- --
--   ct_pre_mark_seq 1 [(1,'A')] == [(1,Nothing)]
--   ct_pre_mark_seq 10 [(3,'A'),(8,'B')]
--   
ct_pre_mark_seq :: Measure -> Tseq Measure Char -> Tseq Measure (Maybe ()) ct_tempo_lseq_rq :: [[RQ]] -> Lseq (Measure, Pulse) RQ -> Lseq RQ RQ -- | Interpolating lookup of tempo sequence (lseq_lookup_err). ct_tempo_at :: Lseq RQ RQ -> RQ -> Rational -- | Types of nodes. data CT_Node -- | The start of a measure with a rehearsal mark. CT_Mark :: RQ -> CT_Node -- | The start of a regular measure. CT_Start :: RQ -> CT_Node -- | A regular pulse. CT_Normal :: RQ -> CT_Node -- | The start of a pulse group within a measure. CT_Edge :: RQ -> CT_Node -- | A regular pulse in a measure prior to a rehearsal mark. CT_Pre :: RQ -> CT_Node -- | The end of the track. CT_End :: CT_Node -- | Lead-in of (pulse,tempo,count). ct_leadin :: (RQ, Double, Int) -> Dseq Double CT_Node -- | Prepend initial element to start of list. -- --
--   delay1 "abc" == "aabc"
--   
delay1 :: [a] -> [a] ct_measure :: Lseq RQ RQ -> ([RQ], Maybe Char, Maybe (), [[RQ]]) -> [(Rational, CT_Node)] -- | Click track definition. data CT CT :: Int -> [(Measure, Rational_Time_Signature)] -> [(Measure, Char)] -> Lseq (Measure, Pulse) RQ -> (RQ, Int) -> CT ct_len :: CT -> Int ct_ts :: CT -> [(Measure, Rational_Time_Signature)] ct_mark :: CT -> [(Measure, Char)] ct_tempo :: CT -> Lseq (Measure, Pulse) RQ ct_count :: CT -> (RQ, Int) -- | Initial tempo, if given. ct_tempo0 :: CT -> Maybe RQ -- | Erroring variant. ct_tempo0_err :: CT -> RQ ct_measures :: CT -> [Dseq Rational CT_Node] ct_dseq' :: CT -> Dseq Rational CT_Node ct_dseq :: CT -> Dseq Double CT_Node ct_rq_measure :: [[RQ]] -> RQ -> Maybe Measure ct_rq_mp :: [[RQ]] -> RQ -> Maybe (Measure, Pulse) ct_rq_mp_err :: [[RQ]] -> RQ -> (Measure, Pulse) ct_mp_to_rq :: [[RQ]] -> [((Measure, Pulse), t)] -> [(RQ, t)] instance Eq CT_Node instance Show CT_Node instance Show CT -- | RQ values with tie right qualifier. module Music.Theory.Duration.RQ.Tied -- | Boolean. type Tied_Right = Bool -- | RQ with tie right. type RQ_T = (RQ, Tied_Right) -- | Construct RQ_T. rqt :: Tied_Right -> RQ -> RQ_T -- | RQ field of RQ_T. rqt_rq :: RQ_T -> RQ -- | Tied field of RQ_T. rqt_tied :: RQ_T -> Tied_Right -- | Is RQ_T tied right. is_tied_right :: RQ_T -> Bool -- | RQ_T variant of rq_un_tuplet. -- --
--   rqt_un_tuplet (3,2) (1,T) == (3/2,T)
--   
-- --
--   let f = rqt_un_tuplet (7,4)
--   in map f [(2/7,F),(4/7,T),(1/7,F)] == [(1/2,F),(1,T),(1/4,F)]
--   
rqt_un_tuplet :: (Integer, Integer) -> RQ_T -> RQ_T -- | Transform RQ to untied RQ_T. -- --
--   rq_rqt 3 == (3,F)
--   
rq_rqt :: RQ -> RQ_T -- | Tie last element only of list of RQ. -- --
--   rq_tie_last [1,2,3] == [(1,F),(2,F),(3,T)]
--   
rq_tie_last :: [RQ] -> [RQ_T] -- | Transform a list of RQ_T to a list of Duration_A. The -- flag indicates if the initial value is tied left. -- --
--   rqt_to_duration_a False [(1,T),(1/4,T),(3/4,F)]
--   
rqt_to_duration_a :: Bool -> [RQ_T] -> [Duration_A] -- | RQ_T variant of rq_can_notate. rqt_can_notate :: [RQ_T] -> Bool -- | RQ_T variant of rq_to_cmn. -- --
--   rqt_to_cmn (5,T) == Just ((4,T),(1,T))
--   rqt_to_cmn (5/4,T) == Just ((1,T),(1/4,T))
--   rqt_to_cmn (5/7,F) == Just ((4/7,T),(1/7,F))
--   
rqt_to_cmn :: RQ_T -> Maybe (RQ_T, RQ_T) -- | List variant of rqt_to_cmn. -- --
--   rqt_to_cmn_l (5,T) == [(4,T),(1,T)]
--   
rqt_to_cmn_l :: RQ_T -> [RQ_T] -- | concatMap rqt_to_cmn_l. -- --
--   rqt_set_to_cmn [(1,T),(5/4,F)] == [(1,T),(1,T),(1/4,F)]
--   
-- --
--   rqt_set_to_cmn [(1/5,True),(1/20,False),(1/2,False),(1/4,True)]
--   
rqt_set_to_cmn :: [RQ_T] -> [RQ_T] -- | RQ sub-divisions. module Music.Theory.Duration.RQ.Division -- | Divisions of n RQ into i equal parts grouped as -- j. A quarter and eighth note triplet is written -- (1,1,[2,1],False). type RQ_Div = (Rational, Integer, [Integer], Tied_Right) -- | Variant of RQ_Div where n is 1. type RQ1_Div = (Integer, [Integer], Tied_Right) -- | Lift RQ1_Div to RQ_Div. rq1_div_to_rq_div :: RQ1_Div -> RQ_Div -- | Verify that grouping j sums to the divisor i. rq_div_verify :: RQ_Div -> Bool rq_div_mm_verify :: Int -> [RQ_Div] -> [(Integer, [RQ])] -- | Translate from RQ_Div to a sequence of RQ values. -- --
--   rq_div_to_rq_set_t (1,5,[1,3,1],True) == ([1/5,3/5,1/5],True)
--   rq_div_to_rq_set_t (1/2,6,[3,1,2],False) == ([1/4,1/12,1/6],False)
--   
rq_div_to_rq_set_t :: RQ_Div -> ([RQ], Tied_Right) -- | Translate from result of rq_div_to_rq_set_t to seqeunce of -- RQ_T. -- --
--   rq_set_t_to_rqt ([1/5,3/5,1/5],True) == [(1/5,_f),(3/5,_f),(1/5,_t)]
--   
rq_set_t_to_rqt :: ([RQ], Tied_Right) -> [RQ_T] -- | Transform sequence of RQ_Div into sequence of RQ, -- discarding any final tie. -- --
--   let q = [(1,5,[1,3,1],True),(1/2,6,[3,1,2],True)]
--   in rq_div_seq_rq q == [1/5,3/5,9/20,1/12,1/6]
--   
rq_div_seq_rq :: [RQ_Div] -> [RQ] -- | Partitions of an Integral that sum to n. This includes -- the two 'trivial paritions, into a set n 1, and a set -- of 1 n. -- --
--   partitions_sum 4 == [[1,1,1,1],[2,1,1],[2,2],[3,1],[4]]
--   
-- --
--   map (length . partitions_sum) [9..15] == [30,42,56,77,101,135,176]
--   
partitions_sum :: Integral i => i -> [[i]] -- | The multiset_permutations of partitions_sum. -- --
--   map (length . partitions_sum_p) [9..12] == [256,512,1024,2048]
--   
partitions_sum_p :: Integral i => i -> [[i]] -- | The set of all RQ1_Div that sum to n, a variant on -- partitions_sum_p. -- --
--   map (length . rq1_div_univ) [3..5] == [8,16,32]
--   map (length . rq1_div_univ) [9..12] == [512,1024,2048,4096]
--   
rq1_div_univ :: Integer -> [RQ1_Div] -- | Notation of a sequence of RQ values as annotated -- Duration values. -- --
    --
  1. Separate input sequence into measures, adding tie annotations as -- required (see to_measures_ts). Ensure all RQ_T values -- can be notated as common music notation durations.
  2. --
  3. Separate each measure into pulses (see m_divisions_ts). -- Further subdivides pulses to ensure cmn tuplet notation. See -- to_divisions_ts for a composition of to_measures_ts and -- m_divisions_ts.
  4. --
  5. Simplify each measure (see m_simplify and -- default_rule). Coalesces tied durations where appropriate.
  6. --
  7. Notate measures (see m_notate or mm_notate).
  8. --
  9. Ascribe values to notated durations, see ascribe.
  10. --
module Music.Theory.Duration.Sequence.Notate -- | Variant of catMaybes. If all elements of the list are Just -- a, then gives Just [a] else gives Nothing. -- --
--   all_just (map Just [1..3]) == Just [1..3]
--   all_just [Just 1,Nothing,Just 3] == Nothing
--   
all_just :: [Maybe a] -> Maybe [a] -- | Variant of rights that preserves first Left. -- --
--   all_right (map Right [1..3]) == Right [1..3]
--   all_right [Right 1,Left 'a',Left 'b'] == Left 'a'
--   
all_right :: [Either a b] -> Either a [b] -- | Applies a join function to the first two elements of the list. -- If the join function succeeds the joined element is considered -- for further coalescing. -- --
--   coalesce (\p q -> Just (p + q)) [1..5] == [15]
--   
-- --
--   let jn p q = if even p then Just (p + q) else Nothing
--   in coalesce jn [1..5] == map sum [[1],[2,3],[4,5]]
--   
coalesce :: (a -> a -> Maybe a) -> [a] -> [a] -- | Variant of coalesce with accumulation parameter. -- --
--   coalesce_accum (\i p q -> Left (p + q)) 0 [1..5] == [(0,15)]
--   
-- --
--   let jn i p q = if even p then Left (p + q) else Right (p + i)
--   in coalesce_accum jn 0 [1..7] == [(0,1),(1,5),(6,9),(15,13)]
--   
-- --
--   let jn i p q = if even p then Left (p + q) else Right [p,q]
--   in coalesce_accum jn [] [1..5] == [([],1),([1,2],5),([5,4],9)]
--   
coalesce_accum :: (b -> a -> a -> Either a b) -> b -> [a] -> [(b, a)] -- | Variant of coalesce_accum that accumulates running sum. -- --
--   let f i p q = if i == 1 then Just (p + q) else Nothing
--   in coalesce_sum (+) 0 f [1,1/2,1/4,1/4] == [1,1]
--   
coalesce_sum :: (b -> a -> b) -> b -> (b -> a -> a -> Maybe a) -> [a] -> [a] -- | Lower Either to Maybe by discarding Left. either_to_maybe :: Either a b -> Maybe b -- | Take elements while the sum of the prefix is less than or equal to the -- indicated value. Returns also the difference between the prefix sum -- and the requested sum. Note that zero elements are kept left. -- --
--   take_sum_by id 3 [2,1] == ([2,1],0,[])
--   take_sum_by id 3 [2,2] == ([2],1,[2])
--   take_sum_by id 3 [2,1,0,1] == ([2,1,0],0,[1])
--   take_sum_by id 3 [4] == ([],3,[4])
--   take_sum_by id 0 [1..5] == ([],0,[1..5])
--   
take_sum_by :: (Ord n, Num n) => (a -> n) -> n -> [a] -> ([a], n, [a]) -- | Variant of take_sum_by with id function. take_sum :: (Ord a, Num a) => a -> [a] -> ([a], a, [a]) -- | Variant of take_sum that requires the prefix to sum to value. -- --
--   take_sum_by_eq id 3 [2,1,0,1] == Just ([2,1,0],[1])
--   take_sum_by_eq id 3 [2,2] == Nothing
--   
take_sum_by_eq :: (Ord n, Num n) => (a -> n) -> n -> [a] -> Maybe ([a], [a]) -- | Recursive variant of take_sum_by_eq. -- --
--   split_sum_by_eq id [3,3] [2,1,0,3] == Just [[2,1,0],[3]]
--   split_sum_by_eq id [3,3] [2,2,2] == Nothing
--   
split_sum_by_eq :: (Ord n, Num n) => (a -> n) -> [n] -> [a] -> Maybe [[a]] -- | Split sequence such that the prefix sums to precisely m. The -- third element of the result indicates if it was required to divide an -- element. Note that zero elements are kept left. If the required sum is -- non positive, or the input list does not sum to at least the required -- sum, gives nothing. -- --
--   split_sum 5 [2,3,1] == Just ([2,3],[1],Nothing)
--   split_sum 5 [2,1,3] == Just ([2,1,2],[1],Just (2,1))
--   split_sum 2 [3/2,3/2,3/2] == Just ([3/2,1/2],[1,3/2],Just (1/2,1))
--   split_sum 6 [1..10] == Just ([1..3],[4..10],Nothing)
--   fmap (\(a,_,c)->(a,c)) (split_sum 5 [1..]) == Just ([1,2,2],Just (2,1))
--   split_sum 0 [1..] == Nothing
--   split_sum 3 [1,1] == Nothing
--   split_sum 3 [2,1,0] == Just ([2,1,0],[],Nothing)
--   split_sum 3 [2,1,0,1] == Just ([2,1,0],[1],Nothing)
--   
split_sum :: (Ord a, Num a) => a -> [a] -> Maybe ([a], [a], Maybe (a, a)) -- | Alias for True, used locally for documentation. _t :: Bool -- | Alias for False, used locally for documentation. _f :: Bool -- | Variant of split_sum that operates at RQ_T sequences. -- --
--   let r = Just ([(3,_f),(2,_t)],[(1,_f)])
--   in rqt_split_sum 5 [(3,_f),(2,_t),(1,_f)] == r
--   
-- --
--   let r = Just ([(3,_f),(1,_t)],[(1,_t),(1,_f)])
--   in rqt_split_sum 4 [(3,_f),(2,_t),(1,_f)] == r
--   
-- --
--   rqt_split_sum 4 [(5/2,False)] == Nothing
--   
rqt_split_sum :: RQ -> [RQ_T] -> Maybe ([RQ_T], [RQ_T]) -- | Separate RQ_T values in sequences summing to RQ values. -- This is a recursive variant of rqt_split_sum. Note that is does -- not ensure cmn notation of values. -- --
--   let d = [(2,_f),(2,_f),(2,_f)]
--   in rqt_separate [3,3] d == Right [[(2,_f),(1,_t)]
--                                    ,[(1,_f),(2,_f)]]
--   
-- --
--   let d = [(5/8,_f),(1,_f),(3/8,_f)]
--   in rqt_separate [1,1] d == Right [[(5/8,_f),(3/8,_t)]
--                                    ,[(5/8,_f),(3/8,_f)]]
--   
-- --
--   let d = [(4/7,_t),(1/7,_f),(1,_f),(6/7,_f),(3/7,_f)]
--   in rqt_separate [1,1,1] d == Right [[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                      ,[(5/7,_f),(2/7,_t)]
--                                      ,[(4/7,_f),(3/7,_f)]]
--   
rqt_separate :: [RQ] -> [RQ_T] -> Either String [[RQ_T]] rqt_separate_m :: [RQ] -> [RQ_T] -> Maybe [[RQ_T]] -- | If the input RQ_T sequence cannot be notated (see -- rqt_can_notate) separate into equal parts, so long as each part -- is not less than i. -- --
--   rqt_separate_tuplet undefined [(1/3,_f),(1/6,_f)]
--   rqt_separate_tuplet undefined [(4/7,_t),(1/7,_f),(2/7,_f)]
--   
-- --
--   let d = map rq_rqt [1/3,1/6,2/5,1/10]
--   in rqt_separate_tuplet (1/8) d == Right [[(1/3,_f),(1/6,_f)]
--                                           ,[(2/5,_f),(1/10,_f)]]
--   
-- --
--   let d = [(1/5,True),(1/20,False),(1/2,False),(1/4,True)]
--   in rqt_separate_tuplet (1/16) d
--   
-- --
--   let d = [(2/5,_f),(1/5,_f),(1/5,_f),(1/5,_t),(1/2,_f),(1/2,_f)]
--   in rqt_separate_tuplet (1/2) d
--   
-- --
--   let d = [(4/10,True),(1/10,False),(1/2,True)]
--   in rqt_separate_tuplet (1/2) d
--   
rqt_separate_tuplet :: RQ -> [RQ_T] -> Either String [[RQ_T]] -- | Recursive variant of rqt_separate_tuplet. -- --
--   let d = map rq_rqt [1,1/3,1/6,2/5,1/10]
--   in rqt_tuplet_subdivide (1/8) d == [[(1/1,_f)]
--                                      ,[(1/3,_f),(1/6,_f)]
--                                      ,[(2/5,_f),(1/10,_f)]]
--   
rqt_tuplet_subdivide :: RQ -> [RQ_T] -> [[RQ_T]] -- | Sequence variant of rqt_tuplet_subdivide. -- --
--   let d = [(1/5,True),(1/20,False),(1/2,False),(1/4,True)]
--   in rqt_tuplet_subdivide_seq (1/2) [d]
--   
rqt_tuplet_subdivide_seq :: RQ -> [[RQ_T]] -> [[RQ_T]] -- | If a tuplet is all tied, it ought to be a plain value?! -- --
--   rqt_tuplet_sanity_ [(4/10,_t),(1/10,_f)] == [(1/2,_f)]
--   
rqt_tuplet_sanity_ :: [RQ_T] -> [RQ_T] rqt_tuplet_subdivide_seq_sanity_ :: RQ -> [[RQ_T]] -> [[RQ_T]] -- | Separate RQ sequence into measures given by RQ length. -- --
--   to_measures_rq [3,3] [2,2,2] == Right [[(2,_f),(1,_t)],[(1,_f),(2,_f)]]
--   to_measures_rq [3,3] [6] == Right [[(3,_t)],[(3,_f)]]
--   to_measures_rq [1,1,1] [3] == Right [[(1,_t)],[(1,_t)],[(1,_f)]]
--   to_measures_rq [3,3] [2,2,1]
--   to_measures_rq [3,2] [2,2,2]
--   
-- --
--   let d = [4/7,33/28,9/20,4/5]
--   in to_measures_rq [3] d == Right [[(4/7,_f),(33/28,_f),(9/20,_f),(4/5,_f)]]
--   
to_measures_rq :: [RQ] -> [RQ] -> Either String [[RQ_T]] -- | Variant of to_measures_rq that ensures RQ_T are -- cmn durations. This is not a good composition. -- --
--   to_measures_rq_cmn [6,6] [5,5,2] == Right [[(4,_t),(1,_f),(1,_t)]
--                                             ,[(4,_f),(2,_f)]]
--   
-- --
--   let r = [[(4/7,_t),(1/7,_f),(1,_f),(6/7,_f),(3/7,_f)]]
--   in to_measures_rq_cmn [3] [5/7,1,6/7,3/7] == Right r
--   
-- --
--   to_measures_rq_cmn [1,1,1] [5/7,1,6/7,3/7] == Right [[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                                       ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                                       ,[(4/7,_f),(3/7,_f)]]
--   
to_measures_rq_cmn :: [RQ] -> [RQ] -> Either String [[RQ_T]] -- | Variant of to_measures_rq with measures given by -- Time_Signature values. Does not ensure RQ_T are -- cmn durations. -- --
--   to_measures_ts [(1,4)] [5/8,3/8] /= Right [[(1/2,_t),(1/8,_f),(3/8,_f)]]
--   to_measures_ts [(1,4)] [5/7,2/7] /= Right [[(4/7,_t),(1/7,_f),(2/7,_f)]]
--   
-- --
--   let {m = replicate 18 (1,4)
--       ;x = [3/4,2,5/4,9/4,1/4,3/2,1/2,7/4,1,5/2,11/4,3/2]}
--   in to_measures_ts m x == Right [[(3/4,_f),(1/4,_t)],[(1/1,_t)]
--                                  ,[(3/4,_f),(1/4,_t)],[(1/1,_f)]
--                                  ,[(1/1,_t)],[(1/1,_t)]
--                                  ,[(1/4,_f),(1/4,_f),(1/2,_t)],[(1/1,_f)]
--                                  ,[(1/2,_f),(1/2,_t)],[(1/1,_t)]
--                                  ,[(1/4,_f),(3/4,_t)],[(1/4,_f),(3/4,_t)]
--                                  ,[(1/1,_t)],[(3/4,_f),(1/4,_t)]
--                                  ,[(1/1,_t)],[(1/1,_t)]
--                                  ,[(1/2,_f),(1/2,_t)],[(1/1,_f)]]
--   
-- --
--   to_measures_ts [(3,4)] [4/7,33/28,9/20,4/5]
--   to_measures_ts (replicate 3 (1,4)) [4/7,33/28,9/20,4/5]
--   
to_measures_ts :: [Time_Signature] -> [RQ] -> Either String [[RQ_T]] -- | Variant of to_measures_ts that allows for duration field -- operation but requires that measures be well formed. This is useful -- for re-grouping measures after notation and ascription. to_measures_ts_by_eq :: (a -> RQ) -> [Time_Signature] -> [a] -> Maybe [[a]] -- | Divide measure into pulses of indicated RQ durations. Measure -- must be of correct length but need not contain only cmn -- durations. Pulses are further subdivided if required to notate tuplets -- correctly, see rqt_tuplet_subdivide_seq. -- --
--   let d = [(1/4,_f),(1/4,_f),(2/3,_t),(1/6,_f),(16/15,_f),(1/5,_f)
--           ,(1/5,_f),(2/5,_t),(1/20,_f),(1/2,_f),(1/4,_t)]
--   in m_divisions_rq [1,1,1,1] d
--   
-- --
--   m_divisions_rq [1,1,1] [(4/7,_f),(33/28,_f),(9/20,_f),(4/5,_f)]
--   
m_divisions_rq :: [RQ] -> [RQ_T] -> Either String [[RQ_T]] -- | Variant of m_divisions_rq that determines pulse divisions from -- Time_Signature. -- --
--   let d = [(4/7,_t),(1/7,_f),(2/7,_f)]
--   in m_divisions_ts (1,4) d == Just [d]
--   
-- --
--   let d = map rq_rqt [1/3,1/6,2/5,1/10]
--   in m_divisions_ts (1,4) d == Just [[(1/3,_f),(1/6,_f)]
--                                     ,[(2/5,_f),(1/10,_f)]]
--   
-- --
--   let d = map rq_rqt [4/7,33/28,9/20,4/5]
--   in m_divisions_ts (3,4) d == Just [[(4/7,_f),(3/7,_t)]
--                                     ,[(3/4,_f),(1/4,_t)]
--                                     ,[(1/5,_f),(4/5,_f)]]
--   
m_divisions_ts :: Time_Signature -> [RQ_T] -> Either String [[RQ_T]] -- | Composition of to_measures_rq and m_divisions_rq, where -- measures are initially given as sets of divisions. -- --
--   let m = [[1,1,1],[1,1,1]]
--   in to_divisions_rq m [2,2,2] == Right [[[(1,_t)],[(1,_f)],[(1,_t)]]
--                                        ,[[(1,_f)],[(1,_t)],[(1,_f)]]]
--   
-- --
--   let d = [2/7,1/7,4/7,5/7,8/7,1,1/7]
--   in to_divisions_rq [[1,1,1,1]] d == Right [[[(2/7,_f),(1/7,_f),(4/7,_f)]
--                                             ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                             ,[(6/7,_f),(1/7,_t)]
--                                             ,[(6/7,_f),(1/7,_f)]]]
--   
-- --
--   let d = [5/7,1,6/7,3/7]
--   in to_divisions_rq [[1,1,1]] d == Right [[[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                           ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                           ,[(4/7,_f),(3/7,_f)]]]
--   
-- --
--   let d = [2/7,1/7,4/7,5/7,1,6/7,3/7]
--   in to_divisions_rq [[1,1,1,1]] d == Right [[[(2/7,_f),(1/7,_f),(4/7,_f)]
--                                             ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                             ,[(4/7,_t),(1/7,_f),(2/7,_t)]
--                                             ,[(4/7,_f),(3/7,_f)]]]
--   
-- --
--   let d = [4/7,33/28,9/20,4/5]
--   in to_divisions_rq [[1,1,1]] d == Right [[[(4/7,_f),(3/7,_t)]
--                                            ,[(3/4,_f),(1/4,_t)]
--                                            ,[(1/5,_f),(4/5,_f)]]]
--   
-- --
--   let {p = [[1/2,1,1/2],[1/2,1]]
--       ;d = map (/6) [1,1,1,1,1,1,4,1,2,1,1,2,1,3]}
--   in to_divisions_rq p d == Right [[[(1/6,_f),(1/6,_f),(1/6,_f)]
--                                    ,[(1/6,_f),(1/6,_f),(1/6,_f),(1/2,True)]
--                                    ,[(1/6,_f),(1/6,_f),(1/6,True)]]
--                                   ,[[(1/6,_f),(1/6,_f),(1/6,_f)]
--                                    ,[(1/3,_f),(1/6,_f),(1/2,_f)]]]
--   
to_divisions_rq :: [[RQ]] -> [RQ] -> Either String [[[RQ_T]]] -- | Variant of to_divisions_rq with measures given as set of -- Time_Signature. -- --
--   let d = [3/5,2/5,1/3,1/6,7/10,17/15,1/2,1/6]
--   in to_divisions_ts [(4,4)] d == Just [[[(3/5,_f),(2/5,_f)]
--                                         ,[(1/3,_f),(1/6,_f),(1/2,_t)]
--                                         ,[(1/5,_f),(4/5,_t)]
--                                         ,[(1/3,_f),(1/2,_f),(1/6,_f)]]]
--   
-- --
--   let d = [3/5,2/5,1/3,1/6,7/10,29/30,1/2,1/3]
--   in to_divisions_ts [(4,4)] d == Just [[[(3/5,_f),(2/5,_f)]
--                                         ,[(1/3,_f),(1/6,_f),(1/2,_t)]
--                                         ,[(1/5,_f),(4/5,_t)]
--                                         ,[(1/6,_f),(1/2,_f),(1/3,_f)]]]
--   
-- --
--   let d = [3/5,2/5,1/3,1/6,7/10,4/5,1/2,1/2]
--   in to_divisions_ts [(4,4)] d == Just [[[(3/5,_f),(2/5,_f)]
--                                         ,[(1/3,_f),(1/6,_f),(1/2,_t)]
--                                         ,[(1/5,_f),(4/5,_f)]
--                                         ,[(1/2,_f),(1/2,_f)]]]
--   
-- --
--   let d = [4/7,33/28,9/20,4/5]
--   in to_divisions_ts [(3,4)] d == Just [[[(4/7,_f),(3/7,_t)]
--                                         ,[(3/4,_f),(1/4,_t)]
--                                         ,[(1/5,_f),(4/5,_f)]]]
--   
to_divisions_ts :: [Time_Signature] -> [RQ] -> Either String [[[RQ_T]]] -- | Pulse tuplet derivation. -- --
--   p_tuplet_rqt [(2/3,_f),(1/3,_t)] == Just ((3,2),[(1,_f),(1/2,_t)])
--   p_tuplet_rqt (map rq_rqt [1/3,1/6]) == Just ((3,2),[(1/2,_f),(1/4,_f)])
--   p_tuplet_rqt (map rq_rqt [2/5,1/10]) == Just ((5,4),[(1/2,_f),(1/8,_f)])
--   p_tuplet_rqt (map rq_rqt [1/3,1/6,2/5,1/10])
--   
p_tuplet_rqt :: [RQ_T] -> Maybe ((Integer, Integer), [RQ_T]) -- | Notate pulse, ie. derive tuplet if neccesary. The flag indicates if -- the initial value is tied left. -- --
--   p_notate False [(2/3,_f),(1/3,_t)]
--   p_notate False [(2/5,_f),(1/10,_t)]
--   p_notate False [(1/4,_t),(1/8,_f),(1/8,_f)]
--   p_notate False (map rq_rqt [1/3,1/6])
--   p_notate False (map rq_rqt [2/5,1/10])
--   p_notate False (map rq_rqt [1/3,1/6,2/5,1/10]) == Nothing
--   
p_notate :: Bool -> [RQ_T] -> Either String [Duration_A] -- | Notate measure. -- --
--   m_notate True [[(2/3,_f),(1/3,_t)],[(1,_t)],[(1,_f)]]
--   
-- --
--   let f = m_notate False . concat
--   
-- --
--   fmap f (to_divisions_ts [(4,4)] [3/5,2/5,1/3,1/6,7/10,17/15,1/2,1/6])
--   fmap f (to_divisions_ts [(4,4)] [3/5,2/5,1/3,1/6,7/10,29/30,1/2,1/3])
--   
m_notate :: Bool -> [[RQ_T]] -> Either String [Duration_A] -- | Multiple measure notation. -- --
--   let d = [2/7,1/7,4/7,5/7,8/7,1,1/7]
--   in fmap mm_notate (to_divisions_ts [(4,4)] d)
--   
-- --
--   let d = [2/7,1/7,4/7,5/7,1,6/7,3/7]
--   in fmap mm_notate (to_divisions_ts [(4,4)] d)
--   
-- --
--   let d = [3/5,2/5,1/3,1/6,7/10,4/5,1/2,1/2]
--   in fmap mm_notate (to_divisions_ts [(4,4)] d)
--   
-- --
--   let {p = [[1/2,1,1/2],[1/2,1]]
--       ;d = map (/6) [1,1,1,1,1,1,4,1,2,1,1,2,1,3]}
--   in fmap mm_notate (to_divisions_rq p d)
--   
mm_notate :: [[[RQ_T]]] -> Either String [[Duration_A]] -- | Structure given to Simplify_P to decide simplification. The -- structure is (ts,start-rq,(left-rq,right-rq)). type Simplify_T = (Time_Signature, RQ, (RQ, RQ)) -- | Predicate function at Simplify_T. type Simplify_P = Simplify_T -> Bool -- | Variant of Simplify_T allowing multiple rules. type Simplify_M = ([Time_Signature], [RQ], [(RQ, RQ)]) -- | Transform Simplify_M to Simplify_P. meta_table_p :: Simplify_M -> Simplify_P -- | Transform Simplify_M to set of Simplify_T. meta_table_t :: Simplify_M -> [Simplify_T] -- | The default table of simplifiers. -- --
--   default_table ((3,4),1,(1,1)) == True
--   
default_table :: Simplify_P -- | The default eighth-note pulse simplifier rule. -- --
--   default_8_rule ((3,8),0,(1/2,1/2)) == True
--   default_8_rule ((3,8),1/2,(1/2,1/2)) == True
--   default_8_rule ((3,8),1,(1/2,1/2)) == True
--   default_8_rule ((2,8),0,(1/2,1/2)) == True
--   default_8_rule ((5,8),0,(1,1/2)) == True
--   default_8_rule ((5,8),0,(2,1/2)) == True
--   
default_8_rule :: Simplify_P -- | The default quarter note pulse simplifier rule. -- --
--   default_4_rule ((3,4),0,(1,1/2)) == True
--   default_4_rule ((3,4),0,(1,3/4)) == True
--   default_4_rule ((4,4),1,(1,1)) == False
--   default_4_rule ((4,4),2,(1,1)) == True
--   default_4_rule ((4,4),2,(1,2)) == True
--   default_4_rule ((4,4),0,(2,1)) == True
--   default_4_rule ((3,4),1,(1,1)) == False
--   
default_4_rule :: Simplify_P -- | The default simplifier rule. To extend provide a list of -- Simplify_T. default_rule :: [Simplify_T] -> Simplify_P -- | Measure simplifier. Apply given Simplify_P. m_simplify :: Simplify_P -> Time_Signature -> [Duration_A] -> [Duration_A] -- | Pulse simplifier predicate, which is const True. p_simplify_rule :: Simplify_P -- | Pulse simplifier. -- --
--   import Music.Theory.Duration.Name.Abbreviation
--   p_simplify [(q,[Tie_Right]),(e,[Tie_Left])] == [(q',[])]
--   p_simplify [(e,[Tie_Right]),(q,[Tie_Left])] == [(q',[])]
--   p_simplify [(q,[Tie_Right]),(e',[Tie_Left])] == [(q'',[])]
--   p_simplify [(q'',[Tie_Right]),(s,[Tie_Left])] == [(h,[])]
--   p_simplify [(e,[Tie_Right]),(s,[Tie_Left]),(e',[])] == [(e',[]),(e',[])]
--   
-- --
--   let f = rqt_to_duration_a False
--   in p_simplify (f [(1/8,_t),(1/4,_t),(1/8,_f)]) == f [(1/2,_f)]
--   
p_simplify :: [Duration_A] -> [Duration_A] -- | Notate RQ duration sequence. Derive pulse divisions from -- Time_Signature if not given directly. Composition of -- to_divisions_ts, mm_notate m_simplify. -- --
--   let ts = [(4,8),(3,8)]
--       ts_p = [[1/2,1,1/2],[1/2,1]]
--       rq = map (/6) [1,1,1,1,1,1,4,1,2,1,1,2,1,3]
--       sr x = T.default_rule [] x
--   in T.notate_rqp sr ts (Just ts_p) rq
--   
notate_rqp :: Simplify_P -> [Time_Signature] -> Maybe [[RQ]] -> [RQ] -> Either String [[Duration_A]] -- | Variant of notate_rqp without pulse divisions (derive). -- --
--   notate (default_rule [((3,2),0,(2,2)),((3,2),0,(4,2))]) [(3,2)] [6]
--   
notate :: Simplify_P -> [Time_Signature] -> [RQ] -> Either String [[Duration_A]] -- | Variant of zip that retains elements of the right hand (rhs) -- list where elements of the left hand (lhs) list meet the given lhs -- predicate. If the right hand side is longer the remaining elements to -- be processed are given. It is an error for the right hand side to be -- short. -- --
--   zip_hold_lhs even [1..5] "abc" == ([],zip [1..6] "abbcc")
--   zip_hold_lhs odd [1..6] "abc" == ([],zip [1..6] "aabbcc")
--   zip_hold_lhs even [1] "ab" == ("b",[(1,'a')])
--   zip_hold_lhs even [1,2] "a" == undefined
--   
zip_hold_lhs :: (Show t, Show x) => (x -> Bool) -> [x] -> [t] -> ([t], [(x, t)]) -- | Variant of zip_hold that requires the right hand side to be -- precisely the required length. -- --
--   zip_hold_lhs_err even [1..5] "abc" == zip [1..6] "abbcc"
--   zip_hold_lhs_err odd [1..6] "abc" == zip [1..6] "aabbcc"
--   zip_hold_lhs_err id [False,False] "a" == undefined
--   zip_hold_lhs_err id [False] "ab" == undefined
--   
zip_hold_lhs_err :: (Show t, Show x) => (x -> Bool) -> [x] -> [t] -> [(x, t)] -- | Variant of zip that retains elements of the right hand (rhs) -- list where elements of the left hand (lhs) list meet the given lhs -- predicate, and elements of the lhs list where elements of the rhs meet -- the rhs predicate. If the right hand side is longer the remaining -- elements to be processed are given. It is an error for the right hand -- side to be short. -- --
--   zip_hold even (const False) [1..5] "abc" == ([],zip [1..6] "abbcc")
--   zip_hold odd (const False) [1..6] "abc" == ([],zip [1..6] "aabbcc")
--   zip_hold even (const False) [1] "ab" == ("b",[(1,'a')])
--   zip_hold even (const False) [1,2] "a" == undefined
--   
-- --
--   zip_hold odd even [1,2,6] [1..5] == ([4,5],[(1,1),(2,1),(6,2),(6,3)])
--   
zip_hold :: (Show t, Show x) => (x -> Bool) -> (t -> Bool) -> [x] -> [t] -> ([t], [(x, t)]) -- | Zip a list of Duration_A elements duplicating elements of the -- right hand sequence for tied durations. -- --
--   let {Just d = to_divisions_ts [(4,4),(4,4)] [3,3,2]
--       ;f = map snd . snd . flip m_ascribe "xyz"}
--   in fmap f (notate d) == Just "xxxyyyzz"
--   
m_ascribe :: Show x => [Duration_A] -> [x] -> ([x], [(Duration_A, x)]) -- | snd . m_ascribe. ascribe :: Show x => [Duration_A] -> [x] -> [(Duration_A, x)] -- | Variant of m_ascribe for a set of measures. mm_ascribe :: Show x => [[Duration_A]] -> [x] -> [[(Duration_A, x)]] -- | 'mm_ascribe of notate. notate_mm_ascribe :: Show a => [Simplify_T] -> [Time_Signature] -> Maybe [[RQ]] -> [RQ] -> [a] -> Either String [[(Duration_A, a)]] notate_mm_ascribe_err :: Show a => [Simplify_T] -> [Time_Signature] -> Maybe [[RQ]] -> [RQ] -> [a] -> [[(Duration_A, a)]] -- | Group elements as chords where a chord element is indicated by -- the given predicate. -- --
--   group_chd even [1,2,3,4,4,5,7,8] == [[1,2],[3,4,4],[5],[7,8]]
--   
group_chd :: (x -> Bool) -> [x] -> [[x]] -- | Variant of ascribe that groups the rhs elements using -- group_chd and with the indicated chord function, then -- rejoins the resulting sequence. ascribe_chd :: Show x => (x -> Bool) -> [Duration_A] -> [x] -> [(Duration_A, x)] -- | Variant of mm_ascribe using group_chd mm_ascribe_chd :: Show x => (x -> Bool) -> [[Duration_A]] -> [x] -> [[(Duration_A, x)]] -- | Common music notation dynamic marks. module Music.Theory.Dynamic_Mark -- | Enumeration of dynamic mark symbols. data Dynamic_Mark_T Niente :: Dynamic_Mark_T PPPPP :: Dynamic_Mark_T PPPP :: Dynamic_Mark_T PPP :: Dynamic_Mark_T PP :: Dynamic_Mark_T P :: Dynamic_Mark_T MP :: Dynamic_Mark_T MF :: Dynamic_Mark_T F :: Dynamic_Mark_T FF :: Dynamic_Mark_T FFF :: Dynamic_Mark_T FFFF :: Dynamic_Mark_T FFFFF :: Dynamic_Mark_T FP :: Dynamic_Mark_T SF :: Dynamic_Mark_T SFP :: Dynamic_Mark_T SFPP :: Dynamic_Mark_T SFZ :: Dynamic_Mark_T SFFZ :: Dynamic_Mark_T -- | Lookup MIDI velocity for Dynamic_Mark_T. The range is linear in -- 0-127. -- --
--   let r = [0,6,17,28,39,50,61,72,83,94,105,116,127]
--   in mapMaybe dynamic_mark_midi [Niente .. FFFFF] == r
--   
-- --
--   map dynamic_mark_midi [FP,SF,SFP,SFPP,SFZ,SFFZ] == replicate 6 Nothing
--   
dynamic_mark_midi :: (Num n, Enum n) => Dynamic_Mark_T -> Maybe n -- | Error variant. dynamic_mark_midi_err :: Integral n => Dynamic_Mark_T -> n -- | Map midi velocity (0-127) to dynamic mark. -- --
--   histogram (mapMaybe midi_dynamic_mark [0 .. 127])
--   
midi_dynamic_mark :: (Ord n, Eq n, Num n, Enum n) => n -> Maybe Dynamic_Mark_T -- | Translate fixed Dynamic_Mark_Ts to db amplitude -- over given range. -- --
--   mapMaybe (dynamic_mark_db 120) [Niente,P,F,FFFFF] == [-120,-70,-40,0]
--   mapMaybe (dynamic_mark_db 60) [Niente,P,F,FFFFF] == [-60,-35,-20,0]
--   
dynamic_mark_db :: Fractional n => n -> Dynamic_Mark_T -> Maybe n -- | http://www.csounds.com/manual/html/ampmidid.html -- --
--   import Sound.SC3.Plot
--   plotTable [map (ampmidid 20) [0 .. 127],map (ampmidid 60) [0 .. 127]]
--   
ampmidid :: Floating a => a -> a -> a -- | JMcC (SC3) equation. -- --
--   plotTable1 (map amp_db [0,0.005 .. 1])
--   
amp_db :: Floating a => a -> a -- | JMcC (SC3) equation. -- --
--   plotTable1 (map db_amp [-60,-59 .. 0])
--   
db_amp :: Floating a => a -> a -- | Enumeration of hairpin indicators. data Hairpin_T Crescendo :: Hairpin_T Diminuendo :: Hairpin_T End_Hairpin :: Hairpin_T -- | The Hairpin_T implied by a ordered pair of -- Dynamic_Mark_Ts. -- --
--   map (implied_hairpin MF) [MP,F] == [Just Diminuendo,Just Crescendo]
--   
implied_hairpin :: Dynamic_Mark_T -> Dynamic_Mark_T -> Maybe Hairpin_T -- | A node in a dynamic sequence. type Dynamic_Node = (Maybe Dynamic_Mark_T, Maybe Hairpin_T) -- | The empty Dynamic_Node. empty_dynamic_node :: Dynamic_Node -- | Calculate a Dynamic_Node sequence from a sequence of -- Dynamic_Mark_Ts. -- --
--   dynamic_sequence [PP,MP,MP,PP] == [(Just PP,Just Crescendo)
--                                     ,(Just MP,Just End_Hairpin)
--                                     ,(Nothing,Just Diminuendo)
--                                     ,(Just PP,Just End_Hairpin)]
--   
dynamic_sequence :: [Dynamic_Mark_T] -> [Dynamic_Node] -- | Delete redundant (unaltered) dynamic marks. -- --
--   let s = [Just P,Nothing,Just P,Just P,Just F]
--   in delete_redundant_marks s == [Just P,Nothing,Nothing,Nothing,Just F]
--   
delete_redundant_marks :: [Maybe Dynamic_Mark_T] -> [Maybe Dynamic_Mark_T] -- | Variant of dynamic_sequence for sequences of -- Dynamic_Mark_T with holes (ie. rests). Runs -- delete_redundant_marks. -- --
--   let r = [Just (Just P,Just Crescendo),Just (Just F,Just End_Hairpin)
--           ,Nothing,Just (Just P,Nothing)]
--   in dynamic_sequence_sets [Just P,Just F,Nothing,Just P] == r
--   
-- --
--   let s = [Just P,Nothing,Just P]
--   in dynamic_sequence_sets s = [Just (Just P,Nothing),Nothing,Nothing]
--   
dynamic_sequence_sets :: [Maybe Dynamic_Mark_T] -> [Maybe Dynamic_Node] -- | Apply Hairpin_T and Dynamic_Mark_T functions in that -- order as required by Dynamic_Node. -- --
--   let f _ x = show x
--   in apply_dynamic_node f f (Nothing,Just Crescendo) undefined
--   
apply_dynamic_node :: (a -> Dynamic_Mark_T -> a) -> (a -> Hairpin_T -> a) -> Dynamic_Node -> a -> a -- | ASCII pretty printer for Dynamic_Mark_T. dynamic_mark_ascii :: Dynamic_Mark_T -> String -- | ASCII pretty printer for Hairpin_T. hairpin_ascii :: Hairpin_T -> String -- | ASCII pretty printer for Dynamic_Node. dynamic_node_ascii :: Dynamic_Node -> String -- | ASCII pretty printer for Dynamic_Node sequence. dynamic_sequence_ascii :: [Dynamic_Node] -> String instance Eq Dynamic_Mark_T instance Ord Dynamic_Mark_T instance Enum Dynamic_Mark_T instance Bounded Dynamic_Mark_T instance Show Dynamic_Mark_T instance Eq Hairpin_T instance Ord Hairpin_T instance Enum Hairpin_T instance Bounded Hairpin_T instance Show Hairpin_T -- | Tuning theory module Music.Theory.Tuning -- | An approximation of a ratio. type Approximate_Ratio = Double -- | A real valued division of a semi-tone into one hundred parts, and -- hence of the octave into 1200 parts. type Cents = Double -- | A tuning specified Either as a sequence of exact ratios, or as -- a sequence of possibly inexact Cents. data Tuning Tuning :: Either [Rational] [Cents] -> Rational -> Tuning ratios_or_cents :: Tuning -> Either [Rational] [Cents] octave_ratio :: Tuning -> Rational -- | Divisions of octave. -- --
--   divisions ditone == 12
--   
divisions :: Tuning -> Int -- | Maybe exact ratios of Tuning. ratios :: Tuning -> Maybe [Rational] -- | erroring variant. ratios_err :: Tuning -> [Rational] -- | Possibly inexact Cents of tuning. cents :: Tuning -> [Cents] -- | map round . cents. cents_i :: Integral i => Tuning -> [i] -- | Variant of cents that includes octave at right. cents_octave :: Tuning -> [Cents] -- | Convert from interval in cents to frequency ratio. -- --
--   map cents_to_ratio [0,701.9550008653874,1200] == [1,3/2,2]
--   
cents_to_ratio :: Floating a => a -> a -- | Possibly inexact Approximate_Ratios of tuning. approximate_ratios :: Tuning -> [Approximate_Ratio] -- | Cyclic form, taking into consideration octave_ratio. approximate_ratios_cyclic :: Tuning -> [Approximate_Ratio] -- | Maybe exact ratios reconstructed from possibly inexact -- Cents of Tuning. -- --
--   let r = [1,17/16,9/8,13/11,5/4,4/3,7/5,3/2,11/7,5/3,16/9,15/8]
--   in reconstructed_ratios 1e-2 werckmeister_iii == Just r
--   
reconstructed_ratios :: Double -> Tuning -> Maybe [Rational] -- | Convert from a Floating ratio to cents. -- --
--   let r = [0,498,702,1200]
--   in map (round . fratio_to_cents) [1,4/3,3/2,2] == r
--   
fratio_to_cents :: (Real r, Floating n) => r -> n -- | Type specialised fratio_to_cents. approximate_ratio_to_cents :: Approximate_Ratio -> Cents -- | Type specialised fromRational. approximate_ratio :: Rational -> Approximate_Ratio -- | approximate_ratio_to_cents . approximate_ratio. ratio_to_cents :: Rational -> Cents -- | Construct an exact Rational that approximates Cents to -- within epsilon. -- --
--   map (reconstructed_ratio 1e-5) [0,700,1200] == [1,442/295,2]
--   
-- --
--   ratio_to_cents (442/295) == 699.9976981706734
--   
reconstructed_ratio :: Double -> Cents -> Rational -- | Frequency n cents from f. -- --
--   import Music.Theory.Pitch
--   map (cps_shift_cents 440) [-100,100] == map octpc_to_cps [(4,8),(4,10)]
--   
cps_shift_cents :: Floating a => a -> a -> a -- | Interval in cents from p to q, ie. -- ratio_to_cents of p / q. -- --
--   cps_difference_cents 440 (octpc_to_cps (5,2)) == 500
--   
-- --
--   let abs_dif i j = abs (i - j)
--   in cps_difference_cents 440 (fmidi_to_cps 69.1) `abs_dif` 10 < 1e9
--   
cps_difference_cents :: (Real r, Fractional r, Floating n) => r -> r -> n -- | The Syntonic comma. -- --
--   syntonic_comma == 81/80
--   
syntonic_comma :: Rational -- | The Pythagorean comma. -- --
--   pythagorean_comma == 3^12 / 2^19
--   
pythagorean_comma :: Rational -- | Mercators comma. -- --
--   mercators_comma == 3^53 / 2^84
--   
mercators_comma :: Rational -- | Calculate nth root of x. -- --
--   12 `nth_root` 2 == twelve_tone_equal_temperament_comma
--   
nth_root :: (Floating a, Eq a) => a -> a -> a -- | 12-tone equal temperament comma (ie. 12th root of 2). -- --
--   twelve_tone_equal_temperament_comma == 1.0594630943592953
--   
twelve_tone_equal_temperament_comma :: (Floating a, Eq a) => a -- | Make n division equal temperament. equal_temperament :: Integral n => n -> Tuning -- | 12-tone equal temperament. -- --
--   cents equal_temperament_12 == [0,100..1100]
--   
equal_temperament_12 :: Tuning -- | 19-tone equal temperament. equal_temperament_19 :: Tuning -- | 31-tone equal temperament. equal_temperament_31 :: Tuning -- | 53-tone equal temperament. equal_temperament_53 :: Tuning -- | 72-tone equal temperament. -- --
--   let r = [0,17,33,50,67,83,100]
--   in take 7 (map round (cents equal_temperament_72)) == r
--   
equal_temperament_72 :: Tuning -- | Raise or lower the frequency q by octaves until it is in the -- octave starting at p. -- --
--   fold_cps_to_octave_of 55 392 == 98
--   
fold_cps_to_octave_of :: (Ord a, Fractional a) => a -> a -> a -- | Harmonic series on n. harmonic_series_cps :: (Num t, Enum t) => t -> [t] -- | n elements of harmonic_series_cps. -- --
--   let r = [55,110,165,220,275,330,385,440,495,550,605,660,715,770,825,880,935]
--   in harmonic_series_cps_n 17 55 == r
--   
harmonic_series_cps_n :: (Num a, Enum a) => Int -> a -> [a] -- | Sub-harmonic series on n. subharmonic_series_cps :: (Fractional t, Enum t) => t -> [t] -- | n elements of harmonic_series_cps. -- --
--   let r = [1760,880,587,440,352,293,251,220,196,176,160,147,135,126,117,110,104]
--   in map round (subharmonic_series_cps_n 17 1760) == r
--   
subharmonic_series_cps_n :: (Fractional t, Enum t) => Int -> t -> [t] -- | nth partial of f1, ie. one indexed. -- --
--   map (partial 55) [1,5,3] == [55,275,165]
--   
partial :: (Num a, Enum a) => a -> Int -> a -- | Fold ratio until within an octave, ie. 1 < n -- <= 2. -- --
--   map fold_ratio_to_octave [2/3,3/4] == [4/3,3/2]
--   
fold_ratio_to_octave :: Integral i => Ratio i -> Ratio i -- | The interval between two pitches p and q given as ratio -- multipliers of a fundamental is q / p. The -- classes over such intervals consider the fold_ratio_to_octave -- of both p to q and q to p. -- --
--   map ratio_interval_class [2/3,3/2,3/4,4/3] == [3/2,3/2,3/2,3/2]
--   
ratio_interval_class :: Integral i => Ratio i -> Ratio i -- | Derivative harmonic series, based on kth partial of f1. -- --
--   import Music.Theory.Pitch
--   
-- --
--   let {r = [52,103,155,206,258,309,361,412,464,515,567,618,670,721,773]
--       ;d = harmonic_series_cps_derived 5 (octpc_to_cps (1,4))}
--   in map round (take 15 d) == r
--   
harmonic_series_cps_derived :: (Ord a, Fractional a, Enum a) => Int -> a -> [a] -- | Harmonic series to nth harmonic (folded). -- --
--   harmonic_series_folded 17 == [1,17/16,9/8,5/4,11/8,3/2,13/8,7/4,15/8]
--   
-- --
--   let r = [0,105,204,386,551,702,841,969,1088]
--   in map (round . ratio_to_cents) (harmonic_series_folded 17) == r
--   
harmonic_series_folded :: Integer -> [Rational] -- | ratio_to_cents variant of harmonic_series_folded. -- --
--   map round (harmonic_series_folded_c 21) == [0,105,204,298,386,471,551,702,841,969,1088]
--   
harmonic_series_folded_c :: Integer -> [Cents] -- | 12-tone tuning of first 21 elements of the harmonic -- series. -- --
--   cents_i harmonic_series_folded_21 == [0,105,204,298,386,471,551,702,841,969,1088]
--   divisions harmonic_series_folded_21 == 11
--   
harmonic_series_folded_21 :: Tuning -- | Give cents difference from nearest 12ET tone. -- --
--   let r = [50,-49,-2,0,2,49,50]
--   in map cents_et12_diff [650,651,698,700,702,749,750] == r
--   
cents_et12_diff :: Integral n => n -> n -- | Fractional form of cents_et12_diff. fcents_et12_diff :: Real n => n -> n -- | The class of cents intervals has range (0,600). -- --
--   map cents_interval_class [50,1150,1250] == [50,50,50]
--   
-- --
--   let r = concat [[0,50 .. 550],[600],[550,500 .. 0]]
--   in map cents_interval_class [1200,1250 .. 2400] == r
--   
cents_interval_class :: Integral a => a -> a -- | Fractional form of cents_interval_class. fcents_interval_class :: Real a => a -> a -- | Always include the sign, elide 0. cents_diff_pp :: (Num a, Ord a, Show a) => a -> String -- | Given brackets, print cents difference. cents_diff_br :: (Num a, Ord a, Show a) => (String, String) -> a -> String -- | cents_diff_br with parentheses. -- --
--   map cents_diff_text [-1,0,1] == ["(-1)","","(+1)"]
--   
cents_diff_text :: (Num a, Ord a, Show a) => a -> String -- | cents_diff_br with markdown superscript (^). cents_diff_md :: (Num a, Ord a, Show a) => a -> String -- | cents_diff_br with HTML superscript (sup). cents_diff_html :: (Num a, Ord a, Show a) => a -> String -- | (n -> dt). Function from midi note number n to -- Midi_Detune dt. The incoming note number is the key -- pressed, which may be distant from the note sounded. type Midi_Tuning_F = Int -> Midi_Detune -- | (t,c,k) where t=tuning (must have 12 divisions of octave), c=cents -- deviation (ie. constant detune offset), k=midi offset (ie. value to be -- added to incoming midi note number). type D12_Midi_Tuning = (Tuning, Cents, Int) -- | Midi_Tuning_F for D12_Midi_Tuning. -- --
--   import Music.Theory.Tuning.Gann
--   let f = d12_midi_tuning_f (la_monte_young,-74.7,-3)
--   octpc_to_midi (-1,11) == 11
--   map (round . midi_detune_to_cps . f) [62,63,69] == [293,298,440]
--   
d12_midi_tuning_f :: D12_Midi_Tuning -> Midi_Tuning_F -- | (t,f0,k) where t=tuning, f0=fundamental frequency, k=midi note number -- for f0, n=gamut type CPS_Midi_Tuning = (Tuning, Double, Int, Int) -- | Midi_Tuning_F for CPS_Midi_Tuning. cps_midi_tuning_f :: CPS_Midi_Tuning -> Midi_Tuning_F instance Eq Tuning instance Show Tuning -- | Clarence Barlow. "Two Essays on Theory". Computer Music -- Journal, 11(1):44-60, 1987. Translated by Henning Lohner. module Music.Theory.Interval.Barlow_1987 -- | Barlow's indigestibility function for prime numbers. -- --
--   map barlow [1,2,3,5,7,11,13] == [0,1,8/3,32/5,72/7,200/11,288/13]
--   
barlow :: (Integral a, Fractional b) => a -> b -- | Generate list of factors of n from x. -- --
--   factor primes 315 == [3,3,5,7]
--   
factor :: Integral a => [a] -> a -> [a] -- | factor n from primes. -- --
--   prime_factors 315 == [3,3,5,7]
--   
prime_factors :: Integral a => a -> [a] -- | Collect number of occurences of each element of a sorted list. -- --
--   multiplicities [1,1,1,2,2,3] == [(1,3),(2,2),(3,1)]
--   
multiplicities :: (Eq a, Integral n) => [a] -> [(a, n)] -- | multiplicities . prime_factors. -- --
--   prime_factors_m 315 == [(3,2),(5,1),(7,1)]
--   
prime_factors_m :: Integral a => a -> [(a, a)] -- | Merging function for rational_prime_factors_m. merge :: (Ord a, Num b, Eq b) => [(a, b)] -> [(a, b)] -> [(a, b)] -- | Collect the prime factors in a rational number given as a numerator/ -- denominator pair (n,m). Prime factors are listed in ascending order -- with their positive or negative multiplicities, depending on whether -- the prime factor occurs in the numerator or the denominator (after -- cancelling out common factors). -- --
--   rational_prime_factors_m (16,15) == [(2,4),(3,-1),(5,-1)]
--   rational_prime_factors_m (10,9) == [(2,1),(3,-2),(5,1)]
--   rational_prime_factors_m (81,64) == [(2,-6),(3,4)]
--   rational_prime_factors_m (27,16) == [(2,-4),(3,3)]
--   rational_prime_factors_m (12,7) == [(2,2),(3,1),(7,-1)]
--   
rational_prime_factors_m :: Integral b => (b, b) -> [(b, b)] -- | Variant of rational_prime_factors_m giving results in a table -- up to the nth prime. -- --
--   rational_prime_factors_t 6 (12,7) == [2,1,0,-1,0,0]
--   
rational_prime_factors_t :: Integral b => Int -> (b, b) -> [b] -- | Compute the disharmonicity of the interval (p,q) using the -- prime valuation function pv. -- --
--   map (disharmonicity barlow) [(9,10),(8,9)] ~= [12.733333,8.333333]
--   
disharmonicity :: (Integral a, Num b) => (a -> b) -> (a, a) -> b -- | The reciprocal of disharmonicity. -- --
--   map (harmonicity barlow) [(9,10),(8,9)] ~= [0.078534,0.120000]
--   
harmonicity :: (Integral a, Fractional b) => (a -> b) -> (a, a) -> b -- | Variant of harmonicity with Ratio input. harmonicity_r :: (Integral a, Fractional b) => (a -> b) -> Ratio a -> b -- | uncurry (%). to_rational :: Integral a => (a, a) -> Ratio a -- | Make numerator denominator pair of n. from_rational :: Integral t => Ratio t -> (t, t) -- | Set of 1. interval size (cents), 2. intervals as product of powers of -- primes, 3. frequency ratio and 4. harmonicity value. type Table_2_Row = (Double, [Integer], Rational, Double) -- | Table 2 (p.45) -- --
--   length (table_2 0.06) == 24
--   
table_2 :: Double -> [Table_2_Row] -- | Pretty printer for Table_2_Row values. -- --
--   mapM_ (putStrLn . table_2_pp) (table_2 0.06)
--   
-- --
--      0.000 |  0  0  0  0  0  0 |  1:1  | Infinity
--    111.731 |  4 -1 -1  0  0  0 | 15:16 | 0.076531
--    182.404 |  1 -2  1  0  0  0 |  9:10 | 0.078534
--    203.910 | -3  2  0  0  0  0 |  8:9  | 0.120000
--    231.174 |  3  0  0 -1  0  0 |  7:8  | 0.075269
--    266.871 | -1 -1  0  1  0  0 |  6:7  | 0.071672
--    294.135 |  5 -3  0  0  0  0 | 27:32 | 0.076923
--    315.641 |  1  1 -1  0  0  0 |  5:6  | 0.099338
--    386.314 | -2  0  1  0  0  0 |  4:5  | 0.119048
--    407.820 | -6  4  0  0  0  0 | 64:81 | 0.060000
--    435.084 |  0  2  0 -1  0  0 |  7:9  | 0.064024
--    498.045 |  2 -1  0  0  0  0 |  3:4  | 0.214286
--    519.551 | -2  3 -1  0  0  0 | 20:27 | 0.060976
--    701.955 | -1  1  0  0  0  0 |  2:3  | 0.272727
--    764.916 |  1 -2  0  1  0  0 |  9:14 | 0.060172
--    813.686 |  3  0 -1  0  0  0 |  5:8  | 0.106383
--    884.359 |  0 -1  1  0  0  0 |  3:5  | 0.110294
--    905.865 | -4  3  0  0  0  0 | 16:27 | 0.083333
--    933.129 |  2  1  0 -1  0  0 |  7:12 | 0.066879
--    968.826 | -2  0  0  1  0  0 |  4:7  | 0.081395
--    996.090 |  4 -2  0  0  0  0 |  9:16 | 0.107143
--   1017.596 |  0  2 -1  0  0  0 |  5:9  | 0.085227
--   1088.269 | -3  1  1  0  0  0 |  8:15 | 0.082873
--   1200.000 |  1  0  0  0  0  0 |  1:2  | 1.000000
--   
table_2_pp :: Table_2_Row -> String -- | Bill Alves. module Music.Theory.Tuning.Alves -- | Ratios for harrison_ditone. -- --
--   let c = [0,114,204,294,408,498,612,702,816,906,996,1110]
--   in map (round . ratio_to_cents) harrison_ditone_r == c
--   
harrison_ditone_r :: [Rational] -- | Ditone/pythagorean tuning, see -- http://www.billalves.com/porgitaro/ditonesettuning.html -- --
--   cents_i harrison_ditone == [0,114,204,294,408,498,612,702,816,906,996,1110]
--   
harrison_ditone :: Tuning -- | Bill Alves. "Pleng: Composing for a Justly Tuned Gender Barung". 1/1: -- Journal of the Just Intonation Network, 1:4-11, Spring 1997. -- http://www2.hmc.edu/~alves/pleng.html module Music.Theory.Tuning.Alves_1997 alves_slendro_r :: [Rational] -- | HMC slendro tuning. -- --
--   cents_i alves_slendro == [0,231,498,765,996]
--   
alves_slendro :: Tuning alves_pelog_bem_r :: [Rational] -- | HMC pelog bem tuning. -- --
--   cents_i alves_pelog_bem == [0,231,316,702,814]
--   
alves_pelog_bem :: Tuning alves_pelog_barang_r :: [Rational] -- | HMC pelog 2,3,4,6,7 tuning. -- --
--   cents_i alves_pelog_barang == [0,386,471,857,969]
--   
alves_pelog_barang :: Tuning alves_pelog_23467_r :: [Rational] -- | HMC pelog barang tuning. -- --
--   cents_i alves_pelog_23467 == [0,386,471,702,969]
--   
alves_pelog_23467 :: Tuning -- | Kyle Gann. module Music.Theory.Tuning.Gann -- | Cents for pietro_aaron_1523. -- --
--   let c = [0,76,193,310,386,503,580,697,773,890,1007,1083]
--   in map round pietro_aaron_1523_c == c
--   
pietro_aaron_1523_c :: [Cents] -- | Pietro Aaron (1523) meantone temperament, see -- http://www.kylegann.com/histune.html -- --
--   cents_i pietro_aaron_1523 == [0,76,193,310,386,503,580,697,773,890,1007,1083]
--   
pietro_aaron_1523 :: Tuning -- | Andreas Werckmeister (1645-1706), -- http://www.kylegann.com/histune.html. werckmeister_iii_c :: [Cents] -- | Cents for thomas_young_1799. -- --
--   let c = [0,94,196,298,392,500,592,698,796,894,1000,1092]
--   in map round thomas_young_1799_c == c
--   
thomas_young_1799_c :: [Cents] -- | Thomas Young (1799), Well Temperament, -- http://www.kylegann.com/histune.html. -- --
--   cents_i thomas_young_1799 == [0,94,196,298,392,500,592,698,796,894,1000,1092]
--   
thomas_young_1799 :: Tuning -- | Ratios for zarlino. zarlino_r :: [Rational] -- | Gioseffo Zarlino, 1588, see -- http://www.kylegann.com/tuning.html. -- --
--   divisions zarlino == 16
--   cents_i zarlino == [0,71,182,204,294,316,386,498,569,590,702,773,884,996,1018,1088]
--   
zarlino :: Tuning -- | Ratios for la_monte_young. -- --
--   let c = [0,177,204,240,471,444,675,702,738,969,942,1173]
--   in map (round . ratio_to_cents) la_monte_young_r == c
--   
la_monte_young_r :: [Rational] -- | La Monte Young's "The Well-Tuned Piano", see -- http://www.kylegann.com/wtp.html. -- --
--   cents_i la_monte_young == [0,177,204,240,471,444,675,702,738,969,942,1173]
--   
la_monte_young :: Tuning -- | Ratios for ben_johnston. -- --
--   let c = [0,105,204,298,386,471,551,702,841,906,969,1088]
--   in map (round . ratio_to_cents) ben_johnston_r == c
--   
ben_johnston_r :: [Rational] -- | Ben Johnston's "Suite for Microtonal Piano" (1977), see -- http://www.kylegann.com/tuning.html -- --
--   cents_i ben_johnston == [0,105,204,298,386,471,551,702,841,906,969,1088]
--   
ben_johnston :: Tuning -- | Ratios for gann_arcana_xvi. gann_arcana_xvi_r :: [Rational] -- | Kyle Gann, _Arcana XVI_, see -- http://www.kylegann.com/Arcana.html. -- --
--   let r = [0,84,112,204,267,316,347,386,471,498,520,583,663,702,734,814,845,884,898,969,1018,1049,1088,1161]
--   in cents_i gann_arcana_xvi == r
--   
gann_arcana_xvi :: Tuning -- | Ratios for gann_superparticular. gann_superparticular_r :: [Rational] -- | Kyle Gann, _Superparticular_, see -- http://www.kylegann.com/Super.html. -- --
--   divisions gann_superparticular == 22
--   
-- --
--   let r = [0,165,182,204,231,267,316,386,435,498,551,583,617,702,782,765,814,884,933,969,996,1018]
--   in cents_i gann_superparticular == r
--   
gann_superparticular :: Tuning -- | Max Meyer. "The musician's arithmetic: drill problems for an -- introduction to the scientific study of musical composition." The -- University of Missouri, 1929. p.22 module Music.Theory.Tuning.Meyer_1929 -- | Odd numbers to n. -- --
--   odd_to 7 == [1,3,5,7]
--   
odd_to :: (Num t, Enum t) => t -> [t] -- | Generate initial row for n. -- --
--   row 7 == [1,5/4,3/2,7/4]
--   
row :: Integral i => i -> [Ratio i] -- | Generate initial column for n. -- --
--   column 7 == [1,8/5,4/3,8/7]
--   
column :: Integral i => i -> [Ratio i] -- | fold_to_octave . *. in_oct_mul :: Integral i => Ratio i -> Ratio i -> Ratio i -- | Given row and column generate matrix value at -- (i,j). -- --
--   inner (row 7,column 7) (1,2) == 6/5
--   
inner :: Integral i => ([Ratio i], [Ratio i]) -> (i, i) -> Ratio i meyer_table_rck :: Integral i => i -> ([Ratio i], [Ratio i], i) -- | Meyer table in form (r,c,n). -- --
--   meyer_table_indices 7 == [(0,0,1/1),(0,1,5/4),(0,2,3/2),(0,3,7/4)
--                            ,(1,0,8/5),(1,1,1/1),(1,2,6/5),(1,3,7/5)
--                            ,(2,0,4/3),(2,1,5/3),(2,2,1/1),(2,3,7/6)
--                            ,(3,0,8/7),(3,1,10/7),(3,2,12/7),(3,3,1/1)]
--   
meyer_table_indices :: Integral i => i -> [(i, i, Ratio i)] -- | Meyer table as set of rows. -- --
--   meyer_table_rows 7 == [[1/1, 5/4, 3/2,7/4]
--                         ,[8/5, 1/1, 6/5,7/5]
--                         ,[4/3, 5/3, 1/1,7/6]
--                         ,[8/7,10/7,12/7,1/1]]
--   
-- --
--   let r = [[ 1/1,   9/8,   5/4,  11/8,   3/2,  13/8,   7/4,  15/8]
--           ,[16/9,   1/1,  10/9,  11/9,   4/3,  13/9,  14/9,   5/3]
--           ,[ 8/5,   9/5,   1/1,  11/10,  6/5,  13/10,  7/5,   3/2]
--           ,[16/11, 18/11, 20/11,  1/1,  12/11, 13/11, 14/11, 15/11]
--           ,[ 4/3,   3/2,   5/3,  11/6,   1/1,  13/12,  7/6,   5/4]
--           ,[16/13, 18/13, 20/13, 22/13, 24/13,  1/1,  14/13, 15/13]
--           ,[ 8/7,   9/7,   10/7, 11/7,  12/7,  13/7,   1/1,  15/14]
--           ,[16/15,  6/5,    4/3, 22/15,  8/5,  26/15, 28/15,  1/1]]
--   in meyer_table_rows 15 == r
--   
meyer_table_rows :: Integral a => a -> [[Ratio a]] -- | Third element of three-tuple. t3_3 :: (t1, t2, t3) -> t3 -- | Set of unique ratios in n table. -- --
--   elements 7 == [1,8/7,7/6,6/5,5/4,4/3,7/5,10/7,3/2,8/5,5/3,12/7,7/4]
--   
-- --
--   elements 9 == [1,10/9,9/8,8/7,7/6,6/5,5/4,9/7,4/3,7/5,10/7
--                 ,3/2,14/9,8/5,5/3,12/7,7/4,16/9,9/5]
--   
elements :: Integral i => i -> [Ratio i] -- | Number of unique elements at n table. -- --
--   map degree [7,9,11,13,15] == [13,19,29,41,49]
--   
degree :: Integral i => i -> i -- | http://en.wikipedia.org/wiki/Farey_sequence -- --
--   let r = [[0,1/2,1]
--           ,[0,1/3,1/2,2/3,1]
--           ,[0,1/4,1/3,1/2,2/3,3/4,1]
--           ,[0,1/5,1/4,1/3,2/5,1/2,3/5,2/3,3/4,4/5,1]
--           ,[0,1/6,1/5,1/4,1/3,2/5,1/2,3/5,2/3,3/4,4/5,5/6,1]]
--   in map farey_sequence [2..6] == r
--   
farey_sequence :: Integral a => a -> [Ratio a] -- | http://www.microtonal-synthesis.com/scales.html module Music.Theory.Tuning.Microtonal_Synthesis -- | Ratios for pythagorean. -- --
--   let c = [0,90,204,294,408,498,612,702,792,906,996,1110]
--   in map (round . ratio_to_cents) pythagorean_r == c
--   
pythagorean_r :: [Rational] -- | Pythagorean tuning, -- http://www.microtonal-synthesis.com/scale_pythagorean.html. -- --
--   divisions pythagorean == 12
--   cents_i pythagorean == [0,90,204,294,408,498,612,702,792,906,996,1110]
--   
pythagorean :: Tuning -- | Ratios for five_limit_tuning. -- --
--   let c = [0,112,204,316,386,498,590,702,814,884,996,1088]
--   in map (round . ratio_to_cents) five_limit_tuning_r == c
--   
five_limit_tuning_r :: [Rational] -- | Five-limit tuning (five limit just intonation). -- --
--   cents_i five_limit_tuning == [0,112,204,316,386,498,590,702,814,884,996,1088]
--   
five_limit_tuning :: Tuning -- | Ratios for septimal_tritone_just_intonation. -- --
--   let c = [0,112,204,316,386,498,583,702,814,884,1018,1088]
--   in map (round . ratio_to_cents) septimal_tritone_just_intonation == c
--   
septimal_tritone_just_intonation_r :: [Rational] -- | Septimal tritone Just Intonation, see -- http://www.microtonal-synthesis.com/scale_just_intonation.html -- --
--   cents_i septimal_tritone_just_intonation == [0,112,204,316,386,498,583,702,814,884,1018,1088]
--   
septimal_tritone_just_intonation :: Tuning -- | Ratios for seven_limit_just_intonation. -- --
--   let c = [0,112,204,316,386,498,583,702,814,884,969,1088]
--   in map (round . ratio_to_cents) seven_limit_just_intonation == c
--   
seven_limit_just_intonation_r :: [Rational] -- | Seven limit Just Intonation. -- --
--   cents_i seven_limit_just_intonation == [0,112,204,316,386,498,583,702,814,884,969,1088]
--   
seven_limit_just_intonation :: Tuning -- | Approximate ratios for kirnberger_iii. -- --
--   let c = [0,90,193,294,386,498,590,697,792,890,996,1088]
--   in map (round.to_cents) kirnberger_iii_ar == c
--   
kirnberger_iii_ar :: [Approximate_Ratio] -- | http://www.microtonal-synthesis.com/scale_kirnberger.html. -- --
--   cents_i kirnberger_iii == [0,90,193,294,386,498,590,697,792,890,996,1088]
--   
kirnberger_iii :: Tuning vallotti_c :: [Cents] -- | Vallotti & Young scale (Vallotti version), see -- http://www.microtonal-synthesis.com/scale_vallotti_young.html. -- --
--   cents_i vallotti == [0,94,196,298,392,502,592,698,796,894,1000,1090]
--   
vallotti :: Tuning mayumi_reinhard_r :: [Rational] -- | Mayumi Reinhard 13-limit Just Intonation scale, -- http://www.microtonal-synthesis.com/scale_reinhard.html. -- --
--   cents_i mayumi_reinhard == [0,128,139,359,454,563,637,746,841,911,1072,1183]
--   
mayumi_reinhard :: Tuning -- | Ratios for lou_harrison_16. -- --
--   length lou_harrison_16_r == 16
--   
-- --
--   let c = [0,112,182,231,267,316,386,498,603,702,814,884,933,969,1018,1088]
--   in map (round . ratio_to_cents) lou_harrison_16_r == c
--   
lou_harrison_16_r :: [Rational] -- | Lou Harrison 16 tone Just Intonation scale, see -- http://www.microtonal-synthesis.com/scale_harrison_16.html -- --
--   let r = [0,112,182,231,267,316,386,498,603,702,814,884,933,969,1018,1088]
--   in cents_i lou_harrison_16 == r
--   
lou_harrison_16 :: Tuning -- | Ratios for partch_43. partch_43_r :: [Rational] -- | Harry Partch 43 tone scale, see -- http://www.microtonal-synthesis.com/scale_partch.html -- --
--   cents_i partch_43 == [0,22,53,84,112,151,165
--                        ,182,204,231,267,294,316
--                        ,347,386,418,435
--                        ,471,498,520,551,583,617,649
--                        ,680,702,729,765,782,814,853,884,906,933
--                        ,969,996,1018,1035,1049,1088,1116,1147,1178]
--   
partch_43 :: Tuning -- | Ratios for ben_johnston_25. ben_johnston_25_r :: [Rational] -- | Ben Johnston 25 note just enharmonic scale, see -- http://www.microtonal-synthesis.com/scale_johnston_25.html ben_johnston_25 :: Tuning -- | Larry Polansky. "Psaltery (for Lou Harrison)". Frog Peak Music, 1978. module Music.Theory.Tuning.Polansky_1978 -- | Three interlocking harmonic series on 1:5:3, by Larry Polansky in -- "Psaltery". -- --
--   import qualified Music.Theory.Tuning.Scala as T
--   let fn = "/home/rohan/opt/scala/scl/polansky_ps.scl"
--   s <- T.load fn
--   T.scale_pitch_representations s == (0,50)
--   1 : Data.Either.rights (T.scale_pitches s) == psaltery
--   
psaltery :: [Rational] -- | fold_ratio_to_octave of psaltery. -- --
--   length psaltery == 51 && length psaltery_o == 21
--   psaltery_o == [1,65/64,33/32,17/16,35/32,9/8,75/64,39/32
--                 ,5/4,21/16,85/64,11/8,45/32
--                 ,3/2,25/16,51/32,13/8,27/16,55/32,7/4,15/8]
--   
psaltery_o :: [Rational] -- | Larry Polansky. "Tuning Systems in American Gamelan, Part I: Interval -- Sizes in Javanese Slendro". Balungan, 1(2):9-11, 1984 module Music.Theory.Tuning.Polansky_1984 k_manisrenga :: Fractional n => [n] k_kanjutmesem :: Fractional n => [n] k_udanriris :: Fractional n => [n] k_pengawesari :: Fractional n => [n] k_rarasrum :: Fractional n => [n] k_hardjanagara :: Fractional n => [n] k_madukentir :: Fractional n => [n] k_surak :: Fractional n => [n] -- | The set of K slendro tunings. -- --
--   map length k_set == replicate (length k_set) 5
--   minimum (concat k_set) == 206
--   maximum (concat k_set) == 268.5
--   
k_set :: Fractional n => [[n]] -- | Given a set of equal length lists calculate the average value of each -- position. -- --
--   calculate_averages [[1,2,3],[3,2,1]] == [2,2,2]
--   
calculate_averages :: Fractional n => [[n]] -> [n] -- | Averages of K set, p. 10. -- --
--   k_averages == [233.8125,245.0625,234.0,240.8125,251.875]
--   
k_averages :: Fractional n => [n] gm_1 :: Fractional n => [n] gm_8 :: Fractional n => [n] gm_7 :: Fractional n => [n] gm_6 :: Fractional n => [n] gm_5 :: Fractional n => [n] gm_4 :: Fractional n => [n] gm_3 :: Fractional n => [n] gm_2 :: Fractional n => [n] -- | The set of GM (Gadja Mada University) slendro tunings. -- --
--   map length gm_set == replicate (length gm_set) 5
--   minimum (concat gm_set) == 218
--   maximum (concat gm_set) == 262
--   
gm_set :: Fractional n => [[n]] -- | Averages of GM set, p. 10. -- --
--   gm_averages == [234.0,240.25,247.625,243.125,254.0625]
--   
gm_averages :: Fractional n => [n] -- | Association list giving interval boundaries for interval class -- categories (pp.10-11). i_categories :: Num n => [((n, n), String)] -- | Categorise an interval. i_category :: (Ord a, Num a) => a -> String -- | Pad String to right with spaces until at least n -- characters. -- --
--   map (pad 3) ["S","E-L"] == ["S  ","E-L"]
--   
pad :: Int -> String -> String -- | Pretty interval category table (pp. 10-11). -- --
--   i_category_table k_set ==
--    ["S    L    S    S    L  "
--    ,"S    L    S    S    L  "
--    ,"L    L    S    S    S  "
--    ,"L    S    S    S    L  "
--    ,"S    S    L    S    L  "
--    ,"S    E-L  S    L    L  "
--    ,"L    E    E    S    S  "
--    ,"S    S    S-E  L    L  "]
--   
-- --
--   i_category_table gm_set ==
--    ["S    L    E-L  E    L  "
--    ,"L    S-E  E    S    L  "
--    ,"S    S-E  S    L    S-E"
--    ,"S    L    L    S    L  "
--    ,"S    S-E  E-L  S    L  "
--    ,"S    S-E  E    E    L  "
--    ,"S-E  S    L    E    L  "
--    ,"S    S    E-L  L    L  "]
--   
i_category_table :: (Ord a, Num a) => [[a]] -> [String] -- | Rational tuning derived from gm_averages, p.11. -- --
--   polansky_1984_r == sort polansky_1984_r
--   polansky_1984_r == [1/1,8/7,21/16,512/343,12/7,96/49]
--   
-- --
--   import Music.Theory.List
--   d_dx polansky_1984_r == [1/7,19/112,989/5488,76/343,12/49]
--   
polansky_1984_r :: [Rational] -- | ratio_to_cents of polansky_1984_r. -- --
--   import Music.Theory.List
--   map round (d_dx polansky_1984_c) == [231,240,223,240,231]
--   
polansky_1984_c :: [Cents] -- | Larry Polansky. "Notes on Piano Study #5". _1/1, The Journal of the -- Just Intonation Newtork_, 1(4), Autumn 1985. module Music.Theory.Tuning.Polansky_1985c -- | The tuning has four octaves, these ratios are per-octave. ps5_jpr_r :: [[Rational]] -- | Four-octave tuning. -- --
--   import Data.List.Split
--   
-- --
--   let r = [[   0,  84, 204, 316, 386, 498, 583, 702, 814, 884, 969,1088]
--           ,[1200,1284,1404,1516,1586,1698,1783,1902,2014,2084,2169,2288]
--           ,[2400,2453,2604,2716,2786,2871,2951,3102,3214,3241,3369,3488]
--           ,[3600,3684,3804,3867,3986,4098,4151,4302,4414,4506,4569,4688]]
--   in chunksOf 12 (cents_i ps5_jpr) == r
--   
-- --
--   let r = [[0,84,204,316,386,498,583,702,814,884,969,1088]
--           ,[0,84,204,316,386,498,583,702,814,884,969,1088]
--           ,[0,53,204,316,386,471,551,702,814,841,969,1088]
--           ,[0,84,204,267,386,498,551,702,814,906,969,1088]]
--   chunksOf 12 (map (`mod` 1200) (cents_i ps5_jpr))
--   
ps5_jpr :: Tuning -- | Terry Riley. module Music.Theory.Tuning.Riley -- | Ratios for riley_albion. -- --
--   let r = [0,112,204,316,386,498,610,702,814,884,996,1088]
--   in map (round . ratio_to_cents) riley_albion_r == r
--   
riley_albion_r :: [Rational] -- | Riley's five-limit tuning as used in _The Harp of New Albion_, see -- http://www.ex-tempore.org/Volx1/hudson/hudson.htm. -- --
--   cents_i riley_albion == [0,112,204,316,386,498,610,702,814,884,996,1088]
--   
riley_albion :: Tuning -- | Parser for the Scala scale file format. See -- http://www.huygens-fokker.org/scala/scl_format.html for -- details. This module succesfully parses all 4496 scales in v.81 of the -- scale library. module Music.Theory.Tuning.Scala -- | A .scl pitch is either in Cents or is a -- Ratio. type Pitch i = Either Cents (Ratio i) -- | A scale has a description, a degree, and a list of Pitches. type Scale i = (String, i, [Pitch i]) -- | Text description of scale. scale_description :: Scale i -> String -- | The degree of the scale (number of Pitches). scale_degree :: Scale i -> i -- | The Pitches at Scale. scale_pitches :: Scale i -> [Pitch i] -- | The last Pitch element of the scale (ie. the ocatve). scale_octave :: Scale i -> Maybe (Pitch i) -- | Is scale_octave perfect, ie. Ratio of 2 or -- Cents of 1200. perfect_octave :: Integral i => Scale i -> Bool -- | A pair giving the number of Cents and number of Ratio -- pitches at Scale. scale_pitch_representations :: Integral t => Scale i -> (t, t) -- | Pitch as Cents, conversion by to_cents_r if necessary. pitch_cents :: Pitch Integer -> Cents type Epsilon = Double -- | Pitch as Rational, conversion by reconstructed_ratio if -- necessary, hence epsilon. pitch_ratio :: Epsilon -> Pitch Integer -> Rational -- | Make scale pitches uniform, conforming to the most promininent pitch -- type. scale_uniform :: Epsilon -> Scale Integer -> Scale Integer -- | Scale as list of Cents (ie. pitch_cents) with 0 -- prefix. scale_cents :: Scale Integer -> [Cents] -- | Scale as list of Rational (ie. pitch_ratio) with -- 1 prefix. scale_ratios :: Epsilon -> Scale Integer -> [Rational] -- | Comment lines being with !. comment_p :: String -> Bool -- | Remove r. filter_cr :: String -> String -- | Logical or of list of predicates. p_or :: [a -> Bool] -> a -> Bool -- | Remove to end of line ! comments. remove_eol_comments :: String -> String -- | Remove comments and null lines. -- --
--   filter_comments ["!a","b","","c"] == ["b","c"]
--   
filter_comments :: [String] -> [String] -- | Delete trailing ., read fails for 700.. delete_trailing_point :: String -> String -- | Pitches are either cents (with decimal point) or ratios (with -- /). -- --
--   map pitch ["700.0","3/2","2"] == [Left 700,Right (3/2),Right 2]
--   
pitch :: (Read i, Integral i) => String -> Pitch i -- | Pitch lines may contain commentary. pitch_ln :: (Read i, Integral i) => String -> Pitch i -- | Parse .scl file. parse :: (Read i, Integral i) => String -> Scale i -- | Load .scl file. -- --
--   s <- load "/home/rohan/data/scala/81/scl/xenakis_chrom.scl"
--   scale_pitch_representations s == (6,1)
--   scale_ratios 1e-3 s == [1,21/20,29/23,179/134,280/187,11/7,100/53,2]
--   
load :: (Read i, Integral i) => FilePath -> IO (Scale i) -- | Subset of files in dir with an extension in ext. dir_subset :: [String] -> FilePath -> IO [FilePath] -- | Load all .scl files at dir. -- --
--   db <- load_dir "/home/rohan/data/scala/81/scl"
--   length db == 4496
--   length (filter ((== 0) . scale_degree) db) == 0
--   length (filter (== Just (Right 2)) (map scale_octave db)) == 3855
--   
-- --
--   let r = [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
--           ,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44
--           ,45,46,47,48,49,50,51,53,54,55,56,57,58,59,60,61,62,63,64
--           ,65,66,67,68,69,70,71,72,74,75,77,78,79,80,81,84,87,88
--           ,90,91,92,95,96,99,100,101,105,110,112,117,118,130,140,171
--           ,180,271,311,342,366,441,612]
--   in nub (sort (map scale_degree db)) == r
--   
-- --
--   let r = ["Xenakis's Byzantine Liturgical mode, 5 + 19 + 6 parts"
--           ,"Xenakis's Byzantine Liturgical mode, 12 + 11 + 7 parts"
--           ,"Xenakis's Byzantine Liturgical mode, 7 + 16 + 7 parts"]
--   in filter (isInfixOf "Xenakis") (map scale_description db) == r
--   
-- --
--   length (filter (not . perfect_octave) db) == 544
--   
-- --
--   mapM_ (putStrLn.scale_description) (filter (not . perfect_octave) db)
--   
load_dir :: (Read i, Integral i) => FilePath -> IO [Scale i] -- | Syntonic tuning. module Music.Theory.Tuning.Syntonic -- | Construct an isomorphic layout of r rows and c columns -- with an upper left value of (i,j). mk_isomorphic_layout :: Integral a => a -> a -> (a, a) -> [[(a, a)]] -- | A minimal isomorphic note layout. -- --
--   let [i,j,k] = mk_isomorphic_layout 3 5 (3,-4)
--   in [i,take 4 j,(2,-4):take 4 k] == minimal_isomorphic_note_layout
--   
minimal_isomorphic_note_layout :: [[(Int, Int)]] -- | Make a rank two regular temperament from a list of (i,j) -- positions by applying the scalars a and b. rank_two_regular_temperament :: Integral a => a -> a -> [(a, a)] -> [a] -- | Syntonic tuning system based on mk_isomorphic_layout of -- 5 rows and 7 columns starting at (3,-4) and -- a rank_two_regular_temperament with a of 1200 -- and indicated b. mk_syntonic_tuning :: Int -> [Cents] -- | mk_syntonic_tuning of 697. -- --
--   divisions syntonic_697 == 17
--   
-- --
--   let c = [0,79,194,273,309,388,467,503,582,697,776,812,891,970,1006,1085,1164]
--   in cents_i syntonic_697 == c
--   
syntonic_697 :: Tuning -- | mk_syntonic_tuning of 702. -- --
--   divisions syntonic_702 == 17
--   
-- --
--   let c = [0,24,114,204,294,318,408,498,522,612,702,792,816,906,996,1020,1110]
--   in cents_i syntonic_702 == c
--   
syntonic_702 :: Tuning -- | Andreas Werckmeister (1645-1706). module Music.Theory.Tuning.Werckmeister -- | Approximate ratios for werckmeister_iii. -- --
--   let c = [0,90,192,294,390,498,588,696,792,888,996,1092]
--   in map (round . ratio_to_cents) werckmeister_iii_ar == c
--   
werckmeister_iii_ar :: [Approximate_Ratio] -- | Cents for werckmeister_iii. werckmeister_iii_ar_c :: [Cents] -- | Werckmeister III, Andreas Werckmeister (1645-1706) -- --
--   cents_i werckmeister_iii == [0,90,192,294,390,498,588,696,792,888,996,1092]
--   
werckmeister_iii :: Tuning -- | Approximate ratios for werckmeister_iv. -- --
--   let c = [0,82,196,294,392,498,588,694,784,890,1004,1086]
--   in map (round . ratio_to_cents) werckmeister_iv_ar == c
--   
werckmeister_iv_ar :: [Approximate_Ratio] -- | Cents for werckmeister_iv. werckmeister_iv_c :: [Cents] -- | Werckmeister IV, Andreas Werckmeister (1645-1706) -- --
--   cents_i werckmeister_iv == [0,82,196,294,392,498,588,694,784,890,1004,1086]
--   
werckmeister_iv :: Tuning -- | Approximate ratios for werckmeister_v. -- --
--   let c = [0,96,204,300,396,504,600,702,792,900,1002,1098]
--   in map (round . ratio_to_cents) werckmeister_v_ar == c
--   
werckmeister_v_ar :: [Approximate_Ratio] -- | Cents for werckmeister_v. werckmeister_v_c :: [Cents] -- | Werckmeister V, Andreas Werckmeister (1645-1706) -- --
--   cents_i werckmeister_v == [0,96,204,300,396,504,600,702,792,900,1002,1098]
--   
werckmeister_v :: Tuning -- | Ratios for werckmeister_vi. -- --
--   let c = [0,91,196,298,395,498,595,698,793,893,1000,1097]
--   in map (round . ratio_to_cents) werckmeister_vi_r == c
--   
werckmeister_vi_r :: [Rational] -- | Werckmeister VI, Andreas Werckmeister (1645-1706) -- --
--   cents_i werckmeister_vi == [0,91,196,298,395,498,595,698,793,893,1000,1097]
--   
werckmeister_vi :: Tuning -- | Larry Polansky. "Morphological Metrics". Journal of New Music -- Research, 25(4):289-368, 1996. module Music.Theory.Metric.Polansky_1996 -- | Distance function, ordinarily n below is in Num, -- Fractional or Real. type Interval a n = a -> a -> n -- | fromIntegral . -. dif_i :: (Integral a, Num b) => a -> a -> b -- | realToFrac . -. dif_r :: (Real a, Fractional b) => a -> a -> b -- | abs . f. abs_dif :: Num n => Interval a n -> a -> a -> n -- | Square. sqr :: Num a => a -> a -- | sqr . f. sqr_dif :: Num n => Interval a n -> a -> a -> n -- | sqr . abs . f. sqr_abs_dif :: Num n => Interval a n -> a -> a -> n -- | sqrt . abs . f. sqrt_abs_dif :: Floating c => Interval a c -> a -> a -> c -- | City block metric, p.296 -- --
--   city_block_metric (-) (1,2) (3,5) == 2+3
--   
city_block_metric :: Num n => Interval a n -> (a, a) -> (a, a) -> n -- | Two-dimensional euclidean metric, p.297. -- --
--   euclidean_metric_2 (-) (1,2) (3,5) == sqrt (4+9)
--   
euclidean_metric_2 :: Floating n => Interval a n -> (a, a) -> (a, a) -> n -- | n-dimensional euclidean metric -- --
--   euclidean_metric_l (-) [1,2] [3,5] == sqrt (4+9)
--   euclidean_metric_l (-) [1,2,3] [2,4,6] == sqrt (1+4+9)
--   
euclidean_metric_l :: Floating c => Interval b c -> [b] -> [b] -> c -- | Cube root. -- --
--   map cbrt [1,8,27] == [1,2,3]
--   
cbrt :: Floating a => a -> a -- | n-th root -- --
--   map (nthrt 4) [1,16,81] == [1,2,3]
--   
nthrt :: Floating a => a -> a -> a -- | Two-dimensional Minkowski metric, p.297 -- --
--   minkowski_metric_2 (-) 1 (1,2) (3,5) == 5
--   minkowski_metric_2 (-) 2 (1,2) (3,5) == sqrt (4+9)
--   minkowski_metric_2 (-) 3 (1,2) (3,5) == cbrt (8+27)
--   
minkowski_metric_2 :: Floating a => Interval t a -> a -> (t, t) -> (t, t) -> a -- | n-dimensional Minkowski metric -- --
--   minkowski_metric_l (-) 2 [1,2,3] [2,4,6] == sqrt (1+4+9)
--   minkowski_metric_l (-) 3 [1,2,3] [2,4,6] == cbrt (1+8+27)
--   
minkowski_metric_l :: Floating a => Interval t a -> a -> [t] -> [t] -> a -- | Integration with f. -- --
--   d_dx (-) [0,2,4,1,0] == [2,2,-3,-1]
--   d_dx (-) [2,3,0,4,1] == [1,-3,4,-3]
--   
d_dx :: Interval a n -> [a] -> [n] -- | map abs . d_dx. -- --
--   d_dx_abs (-) [0,2,4,1,0] == [2,2,3,1]
--   d_dx_abs (-) [2,3,0,4,1] == [1,3,4,3]
--   
d_dx_abs :: Num n => Interval a n -> [a] -> [n] -- | Ordered linear magnitude (no delta), p.300 -- --
--   olm_no_delta' [0,2,4,1,0] [2,3,0,4,1] == 1.25
--   
olm_no_delta' :: Fractional a => [a] -> [a] -> a -- | Ordered linear magintude (general form) p.302 -- --
--   olm_general (abs_dif (-)) [0,2,4,1,0] [2,3,0,4,1] == 1.25
--   olm_general (abs_dif (-)) [1,5,12,2,9,6] [7,6,4,9,8,1] == 4.6
--   
olm_general :: (Fractional a, Enum a, Fractional n) => Interval a n -> [a] -> [a] -> n -- | Delta (Δ) determines an interval given a sequence and an index. type Delta n a = [n] -> Int -> a -- | f at indices i and i+1 of x. -- --
--   map (ix_dif (-) [0,1,3,6,10]) [0..3] == [-1,-2,-3,-4]
--   
ix_dif :: Interval a t -> Delta a t -- | abs . ix_dif -- --
--   map (abs_ix_dif (-) [0,2,4,1,0]) [0..3] == [2,2,3,1]
--   
abs_ix_dif :: Num n => Interval a n -> Delta a n -- | sqr . abs_ix_dif -- --
--   map (sqr_abs_ix_dif (-) [0,2,4,1,0]) [0..3] == [4,4,9,1]
--   map (sqr_abs_ix_dif (-) [2,3,0,4,1]) [0..3] == [1,9,16,9]
--   
sqr_abs_ix_dif :: Num n => Interval a n -> Delta a n -- | Psi (Ψ) joins Delta equivalent intervals from -- morphologies m and n. type Psi a = a -> a -> a -- | Ordered linear magintude (generalised-interval form) p.305 -- --
--   olm (abs_dif dif_r) (abs_ix_dif dif_r) (const 1) [1,5,12,2,9,6] [7,6,4,9,8,1] == 4.6
--   olm (abs_dif dif_r) (abs_ix_dif dif_r) maximum [1,5,12,2,9,6] [7,6,4,9,8,1] == 0.46
--   
olm :: (Fractional a, Enum a) => Psi a -> Delta n a -> ([a] -> a) -> [n] -> [n] -> a olm_no_delta :: (Real a, Real n, Enum n, Fractional n) => [a] -> [a] -> n olm_no_delta_squared :: (Enum a, Floating a) => [a] -> [a] -> a second_order :: Num n => ([n] -> [n] -> t) -> [n] -> [n] -> t olm_no_delta_second_order :: (Real a, Enum a, Fractional a) => [a] -> [a] -> a olm_no_delta_squared_second_order :: (Enum a, Floating a) => [a] -> [a] -> a -- | Second order binomial coefficient, p.307 -- --
--   map second_order_binonial_coefficient [2..10] == [1,3,6,10,15,21,28,36,45]
--   
second_order_binonial_coefficient :: Fractional a => a -> a -- | d_dx of flip compare. -- --
--   direction_interval [5,9,3,2] == [LT,GT,GT]
--   direction_interval [2,5,6,6] == [LT,LT,EQ]
--   
direction_interval :: Ord i => [i] -> [Ordering] -- | Histogram of list of Orderings. -- --
--   ord_hist [LT,GT,GT] == (1,0,2)
--   
ord_hist :: Integral t => [Ordering] -> (t, t, t) -- | Histogram of directions of adjacent elements, p.312. -- --
--   direction_vector [5,9,3,2] == (1,0,2)
--   direction_vector [2,5,6,6] == (2,1,0)
--   
direction_vector :: Integral i => Ord a => [a] -> (i, i, i) -- | Unordered linear direction, p.311 (Fig. 5) -- --
--   uld [5,9,3,2] [2,5,6,6] == 2/3
--   uld [5,3,6,1,4] [3,6,1,4,2] == 0
--   
uld :: (Integral n, Ord a) => [a] -> [a] -> Ratio n -- | Ordered linear direction, p.312 -- --
--   direction_interval [5,3,6,1,4] == [GT,LT,GT,LT]
--   direction_interval [3,6,1,4,2] == [LT,GT,LT,GT]
--   old [5,3,6,1,4] [3,6,1,4,2] == 1
--   
old :: (Ord i, Integral a) => [i] -> [i] -> Ratio a -- | Ordered combinatorial direction, p.314 -- --
--   ocd [5,9,3,2] [2,5,6,6] == 5/6
--   ocd [5,3,6,1,4] [3,6,1,4,2] == 4/5
--   
ocd :: (Ord a, Integral i) => [a] -> [a] -> Ratio i -- | Unordered combinatorial direction, p.314 -- --
--   ucd [5,9,3,2] [2,5,6,6] == 5/6
--   ucd [5,3,6,1,4] [3,6,1,4,2] == 0
--   ucd [5,3,7,6] [2,1,2,1] == 1/2
--   ucd [2,1,2,1] [8,3,5,4] == 1/3
--   ucd [5,3,7,6] [8,3,5,4] == 1/3
--   
ucd :: (Integral n, Ord a) => [a] -> [a] -> Ratio n -- | half_matrix_f, Fig.9, p.318 -- --
--   let r = [[2,3,1,4]
--             ,[1,3,6]
--               ,[4,7]
--                 ,[3]]
--   in combinatorial_magnitude_matrix (abs_dif (-)) [5,3,2,6,9] == r
--   
combinatorial_magnitude_matrix :: Interval a n -> [a] -> [[n]] -- | Unordered linear magnitude (simplified), p.320-321 -- --
--   let r = abs (sum [5,4,3,6] - sum [12,2,11,7]) / 4
--   in ulm_simplified (abs_dif (-)) [1,6,2,5,11] [3,15,13,2,9] == r
--   
-- --
--   ulm_simplified (abs_dif (-)) [1,5,12,2,9,6] [7,6,4,9,8,1] == 3
--   
ulm_simplified :: Fractional n => Interval a n -> [a] -> [a] -> n ocm_zcm :: (Fractional n, Num a) => Interval a n -> [a] -> [a] -> (n, n, [n]) -- | Ordered combinatorial magnitude (OCM), p.323 -- --
--   ocm (abs_dif (-)) [1,6,2,5,11] [3,15,13,2,9] == 5.2
--   ocm (abs_dif (-)) [1,5,12,2,9,6] [7,6,4,9,8,1] == 3.6
--   
ocm :: (Fractional a, Enum a, Fractional n) => Interval a n -> [a] -> [a] -> n -- | Ordered combinatorial magnitude (OCM), p.323 -- --
--   ocm_absolute_scaled (abs_dif (-)) [1,6,2,5,11] [3,15,13,2,9] == 0.4
--   ocm_absolute_scaled (abs_dif (-)) [1,5,12,2,9,6] [7,6,4,9,8,1] == 54/(15*11)
--   
ocm_absolute_scaled :: (Ord a, Fractional a, Enum a, Ord n, Fractional n) => Interval a n -> [a] -> [a] -> n -- | Place notation (method ringing). -- -- Morris, R. G. T. "Place Notation" Central Council of Church Bell -- Ringers (1984). http://www.cccbr.org.uk/bibliography/ module Music.Theory.Permutations.Morris_1984 -- | A change either swaps all adjacent bells, or holds a subset of bells. data Change Swap_All :: Change Hold :: [Int] -> Change -- | A method is a sequence of changes, if symmetrical only have the -- changes are given and the lead end. data Method Method :: [Change] -> (Maybe Change) -> Method -- | Compete list of Changes at Method, writing out -- symmetries. method_changes :: Method -> [Change] -- | Parse a change notation. -- --
--   map parse_change ["-","x","38"] == [Swap_All,Swap_All,Hold [3,8]]
--   
parse_change :: String -> Change -- | Separate changes. -- --
--   split_changes "-38-14-1258-36-14-58-16-78"
--   split_changes "345.145.5.1.345" == ["345","145","5","1","345"]
--   
split_changes :: String -> [String] -- | Parse Method from the sequence of changes with possible lead -- end. -- --
--   parse_method ("-38-14-1258-36-14-58-16-78",Just "12")
--   
parse_method :: (String, Maybe String) -> Method is_swap_all :: String -> Bool -- | Swap elemets of two-tuple (pair). -- --
--   swap_pair (1,2) == (2,1)
--   
swap_pair :: (s, t) -> (t, s) -- | Flatten list of pairs. -- --
--   flatten_pairs [(1,2),(3,4)] == [1..4]
--   
flatten_pairs :: [(a, a)] -> [a] -- | Swap all adjacent pairs at list. -- --
--   swap_all [1 .. 8] == [2,1,4,3,6,5,8,7]
--   
swap_all :: [a] -> [a] -- | Parse abbreviated Hold notation, characters are hexedecimal. -- --
--   to_abbrev "38A" == [3,8,10]
--   
to_abbrev :: String -> [Int] -- | Given a Hold notation, generate permutation cycles. -- --
--   let r = [Right (1,2),Left 3,Right (4,5),Right (6,7),Left 8]
--   in gen_swaps 8 [3,8] == r
--   
-- --
--   let r = [Left 1,Left 2,Right (3,4),Right (5,6),Right (7,8)]
--   gen_swaps 8 [1,2] == r
--   
gen_swaps :: (Num t, Ord t) => t -> [t] -> [Either t (t, t)] -- | Two-tuple to two element list. pair_to_list :: (t, t) -> [t] -- | Swap notation to plain permutation cycles notation. -- --
--   let n = [Left 1,Left 2,Right (3,4),Right (5,6),Right (7,8)]
--   in swaps_to_cycles n == [[1],[2],[3,4],[5,6],[7,8]]
--   
swaps_to_cycles :: [Either t (t, t)] -> [[t]] -- | One-indexed permutation cycles to zero-indexed. -- --
--   let r = [[0],[1],[2,3],[4,5],[6,7]]
--   in to_zero_indexed [[1],[2],[3,4],[5,6],[7,8]] == r
--   
to_zero_indexed :: Enum t => [[t]] -> [[t]] -- | Apply abbreviated Hold notation, given cardinality. -- --
--   swap_abbrev 8 [3,8] [2,1,4,3,6,5,8,7] == [1,2,4,6,3,8,5,7]
--   
swap_abbrev :: Eq a => Int -> [Int] -> [a] -> [a] -- | Apply a Change. apply_change :: Eq a => Int -> Change -> [a] -> [a] -- | Apply a Method, gives next starting sequence and the course of -- the method. -- --
--   let r = ([1,2,4,5,3]
--           ,[[1,2,3,4,5],[2,1,3,4,5],[2,3,1,4,5],[3,2,4,1,5],[3,4,2,5,1]
--            ,[4,3,2,5,1],[4,2,3,1,5],[2,4,1,3,5],[2,1,4,3,5],[1,2,4,3,5]])
--   in apply_method cambridgeshire_slow_course_doubles [1..5] == r
--   
apply_method :: Eq a => Method -> [a] -> ([a], [[a]]) -- | Iteratively apply a Method until it closes (ie. arrives back at -- the starting sequence). -- --
--   length (closed_method cambridgeshire_slow_course_doubles [1..5]) == 3
--   
closed_method :: Eq a => Method -> [a] -> [[[a]]] -- | concat of closed_method with initial sequence appended. closed_method' :: Eq a => Method -> [a] -> [[a]] -- | Cambridgeshire Slow Course Doubles. -- -- -- https://rsw.me.uk/blueline/methods/view/Cambridgeshire_Slow_Course_Doubles -- --
--   length (closed_method cambridgeshire_slow_course_doubles [1..5]) == 3
--   
cambridgeshire_slow_course_doubles :: Method -- | Double Cambridge Cyclic Bob Minor. -- -- -- https://rsw.me.uk/blueline/methods/view/Double_Cambridge_Cyclic_Bob_Minor -- --
--   length (closed_method double_cambridge_cyclic_bob_minor [1..6]) == 5
--   
double_cambridge_cyclic_bob_minor :: Method -- | Hammersmith Bob Triples -- -- https://rsw.me.uk/blueline/methods/view/Hammersmith_Bob_Triples -- --
--   length (closed_method hammersmith_bob_triples [1..7]) == 6
--   
hammersmith_bob_triples :: Method -- | Cambridge Surprise Major. -- -- -- https://rsw.me.uk/blueline/methods/view/Cambridge_Surprise_Major -- --
--   length (closed_method cambridge_surprise_major [1..8]) == 7
--   
cambridge_surprise_major :: Method -- | Smithsonian Surprise Royal. -- -- -- https://rsw.me.uk/blueline/methods/view/Smithsonian_Surprise_Royal -- --
--   length (closed_method smithsonian_surprise_royal [1..10]) == 9
--   
smithsonian_surprise_royal :: Method instance Eq Change instance Show Change instance Eq Method instance Show Method -- | Bel(R) is a simplified form of the Bel notation -- described in: -- -- -- -- For patterns without tempo indications, the two notations should give -- equivalent phase diagrams, for instance (Bel 1990, §11, p.24): -- --
--   > bel_ascii_pp "ab{ab,cde}cd"
--   
--   Bel(R): "ab{ab,cde}cd", Dur: 7
--   
--   a _ b _ a _ _ b _ _ c _ d _
--           c _ d _ e _        
--   
-- -- and: -- --
--   > bel_ascii_pp "{a{bc,def},ghijk}"
--   
--   Bel(R): "{a{bc,def},ghijk}", Dur: 5
--   
--   a _ _ _ _ _ _ _ _ _ b _ _ _ _ _ _ _ _ _ _ _ _ _ _ c _ _ _ _ _ _ _ _ _ _ _ _ _ _
--                       d _ _ _ _ _ _ _ _ _ e _ _ _ _ _ _ _ _ _ f _ _ _ _ _ _ _ _ _
--   g _ _ _ _ _ _ _ h _ _ _ _ _ _ _ i _ _ _ _ _ _ _ j _ _ _ _ _ _ _ k _ _ _ _ _ _ _
--   
-- -- The Bel notation allows n-ary parallel structures, ie. -- {a_bcd_e,a_f_gh_,ji_a_i_} (Bel 1992, p.29), however -- Bel(R) allows only binary structures. The parallel -- interpretation rules are associative: -- --
--   > bel_ascii_pp "{a_bcd_e,{a_f_gh_,ji_a_i_}}"
--   
--   Bel(R): "{a_bcd_e,{a_f_gh_,ji_a_i_}}", Dur: 7
--   
--   a _ b c d _ e
--   a _ f _ g h _
--   j i _ a _ i _
--   
-- -- Bel(R) does allow unary parallel structures (see Iso), -- which can be used to isolate tempo changes: -- --
--   > bel_ascii_pp "ab{*2cd}ef{*2/3gh}ij"
--   
--   Bel(R): "ab{*2cd}ef{*2/3gh}ij", Dur: 10
--   
--   a _ b _ c d e _ f _ g _ _ h _ _ i _ j _
--   
-- -- Patterns with tempo indications have completely different meanings in -- Bel and Bel(R), though in both cases parallel nodes -- delimit the scope of tempo markings. -- -- Bel(R) replaces the /n notation for explicit tempo -- marks with a *n notation to indicate a tempo multiplier, and -- a set of bracketing notations to specify interpretation rules for -- parallel (concurrent) temporal structures. -- -- The tempo indication /1 in the expression -- ab{/1ab,cde}cd (Bel 1990, p.24) requires that the inner -- ab have the same tempo as the outer ab, which is -- implicitly /1. Setting the tempo of one part of a parallel -- structure requires assigning a tempo to the other part in order that -- the two parts have equal duration. Here the tempo assigned to -- cde is /1.5, but since fractional tempi are not -- allowed the expression is re-written as /2ab{/2ab,/3cde}/2cd. -- -- Importantly the explicit tempo indications make it possible to write -- syntactically correct expressions in Bel that do not have a -- coherent interpretation, ie. {/1ab,/1cde}. Determining if a -- coherent set of tempos can be assigned, and assigning these tempos, is -- the object of the interpretation system. -- -- In comparison, all syntactically valid Bel(R) strings have an -- interpretation. The expression {*1ab,*1cde} is trivially -- equal to {ab,cde}, and tempo marks in parallel parts do not -- interact: -- --
--   > bel_ascii_pp "{a*2b,*3c/2d/3e}"
--   
--   Bel(R): "{a*2b,*3c*1/2d*1/3e}", Dur: 3
--   
--   a _ _ _ _ _ b _ _
--   c d _ e _ _ _ _ _
--   
-- -- Here a is twice the duration of b, and e is -- three times the duration of d, which is twice the duration of -- c (in Bel(R) /n is equivalent to -- *1/n). The duration of any Bel(R) expression can be -- calculated directly, given an initial Tempo: -- --
--   bel_dur 1 (bel_char_parse "a*2b") == 3/2
--   bel_dur 1 (bel_char_parse "*3c/2d/3e") == 3
--   
-- -- Therefore in the composite expression the left part is slowed by a -- factor of two to align with the right part. -- -- The Bel string ab{/1ab,cde}cd can be re-written in -- Bel(R) as either ab~{ab,cde}cd or -- ab(ab,cde)cd. The absolute tempo indication is replaced by -- notations giving alternate modes of interpretation for the parallel -- structure. -- -- In the first case the ~ indicates the opposite of the -- normal rule for parallel nodes. The normal rule is the same as for -- Bel and is that the duration of the whole is equal to duration -- of the longer of the two parts. The ~ inverts this so that -- the whole has the duration of the shorter of the two parts, and the -- longer part is scaled to have equal duration. -- -- In the second case the parentheses () replacing the braces -- {} indicates that the duration of the whole is equal to the -- duration of the left side, and that the right is to be scaled. -- Similarly, a ~ preceding parentheses indicates the duration -- of the whole should be the duration of the right side, and the left -- scaled. -- --
--   > bel_ascii_pp "ab~{ab,cde}cd"
--   
--   Bel(R): "ab~{ab,cde}cd", Dur: 6
--   
--   a _ _ b _ _ a _ _ b _ _ c _ _ d _ _
--               c _ d _ e _            
--   
-- -- There is one other parallel mode that has no equivalent in Bel -- notation. It is a mode that does not scale either part, leaving a -- hole at the end of the shorter part, and is indicated by square -- brackets: -- --
--   > bel_ascii_pp "ab[ab,cde]cd"
--   
--   Bel(R): "ab[ab,cde]cd", Dur: 7
--   
--   a b a b   c d
--       c d e    
--   
-- -- The Bel string /2abc/3de (Bel 1992, p.53) can be -- written as *2abc*1/2*3de, or equivalently as -- *2abc*3/2de: -- --
--   > bel_ascii_pp "*2abc*3/2de"
--   
--   Bel(R): "*2abc*3/2de", Dur: 13/6
--   
--   a _ _ b _ _ c _ _ d _ e _
--   
-- -- It can also be written using the shorthand notation for rest -- sequences, where an integer n indicates a sequence of n -- rests, as: -- --
--   > bel_ascii_pp "(9,abc)(4,de)"
--   
--   Bel(R): "(---------,abc)(----,de)", Dur: 13
--   
--   - - - - - - - - - - - - -
--   a _ _ b _ _ c _ _ d _ e _
--   
-- -- In the Bel string {ab{/3abc,de},fghijk} (Bel 1992, -- p.20) the tempo indication does not change the inter-relation of the -- parts but rather scales the parallel node altogether, and can be -- re-written in Bel(R) notation as: -- --
--   > bel_ascii_pp "{ab*3{abc,de},fghijk}"
--   
--   Bel(R): "{ab*3{abc,de},fghijk}", Dur: 6
--   
--   a _ _ _ _ _ b _ _ _ _ _ a _ b _ c _
--                           d _ _ e _ _
--   f _ _ g _ _ h _ _ i _ _ j _ _ k _ _
--   
-- -- Curiously the following example (Bel 1990, p. 24) does not correspond -- to the phase diagram given: -- --
--   > bel_ascii_pp "{i{ab,cde},jk}"
--   
--   Bel(R): "{i{ab,cde},jk}", Dur: 4
--   
--   i _ a _ _ b _ _
--       c _ d _ e _
--   j _ _ _ k _ _ _
--   
-- -- The paper assigns tempi of /6 to both i and -- ab, which in Bel(R) could be written: -- --
--   > bel_ascii_pp "{i~{ab,cde},jk}"
--   
--   Bel(R): "{i~{ab,cde},jk}", Dur: 3
--   
--   i _ _ _ _ _ a _ _ _ _ _ b _ _ _ _ _
--               c _ _ _ d _ _ _ e _ _ _
--   j _ _ _ _ _ _ _ _ k _ _ _ _ _ _ _ _
--   
module Music.Theory.Time.Bel1990.R -- | Types of Par nodes. data Par_Mode Par_Left :: Par_Mode Par_Right :: Par_Mode Par_Min :: Par_Mode Par_Max :: Par_Mode Par_None :: Par_Mode -- | The different Par modes are indicated by bracket types. par_mode_brackets :: Par_Mode -> (String, String) bel_brackets_match :: (Char, Char) -> Bool -- | Tempo is rational. The duration of a Term is the reciprocal of -- the Tempo that is in place at the Term. type Tempo = Rational -- | Terms are the leaf nodes of the temporal structure. data Term a Value :: a -> Term a Rest :: Term a Continue :: Term a -- | Recursive temporal structure. data Bel a -- | Leaf node Node :: (Term a) -> Bel a -- | Isolate Iso :: (Bel a) -> Bel a -- | Sequence Seq :: (Bel a) -> (Bel a) -> Bel a -- | Parallel Par :: Par_Mode -> (Bel a) -> (Bel a) -> Bel a -- | Tempo multiplier Mul :: Tempo -> Bel a -- | Pretty printer for Bel, given pretty printer for the term type. bel_pp :: (a -> String) -> Bel a -> String -- | bel_pp of return. bel_char_pp :: Bel Char -> String -- | Analyse a Par node giving (duration,LHS-tempo-*,RHS-tempo-*). -- --
--   par_analyse 1 Par_Left (nseq "cd") (nseq "efg") == (2,1,3/2)
--   par_analyse 1 Par_Right (nseq "cd") (nseq "efg") == (3,2/3,1)
--   par_analyse 1 Par_Min (nseq "cd") (nseq "efg") == (2,1,3/2)
--   par_analyse 1 Par_Max (nseq "cd") (nseq "efg") == (3,2/3,1)
--   par_analyse 1 Par_None (nseq "cd") (nseq "efg") == (3,1,1)
--   
par_analyse :: Tempo -> Par_Mode -> Bel a -> Bel a -> (Rational, Rational, Rational) -- | Duration element of par_analyse. par_dur :: Tempo -> Par_Mode -> Bel a -> Bel a -> Rational -- | Calculate final tempo and duration of Bel. bel_tdur :: Tempo -> Bel a -> (Tempo, Rational) -- | snd of bel_tdur. bel_dur :: Tempo -> Bel a -> Rational -- | Time point. type Time = Rational -- | Voices are named as a sequence of left and right directions within -- nested Par structures. type Voice = [Char] -- | Linear state. Time is the start time of the term, Tempo -- is the active tempo & therefore the reciprocal of the duration, -- Voice is the part label. type L_St = (Time, Tempo, Voice) -- | Linear term. type L_Term a = (L_St, Term a) -- | Start time of L_Term. lterm_time :: L_Term a -> Time -- | Duration of L_Term (reciprocal of tempo). lterm_duration :: L_Term a -> Time -- | End time of L_Term. lterm_end_time :: L_Term a -> Time -- | Linear form of Bel, an ascending sequence of L_Term. type L_Bel a = [L_Term a] -- | Linearise Bel given initial L_St, ascending by -- construction. bel_linearise :: L_St -> Bel a -> (L_Bel a, L_St) -- | Merge two ascending L_Bel. lbel_merge :: L_Bel a -> L_Bel a -> L_Bel a -- | Set of unique Tempo at L_Bel. lbel_tempi :: L_Bel a -> [Tempo] -- | Multiply Tempo by n, and divide Time by n. lbel_tempo_mul :: Rational -> L_Bel a -> L_Bel a -- | After normalisation all start times and durations are integral. lbel_normalise :: L_Bel a -> L_Bel a -- | All leftmost voices are re-written to the last non-left turning point. -- --
--   map voice_normalise ["","l","ll","lll"] == replicate 4 ""
--   voice_normalise "lllrlrl" == "rlrl"
--   
voice_normalise :: Voice -> Voice -- | == on voice_normalise voice_eq :: Voice -> Voice -> Bool -- | Unique Voices at L_Bel. lbel_voices :: L_Bel a -> [Voice] -- | The duration of L_Bel. lbel_duration :: L_Bel a -> Time -- | Locate an L_Term that is active at the indicated Time -- and in the indicated Voice. lbel_lookup :: (Time, Voice) -> L_Bel a -> Maybe (L_Term a) -- | Calculate grid (phase diagram) for L_Bel. lbel_grid :: L_Bel a -> [[Maybe (Term a)]] -- | lbel_grid of bel_linearise. bel_grid :: Bel a -> [[Maybe (Term a)]] -- | Bel type phase diagram for Bel of Char. -- Optionally print whitespace between columns. bel_ascii :: Bool -> Bel Char -> String -- | putStrLn of bel_ascii. bel_ascii_pr :: Bel Char -> IO () -- | Infix form for Seq. (~>) :: Bel a -> Bel a -> Bel a -- | foldl1 of Seq. -- --
--   lseq [Node Rest] == Node Rest
--   lseq [Node Rest,Node Continue] == Seq (Node Rest) (Node Continue)
--   
lseq :: [Bel a] -> Bel a -- | Node of Value. node :: a -> Bel a -- | lseq of Node nseq :: [a] -> Bel a -- | Variant of nseq where _ is read as Continue and -- - as Rest. cseq :: String -> Bel Char -- | Par of Par_Max, this is the default Par_Mode. par :: Bel a -> Bel a -> Bel a -- | Node of Rest. rest :: Bel a -- | lseq of replicate of rest. nrests :: Integral n => n -> Bel a -- | Verify that bel_char_pp of bel_char_parse is id. bel_parse_pp_ident :: String -> Bool -- | Run bel_char_parse, and print both bel_char_pp and -- bel_ascii. -- --
--   bel_ascii_pp "{i{ab,{c[d,oh]e,sr{p,qr}}},{jk,ghjkj}}"
--   
bel_ascii_pp :: String -> IO () -- | A Char parser. type P a = GenParser Char () a -- | Parse Rest Term. -- --
--   P.parse p_rest "" "-"
--   
p_rest :: P (Term a) -- | Parse Rest Term. -- --
--   P.parse p_nrests "" "3"
--   
p_nrests :: P (Bel a) -- | Parse Continue Term. -- --
--   P.parse p_continue "" "_"
--   
p_continue :: P (Term a) -- | Parse Char Value Term. -- --
--   P.parse p_char_value "" "a"
--   
p_char_value :: P (Term Char) -- | Parse Char Term. -- --
--   P.parse (P.many1 p_char_term) "" "-_a"
--   
p_char_term :: P (Term Char) -- | Parse Char Node. -- --
--   P.parse (P.many1 p_char_node) "" "-_a"
--   
p_char_node :: P (Bel Char) -- | Parse positive Integer. -- --
--   P.parse p_integer "" "3"
--   
p_integer :: P Integer -- | Parse positive Rational. -- --
--   P.parse (p_rational `P.sepBy` (P.char ',')) "" "3%5,2/3"
--   
p_rational :: P Rational -- | Parse positive Double. -- --
--   P.parse p_double "" "3.5"
--   P.parse (p_double `P.sepBy` (P.char ',')) "" "3.5,7.2,1.0"
--   
p_double :: P Double -- | Parse positive number as Rational. -- --
--   P.parse (p_number `P.sepBy` (P.char ',')) "" "7%2,3.5,3"
--   
p_number :: P Rational -- | Parse Mul. -- --
--   P.parse (P.many1 p_mul) "" "/3*3/2"
--   
p_mul :: P (Bel a) -- | Given parser for Bel a, generate Iso parser. p_iso :: P (Bel a) -> P (Bel a) -- | p_iso of p_char_bel. -- --
--   P.parse p_char_iso "" "{abcde}"
--   
p_char_iso :: P (Bel Char) -- | Given parser for Bel a, generate Par parser. p_par :: P (Bel a) -> P (Bel a) -- | p_par of p_char_bel. -- --
--   P.parse p_char_par "" "{ab,{c,de}}"
--   P.parse p_char_par "" "{ab,~(c,de)}"
--   
p_char_par :: P (Bel Char) -- | Parse Bel Char. -- --
--   P.parse (P.many1 p_char_bel) "" "-_a*3"
--   
p_char_bel :: P (Bel Char) -- | Run parser for Bel of Char. bel_char_parse :: String -> Bel Char instance Eq Par_Mode instance Show Par_Mode instance Eq a => Eq (Term a) instance Show a => Show (Term a) instance Eq a => Eq (Bel a) instance Show a => Show (Bel a) -- | Equal temperament tuning tables. module Music.Theory.Tuning.ET -- | octpc_to_pitch and octpc_to_cps. octpc_to_pitch_cps :: Floating n => OctPC -> (Pitch, n) -- | 12-tone equal temperament table equating Pitch and frequency -- over range of human hearing, where A4 = 440hz. -- --
--   length tbl_12et == 132
--   let min_max l = (minimum l,maximum l)
--   min_max (map (round . snd) tbl_12et) == (16,31609)
--   
tbl_12et :: [(Pitch, Double)] -- | 24-tone equal temperament variant of tbl_12et. -- --
--   length tbl_24et == 264
--   min_max (map (round . snd) tbl_24et) == (16,32535)
--   
tbl_24et :: [(Pitch, Double)] -- | Given an ET table (or like) find bounds of frequency. -- --
--   let r = Just (at_pair octpc_to_pitch_cps ((3,11),(4,0)))
--   in bounds_et_table tbl_12et 256 == r
--   
bounds_et_table :: Ord s => [(t, s)] -> s -> Maybe ((t, s), (t, s)) -- | bounds_et_table of tbl_12et. -- --
--   map bounds_12et_tone (hsn 17 55)
--   
bounds_12et_tone :: Double -> Maybe ((Pitch, Double), (Pitch, Double)) -- | Tuple indicating nearest Pitch to frequency with -- ET frequency, and deviation in hertz and Cents. type HS_R p = (Double, p, Double, Double, Cents) -- | n-decimal places. -- --
--   ndp 3 (1/3) == "0.333"
--   
ndp :: Int -> Double -> String -- | Pretty print HS_R. hs_r_pp :: (p -> String) -> Int -> HS_R p -> [String] hs_r_pitch_pp :: Int -> HS_R Pitch -> [String] -- | Form HS_R for frequency by consulting table. -- --
--   let {f = 256
--       ;f' = octpc_to_cps (4,0)
--       ;r = (f,Pitch C Natural 4,f',f-f',fratio_to_cents (f/f'))}
--   in nearest_et_table_tone tbl_12et 256 == r
--   
nearest_et_table_tone :: [(p, Double)] -> Double -> HS_R p -- | nearest_et_table_tone for tbl_12et. nearest_12et_tone :: Double -> HS_R Pitch -- | nearest_et_table_tone for tbl_24et. -- --
--   let r = "55.0 A1 55.0 0.0 0.0"
--   in unwords (hs_r_pitch_pp 1 (nearest_24et_tone 55)) == r
--   
nearest_24et_tone :: Double -> HS_R Pitch -- | Monzo 72-edo HEWM notation. The domain is (-9,9). -- http://www.tonalsoft.com/enc/number/72edo.aspx -- --
--   let r = ["+",">","^","#<","#-","#","#+","#>","#^"]
--   in map alteration_72et_monzo [1 .. 9] == r
--   
-- --
--   let r = ["-","<","v","b>","b+","b","b-","b<","bv"]
--   in map alteration_72et_monzo [-1,-2 .. -9] == r
--   
alteration_72et_monzo :: Integral n => n -> String -- | Given a midi note number and 1/6 deviation determine -- Pitch' and frequency. -- --
--   let {f = pitch'_pp . fst . pitch_72et
--       ;r = "C4 C+4 C>4 C^4 C#<4 C#-4 C#4 C#+4 C#>4 C#^4"}
--   in unwords (map f (zip (repeat 60) [0..9])) == r
--   
-- --
--   let {f = pitch'_pp . fst . pitch_72et
--       ;r = "A4 A+4 A>4 A^4 Bb<4 Bb-4 Bb4 Bb+4 Bb>4 Bv4"}
--   in unwords (map f (zip (repeat 69) [0..9]))
--   
-- --
--   let {f = pitch'_pp . fst . pitch_72et
--       ;r = "Bb4 Bb+4 Bb>4 Bv4 B<4 B-4 B4 B+4 B>4 B^4"}
--   in unwords (map f (zip (repeat 70) [0..9])) == r
--   
pitch_72et :: (Int, Int) -> (Pitch', Double) -- | 72-tone equal temperament table equating Pitch' and frequency -- over range of human hearing, where A4 = 440hz. -- --
--   length tbl_72et == 792
--   min_max (map (round . snd) tbl_72et) == (16,33167)
--   
tbl_72et :: [(Pitch', Double)] -- | nearest_et_table_tone for tbl_72et. -- --
--   let r = "324.0 E<4 323.3 0.7 3.5"
--   in unwords (hs_r_pp pitch'_pp 1 (nearest_72et_tone 324))
--   
-- --
--   let {f = take 2 . hs_r_pp pitch'_pp 1 . nearest_72et_tone . snd}
--   in mapM_ (print . unwords . f) tbl_72et
--   
nearest_72et_tone :: Double -> HS_R Pitch' -- | Pitch with 12-ET/24-ET tuning deviation given in Cents. type Pitch_Detune = (Pitch, Cents) -- | Exract Pitch_Detune from HS_R. hsr_to_pitch_detune :: HS_R Pitch -> Pitch_Detune -- | Nearest 12-ET Pitch_Detune to indicated frequency (hz). -- --
--   nearest_pitch_detune_12et 452.8929841231365
--   
nearest_pitch_detune_12et :: Double -> Pitch_Detune -- | Nearest 24-ET Pitch_Detune to indicated frequency (hz). -- --
--   nearest_pitch_detune_24et 452.8929841231365
--   
nearest_pitch_detune_24et :: Double -> Pitch_Detune -- | Given near function, f0 and ratio derive -- Pitch_Detune. ratio_to_pitch_detune :: (Double -> HS_R Pitch) -> OctPC -> Rational -> Pitch_Detune -- | Frequency (hz) of Pitch_Detune. -- --
--   pitch_detune_to_cps (octpc_to_pitch pc_spell_ks (4,9),50)
--   
pitch_detune_to_cps :: Floating n => Pitch_Detune -> n -- | ratio_to_pitch_detune of nearest_12et_tone ratio_to_pitch_detune_12et :: OctPC -> Rational -> Pitch_Detune -- | ratio_to_pitch_detune of nearest_24et_tone ratio_to_pitch_detune_24et :: OctPC -> Rational -> Pitch_Detune pitch_detune_in_octave_nearest :: Pitch -> Pitch_Detune -> Pitch_Detune -- | Markdown pretty-printer for Pitch_Detune. pitch_detune_md :: Pitch_Detune -> String -- | HTML pretty-printer for Pitch_Detune. pitch_detune_html :: Pitch_Detune -> String -- | No-octave variant of pitch_detune_md. pitch_class_detune_md :: Pitch_Detune -> String -- | No-octave variant of pitch_detune_html. pitch_class_detune_html :: Pitch_Detune -> String -- | Larry Polansky. "Notes on the Tunings of Three Central Javanese -- Slendro/Pelog Pairs". Experimental Musical Instruments, -- 6(2):12-13,16-17, 1990. module Music.Theory.Tuning.Polansky_1990 -- | Kanjutmesem Slendro (S1,S2,S3,S5,S6,S1') -- --
--   L.d_dx kanjutmesem_s == [252,238,241,236,253]
--   
kanjutmesem_s :: Num n => [n] -- | Kanjutmesem Pelog (P1,P2,P3,P4,P5,P6,P7,P1') -- --
--   L.d_dx kanjutmesem_p == [141,141,272,140,115,172,246]
--   
kanjutmesem_p :: Num n => [n] -- | Darius Slendro (S1,S2,S3,S5,S6,S1') -- --
--   L.d_dx darius_s == [204,231,267,231,267]
--   ax_r darius_s == [9/8,8/7,7/6,8/7,7/6]
--   
darius_s :: Num n => [n] -- | Madeleine Pelog (P1,P2,P3,P4,P5,P6,P7,P1') -- --
--   L.d_dx madeleine_p == [139,128,336,99,94,173,231]
--   ax_r madeleine_p == [13/12,14/13,17/14,18/17,19/18,21/19,8/7]
--   
madeleine_p :: Num n => [n] -- | Lipur Sih Slendro (S1,S2,S3,S5,S6,S1') -- --
--   L.d_dx lipur_sih_s == [273,236,224,258,256]
--   
lipur_sih_s :: Num n => [n] -- | Lipur Sih Pelog (P1,P2,P3,P4,P5,P6,P7,P1') -- --
--   L.d_dx lipur_sih_p == [110,153,253,146,113,179]
--   
lipur_sih_p :: Num n => [n] -- | Idealized ET Slendro, 5-tone equal temperament (p.17) -- --
--   L.d_dx idealized_et_s == [240,240,240,240,240]
--   
idealized_et_s :: Num n => [n] -- | Idealized ET Pelog, subset of 9-tone equal temperament (p.17) -- --
--   L.d_dx idealized_et_p == [400/3,800/3,400/3,400/3,400/3,400/3,800/3]
--   
idealized_et_p :: Integral n => [Ratio n] -- | Reconstruct approximate ratios to within 1e-3 from intervals. ax_r :: Real n => [n] -> [Rational] -- | "Sieves" by Iannis Xenakis and John Rahn Perspectives of New -- Music Vol. 28, No. 1 (Winter, 1990), pp. 58-78 module Music.Theory.Xenakis.Sieve -- | Synonym for Integer type I = Integer -- | A Sieve. data Sieve -- | Empty Sieve Empty :: Sieve -- | Primitive Sieve of modulo and index L :: (I, I) -> Sieve -- | Union of two Sieves Union :: Sieve -> Sieve -> Sieve -- | Intersection of two Sieves Intersection :: Sieve -> Sieve -> Sieve -- | The Union of a list of Sieves, ie. foldl1 -- Union. union :: [Sieve] -> Sieve -- | The Intersection of a list of Sieves, ie. foldl1 -- Intersection. intersection :: [Sieve] -> Sieve -- | Unicode synonym for Union. (∪) :: Sieve -> Sieve -> Sieve -- | Unicode synonym for Intersection. (∩) :: Sieve -> Sieve -> Sieve -- | Variant of L, ie. curry L. -- --
--   l 15 19 == L (15,19)
--   
l :: I -> I -> Sieve -- | unicode synonym for l. (⋄) :: I -> I -> Sieve -- | In a normal Sieve m is > i. -- --
--   normalise (L (15,19)) == L (15,4)
--   
normalise :: Sieve -> Sieve -- | Predicate to test if a Sieve is normal. -- --
--   is_normal (L (15,4)) == True
--   
is_normal :: Sieve -> Bool -- | Predicate to determine if an I is an element of the -- Sieve. -- --
--   map (element (L (3,1))) [1..4] == [True,False,False,True]
--   map (element (L (15,4))) [4,19 .. 49] == [True,True,True,True]
--   
element :: Sieve -> I -> Bool -- | Construct the sequence defined by a Sieve. Note that building a -- sieve that contains an intersection clause that has no elements gives -- _|_. -- --
--   let {d = [0,2,4,5,7,9,11]
--       ;r = d ++ map (+ 12) d}
--   in take 14 (build (union (map (l 12) d))) == r
--   
build :: Sieve -> [I] -- | Variant of build that gives the first n places of the -- reduce of Sieve. -- --
--   buildn 6 (union (map (l 8) [0,3,6])) == [0,3,6,8,11,14]
--   buildn 12 (L (3,2)) == [2,5,8,11,14,17,20,23,26,29,32,35]
--   buildn 9 (L (8,0)) == [0,8,16,24,32,40,48,56,64]
--   buildn 3 (L (3,2) ∩ L (8,0)) == [8,32,56]
--   buildn 12 (L (3,1) ∪ L (4,0)) == [0,1,4,7,8,10,12,13,16,19,20,22]
--   buildn 14 (5⋄4 ∪ 3⋄2 ∪ 7⋄3) == [2,3,4,5,8,9,10,11,14,17,19,20,23,24]
--   buildn 6 (3⋄0 ∪ 4⋄0) == [0,3,4,6,8,9]
--   buildn 8 (5⋄2 ∩ 2⋄0 ∪ 7⋄3) == [2,3,10,12,17,22,24,31]
--   buildn 12 (5⋄1 ∪ 7⋄2) == [1,2,6,9,11,16,21,23,26,30,31,36]
--   
-- --
--   buildn 10 (3⋄2 ∩ 4⋄7 ∪ 6⋄9 ∩ 15⋄18) == [3,11,23,33,35,47,59,63,71,83]
--   
-- --
--   let {s = 3⋄2∩4⋄7∩6⋄11∩8⋄7 ∪ 6⋄9∩15⋄18 ∪ 13⋄5∩8⋄6∩4⋄2 ∪ 6⋄9∩15⋄19
--       ;s' = 24⋄23 ∪ 30⋄3 ∪ 104⋄70}
--   in buildn 16 s == buildn 16 s'
--   
-- --
--   buildn 10 (24⋄23 ∪ 30⋄3 ∪ 104⋄70) == [3,23,33,47,63,70,71,93,95,119]
--   
-- --
--   let r = [2,3,4,5,8,9,10,11,14,17,19,20,23,24,26,29,31]
--   in buildn 17 (5⋄4 ∪ 3⋄2 ∪ 7⋄3) == r
--   
-- --
--   let r = [0,1,3,6,9,10,11,12,15,16,17,18,21,24,26,27,30]
--   in buildn 17 (5⋄1 ∪ 3⋄0 ∪ 7⋄3) == r
--   
-- --
--   let r = [0,2,3,4,6,7,9,11,12,15,17,18,21,22,24,25,27,30,32]
--   in buildn 19 (5⋄2 ∪ 3⋄0 ∪ 7⋄4) == r
--   
buildn :: Int -> Sieve -> [I] -- | Standard differentiation function. -- --
--   differentiate [1,3,6,10] == [2,3,4]
--   differentiate [0,2,4,5,7,9,11,12] == [2,2,1,2,2,2,1]
--   
differentiate :: Num a => [a] -> [a] -- | Euclid's algorithm for computing the greatest common divisor. -- --
--   euclid 1989 867 == 51
--   
euclid :: Integral a => a -> a -> a -- | Bachet De Méziriac's algorithm. -- --
--   de_meziriac 15 4 == 3 && euclid 15 4 == 1
--   
de_meziriac :: Integral a => a -> a -> a -- | Attempt to reduce the Intersection of two L nodes to a -- singular L node. -- --
--   reduce_intersection (3,2) (4,7) == Just (12,11)
--   reduce_intersection (12,11) (6,11) == Just (12,11)
--   reduce_intersection (12,11) (8,7) == Just (24,23)
--   
reduce_intersection :: Integral t => (t, t) -> (t, t) -> Maybe (t, t) -- | Reduce the number of nodes at a Sieve. -- --
--   reduce (L (3,2) ∪ Empty) == L (3,2)
--   reduce (L (3,2) ∩ Empty) == L (3,2)
--   reduce (L (3,2) ∩ L (4,7)) == L (12,11)
--   reduce (L (6,9) ∩ L (15,18)) == L (30,3)
--   
-- --
--   let s = 3⋄2∩4⋄7∩6⋄11∩8⋄7 ∪ 6⋄9∩15⋄18 ∪ 13⋄5∩8⋄6∩4⋄2 ∪ 6⋄9∩15⋄19
--   in reduce s == (24⋄23 ∪ 30⋄3 ∪ 104⋄70)
--   
-- --
--   let s = 3⋄2∩4⋄7∩6⋄11∩8⋄7 ∪ 6⋄9∩15⋄18 ∪ 13⋄5∩8⋄6∩4⋄2 ∪ 6⋄9∩15⋄19
--   in reduce s == (24⋄23 ∪ 30⋄3 ∪ 104⋄70)
--   
reduce :: Sieve -> Sieve instance Eq Sieve instance Show Sieve -- | Allen Forte. The Structure of Atonal Music. Yale University -- Press, New Haven, 1973. module Music.Theory.Z.Forte_1973 -- | T-related rotations of p. -- --
--   t_rotations 12 [0,1,3] == [[0,1,3],[0,2,11],[0,9,10]]
--   
t_rotations :: Integral a => a -> [a] -> [[a]] -- | T/I-related rotations of p. -- --
--   ti_rotations 12 [0,1,3] == [[0,1,3],[0,2,11],[0,9,10]
--                              ,[0,9,11],[0,2,3],[0,1,10]]
--   
ti_rotations :: Integral a => a -> [a] -> [[a]] -- | Variant with default value for empty input list case. minimumBy_or :: a -> (a -> a -> Ordering) -> [a] -> a -- | Prime form rule requiring comparator, considering t_rotations. t_cmp_prime :: Integral a => a -> ([a] -> [a] -> Ordering) -> [a] -> [a] -- | Prime form rule requiring comparator, considering ti_rotations. ti_cmp_prime :: Integral a => a -> ([a] -> [a] -> Ordering) -> [a] -> [a] -- | Forte comparison function (rightmost first then leftmost outwards). -- --
--   forte_cmp [0,1,3,6,8,9] [0,2,3,6,7,9] == LT
--   
forte_cmp :: Ord t => [t] -> [t] -> Ordering -- | Forte prime form, ie. cmp_prime of forte_cmp. -- --
--   forte_prime 12 [0,1,3,6,8,9] == [0,1,3,6,8,9]
--   forte_prime 5 [0,1,4] == [0,1,2]
--   
-- --
--   S.set (map (forte_prime 5) (S.powerset [0..4]))
--   
forte_prime :: Integral a => a -> [a] -> [a] -- | Transpositional equivalence prime form, ie. t_cmp_prime of -- forte_cmp. -- --
--   (forte_prime 12 [0,2,3],t_prime 12 [0,2,3]) == ([0,1,3],[0,2,3])
--   
t_prime :: Integral a => a -> [a] -> [a] -- | Interval class of i interval i. -- --
--   map (ic 5) [1,2,3,4] == [1,2,2,1]
--   map (ic 12) [5,6,7] == [5,6,5]
--   map (ic 12 . to_Z 12) [-13,-1,0,1,13] == [1,1,0,1,1]
--   
ic :: Integral a => a -> a -> a -- | Forte notation for interval class vector. -- --
--   icv 12 [0,1,2,4,7,8] == [3,2,2,3,3,2]
--   
icv :: (Integral i, Num n) => i -> [i] -> [n] -- | Basic interval pattern, see Allen Forte "The Basic Interval Patterns" -- JMT 17/2 (1973):234-272 -- --
--   >>> bip 0t95728e3416
--   11223344556
--   
-- --
--   bip 12 [0,10,9,5,7,2,8,11,3,4,1,6] == [1,1,2,2,3,3,4,4,5,5,6]
--   
bip :: Integral a => a -> [a] -> [a] -- | Allen Forte. The Structure of Atonal Music. Yale University -- Press, New Haven, 1973. module Music.Theory.Z12.Forte_1973 -- | T-related rotations of p. -- --
--   t_rotations [0,1,3] == [[0,1,3],[0,2,11],[0,9,10]]
--   
t_rotations :: [Z12] -> [[Z12]] -- | T/I-related rotations of p. -- --
--   ti_rotations [0,1,3] == [[0,1,3],[0,2,11],[0,9,10]
--                           ,[0,9,11],[0,2,3],[0,1,10]]
--   
ti_rotations :: [Z12] -> [[Z12]] -- | Forte prime form, ie. cmp_prime of forte_cmp. -- --
--   forte_prime [0,1,3,6,8,9] == [0,1,3,6,8,9]
--   
forte_prime :: [Z12] -> [Z12] -- | Transpositional equivalence prime form, ie. t_cmp_prime of -- forte_cmp. -- --
--   (forte_prime [0,2,3],t_prime [0,2,3]) == ([0,1,3],[0,2,3])
--   
t_prime :: [Z12] -> [Z12] -- | Synonym for String. type SC_Name = String -- | The set-class table (Forte prime forms). -- --
--   length sc_table == 224
--   
sc_table :: [(SC_Name, [Z12])] -- | Lookup a set-class name. The input set is subject to -- forte_prime before lookup. -- --
--   sc_name [0,2,3,6,7] == "5-Z18"
--   sc_name [0,1,4,6,7,8] == "6-Z17"
--   
sc_name :: [Z12] -> SC_Name -- | Lookup a set-class given a set-class name. -- --
--   sc "6-Z17" == [0,1,2,4,7,8]
--   
sc :: SC_Name -> [Z12] -- | List of set classes (the set class universe). -- --
--   let r = [("0-1",[0,0,0,0,0,0])
--           ,("1-1",[0,0,0,0,0,0])
--           ,("2-1",[1,0,0,0,0,0])
--           ,("2-2",[0,1,0,0,0,0])
--           ,("2-3",[0,0,1,0,0,0])
--           ,("2-4",[0,0,0,1,0,0])
--           ,("2-5",[0,0,0,0,1,0])
--           ,("2-6",[0,0,0,0,0,1])
--           ,("3-1",[2,1,0,0,0,0])
--           ,("3-2",[1,1,1,0,0,0])
--           ,("3-3",[1,0,1,1,0,0])
--           ,("3-4",[1,0,0,1,1,0])
--           ,("3-5",[1,0,0,0,1,1])
--           ,("3-6",[0,2,0,1,0,0])
--           ,("3-7",[0,1,1,0,1,0])
--           ,("3-8",[0,1,0,1,0,1])
--           ,("3-9",[0,1,0,0,2,0])
--           ,("3-10",[0,0,2,0,0,1])
--           ,("3-11",[0,0,1,1,1,0])
--           ,("3-12",[0,0,0,3,0,0])
--           ,("4-1",[3,2,1,0,0,0])
--           ,("4-2",[2,2,1,1,0,0])
--           ,("4-3",[2,1,2,1,0,0])
--           ,("4-4",[2,1,1,1,1,0])
--           ,("4-5",[2,1,0,1,1,1])
--           ,("4-6",[2,1,0,0,2,1])
--           ,("4-7",[2,0,1,2,1,0])
--           ,("4-8",[2,0,0,1,2,1])
--           ,("4-9",[2,0,0,0,2,2])
--           ,("4-10",[1,2,2,0,1,0])
--           ,("4-11",[1,2,1,1,1,0])
--           ,("4-12",[1,1,2,1,0,1])
--           ,("4-13",[1,1,2,0,1,1])
--           ,("4-14",[1,1,1,1,2,0])
--           ,("4-Z15",[1,1,1,1,1,1])
--           ,("4-16",[1,1,0,1,2,1])
--           ,("4-17",[1,0,2,2,1,0])
--           ,("4-18",[1,0,2,1,1,1])
--           ,("4-19",[1,0,1,3,1,0])
--           ,("4-20",[1,0,1,2,2,0])
--           ,("4-21",[0,3,0,2,0,1])
--           ,("4-22",[0,2,1,1,2,0])
--           ,("4-23",[0,2,1,0,3,0])
--           ,("4-24",[0,2,0,3,0,1])
--           ,("4-25",[0,2,0,2,0,2])
--           ,("4-26",[0,1,2,1,2,0])
--           ,("4-27",[0,1,2,1,1,1])
--           ,("4-28",[0,0,4,0,0,2])
--           ,("4-Z29",[1,1,1,1,1,1])
--           ,("5-1",[4,3,2,1,0,0])
--           ,("5-2",[3,3,2,1,1,0])
--           ,("5-3",[3,2,2,2,1,0])
--           ,("5-4",[3,2,2,1,1,1])
--           ,("5-5",[3,2,1,1,2,1])
--           ,("5-6",[3,1,1,2,2,1])
--           ,("5-7",[3,1,0,1,3,2])
--           ,("5-8",[2,3,2,2,0,1])
--           ,("5-9",[2,3,1,2,1,1])
--           ,("5-10",[2,2,3,1,1,1])
--           ,("5-11",[2,2,2,2,2,0])
--           ,("5-Z12",[2,2,2,1,2,1])
--           ,("5-13",[2,2,1,3,1,1])
--           ,("5-14",[2,2,1,1,3,1])
--           ,("5-15",[2,2,0,2,2,2])
--           ,("5-16",[2,1,3,2,1,1])
--           ,("5-Z17",[2,1,2,3,2,0])
--           ,("5-Z18",[2,1,2,2,2,1])
--           ,("5-19",[2,1,2,1,2,2])
--           ,("5-20",[2,1,1,2,3,1])
--           ,("5-21",[2,0,2,4,2,0])
--           ,("5-22",[2,0,2,3,2,1])
--           ,("5-23",[1,3,2,1,3,0])
--           ,("5-24",[1,3,1,2,2,1])
--           ,("5-25",[1,2,3,1,2,1])
--           ,("5-26",[1,2,2,3,1,1])
--           ,("5-27",[1,2,2,2,3,0])
--           ,("5-28",[1,2,2,2,1,2])
--           ,("5-29",[1,2,2,1,3,1])
--           ,("5-30",[1,2,1,3,2,1])
--           ,("5-31",[1,1,4,1,1,2])
--           ,("5-32",[1,1,3,2,2,1])
--           ,("5-33",[0,4,0,4,0,2])
--           ,("5-34",[0,3,2,2,2,1])
--           ,("5-35",[0,3,2,1,4,0])
--           ,("5-Z36",[2,2,2,1,2,1])
--           ,("5-Z37",[2,1,2,3,2,0])
--           ,("5-Z38",[2,1,2,2,2,1])
--           ,("6-1",[5,4,3,2,1,0])
--           ,("6-2",[4,4,3,2,1,1])
--           ,("6-Z3",[4,3,3,2,2,1])
--           ,("6-Z4",[4,3,2,3,2,1])
--           ,("6-5",[4,2,2,2,3,2])
--           ,("6-Z6",[4,2,1,2,4,2])
--           ,("6-7",[4,2,0,2,4,3])
--           ,("6-8",[3,4,3,2,3,0])
--           ,("6-9",[3,4,2,2,3,1])
--           ,("6-Z10",[3,3,3,3,2,1])
--           ,("6-Z11",[3,3,3,2,3,1])
--           ,("6-Z12",[3,3,2,2,3,2])
--           ,("6-Z13",[3,2,4,2,2,2])
--           ,("6-14",[3,2,3,4,3,0])
--           ,("6-15",[3,2,3,4,2,1])
--           ,("6-16",[3,2,2,4,3,1])
--           ,("6-Z17",[3,2,2,3,3,2])
--           ,("6-18",[3,2,2,2,4,2])
--           ,("6-Z19",[3,1,3,4,3,1])
--           ,("6-20",[3,0,3,6,3,0])
--           ,("6-21",[2,4,2,4,1,2])
--           ,("6-22",[2,4,1,4,2,2])
--           ,("6-Z23",[2,3,4,2,2,2])
--           ,("6-Z24",[2,3,3,3,3,1])
--           ,("6-Z25",[2,3,3,2,4,1])
--           ,("6-Z26",[2,3,2,3,4,1])
--           ,("6-27",[2,2,5,2,2,2])
--           ,("6-Z28",[2,2,4,3,2,2])
--           ,("6-Z29",[2,2,4,2,3,2])
--           ,("6-30",[2,2,4,2,2,3])
--           ,("6-31",[2,2,3,4,3,1])
--           ,("6-32",[1,4,3,2,5,0])
--           ,("6-33",[1,4,3,2,4,1])
--           ,("6-34",[1,4,2,4,2,2])
--           ,("6-35",[0,6,0,6,0,3])
--           ,("6-Z36",[4,3,3,2,2,1])
--           ,("6-Z37",[4,3,2,3,2,1])
--           ,("6-Z38",[4,2,1,2,4,2])
--           ,("6-Z39",[3,3,3,3,2,1])
--           ,("6-Z40",[3,3,3,2,3,1])
--           ,("6-Z41",[3,3,2,2,3,2])
--           ,("6-Z42",[3,2,4,2,2,2])
--           ,("6-Z43",[3,2,2,3,3,2])
--           ,("6-Z44",[3,1,3,4,3,1])
--           ,("6-Z45",[2,3,4,2,2,2])
--           ,("6-Z46",[2,3,3,3,3,1])
--           ,("6-Z47",[2,3,3,2,4,1])
--           ,("6-Z48",[2,3,2,3,4,1])
--           ,("6-Z49",[2,2,4,3,2,2])
--           ,("6-Z50",[2,2,4,2,3,2])
--           ,("7-1",[6,5,4,3,2,1])
--           ,("7-2",[5,5,4,3,3,1])
--           ,("7-3",[5,4,4,4,3,1])
--           ,("7-4",[5,4,4,3,3,2])
--           ,("7-5",[5,4,3,3,4,2])
--           ,("7-6",[5,3,3,4,4,2])
--           ,("7-7",[5,3,2,3,5,3])
--           ,("7-8",[4,5,4,4,2,2])
--           ,("7-9",[4,5,3,4,3,2])
--           ,("7-10",[4,4,5,3,3,2])
--           ,("7-11",[4,4,4,4,4,1])
--           ,("7-Z12",[4,4,4,3,4,2])
--           ,("7-13",[4,4,3,5,3,2])
--           ,("7-14",[4,4,3,3,5,2])
--           ,("7-15",[4,4,2,4,4,3])
--           ,("7-16",[4,3,5,4,3,2])
--           ,("7-Z17",[4,3,4,5,4,1])
--           ,("7-Z18",[4,3,4,4,4,2])
--           ,("7-19",[4,3,4,3,4,3])
--           ,("7-20",[4,3,3,4,5,2])
--           ,("7-21",[4,2,4,6,4,1])
--           ,("7-22",[4,2,4,5,4,2])
--           ,("7-23",[3,5,4,3,5,1])
--           ,("7-24",[3,5,3,4,4,2])
--           ,("7-25",[3,4,5,3,4,2])
--           ,("7-26",[3,4,4,5,3,2])
--           ,("7-27",[3,4,4,4,5,1])
--           ,("7-28",[3,4,4,4,3,3])
--           ,("7-29",[3,4,4,3,5,2])
--           ,("7-30",[3,4,3,5,4,2])
--           ,("7-31",[3,3,6,3,3,3])
--           ,("7-32",[3,3,5,4,4,2])
--           ,("7-33",[2,6,2,6,2,3])
--           ,("7-34",[2,5,4,4,4,2])
--           ,("7-35",[2,5,4,3,6,1])
--           ,("7-Z36",[4,4,4,3,4,2])
--           ,("7-Z37",[4,3,4,5,4,1])
--           ,("7-Z38",[4,3,4,4,4,2])
--           ,("8-1",[7,6,5,4,4,2])
--           ,("8-2",[6,6,5,5,4,2])
--           ,("8-3",[6,5,6,5,4,2])
--           ,("8-4",[6,5,5,5,5,2])
--           ,("8-5",[6,5,4,5,5,3])
--           ,("8-6",[6,5,4,4,6,3])
--           ,("8-7",[6,4,5,6,5,2])
--           ,("8-8",[6,4,4,5,6,3])
--           ,("8-9",[6,4,4,4,6,4])
--           ,("8-10",[5,6,6,4,5,2])
--           ,("8-11",[5,6,5,5,5,2])
--           ,("8-12",[5,5,6,5,4,3])
--           ,("8-13",[5,5,6,4,5,3])
--           ,("8-14",[5,5,5,5,6,2])
--           ,("8-Z15",[5,5,5,5,5,3])
--           ,("8-16",[5,5,4,5,6,3])
--           ,("8-17",[5,4,6,6,5,2])
--           ,("8-18",[5,4,6,5,5,3])
--           ,("8-19",[5,4,5,7,5,2])
--           ,("8-20",[5,4,5,6,6,2])
--           ,("8-21",[4,7,4,6,4,3])
--           ,("8-22",[4,6,5,5,6,2])
--           ,("8-23",[4,6,5,4,7,2])
--           ,("8-24",[4,6,4,7,4,3])
--           ,("8-25",[4,6,4,6,4,4])
--           ,("8-26",[4,5,6,5,6,2])
--           ,("8-27",[4,5,6,5,5,3])
--           ,("8-28",[4,4,8,4,4,4])
--           ,("8-Z29",[5,5,5,5,5,3])
--           ,("9-1",[8,7,6,6,6,3])
--           ,("9-2",[7,7,7,6,6,3])
--           ,("9-3",[7,6,7,7,6,3])
--           ,("9-4",[7,6,6,7,7,3])
--           ,("9-5",[7,6,6,6,7,4])
--           ,("9-6",[6,8,6,7,6,3])
--           ,("9-7",[6,7,7,6,7,3])
--           ,("9-8",[6,7,6,7,6,4])
--           ,("9-9",[6,7,6,6,8,3])
--           ,("9-10",[6,6,8,6,6,4])
--           ,("9-11",[6,6,7,7,7,3])
--           ,("9-12",[6,6,6,9,6,3])
--           ,("10-1",[9,8,8,8,8,4])
--           ,("10-2",[8,9,8,8,8,4])
--           ,("10-3",[8,8,9,8,8,4])
--           ,("10-4",[8,8,8,9,8,4])
--           ,("10-5",[8,8,8,8,9,4])
--           ,("10-6",[8,8,8,8,8,5])
--           ,("11-1",[10,10,10,10,10,5])
--           ,("12-1",[12,12,12,12,12,6])]
--   in let icvs = map icv scs in zip (map sc_name scs) icvs == r
--   
scs :: [[Z12]] -- | Cardinality n subset of scs. -- --
--   map (length . scs_n) [1..11] == [1,6,12,29,38,50,38,29,12,6,1]
--   
scs_n :: Integral i => i -> [[Z12]] -- | Basic interval pattern, see Allen Forte "The Basic Interval Patterns" -- JMT 17/2 (1973):234-272 -- --
--   >>> bip 0t95728e3416
--   11223344556
--   
-- --
--   bip [0,10,9,5,7,2,8,11,3,4,1,6] == [1,1,2,2,3,3,4,4,5,5,6]
--   bip (pco "0t95728e3416") == [1,1,2,2,3,3,4,4,5,5,6]
--   
bip :: [Z12] -> [Z12] -- | Interval class of Z12 interval i. -- --
--   map ic [5,6,7] == [5,6,5]
--   map ic [-13,-1,0,1,13] == [1,1,0,1,1]
--   
ic :: Z12 -> Z12 -- | Forte notation for interval class vector. -- --
--   icv [0,1,2,4,7,8] == [3,2,2,3,3,2]
--   
icv :: Integral i => [Z12] -> [i] -- | Michael Buchler. "Relative Saturation of Subsets and Interval Cycles -- as a Means for Determining Set-Class Similarity". PhD thesis, -- University of Rochester, 1998 module Music.Theory.Metric.Buchler_1998 -- | Predicate for list with cardinality n. of_c :: Integral n => n -> [a] -> Bool -- | Set classes of cardinality n. -- --
--   sc_table_n 2 == [[0,1],[0,2],[0,3],[0,4],[0,5],[0,6]]
--   
sc_table_n :: Integral n => n -> [[Z12]] -- | Minima and maxima of ICV of SCs of cardinality n. -- --
--   icv_minmax 5 == ([0,0,0,1,0,0],[4,4,4,4,4,2])
--   
icv_minmax :: (Integral n, Integral b) => n -> ([b], [b]) data R MIN :: R MAX :: R type D n = (R, n) -- | Pretty printer for R. -- --
--   map r_pp [MIN,MAX] == ["+","-"]
--   
r_pp :: R -> String -- | SATV element measure with given funtion. satv_f :: Integral n => ((n, n, n) -> D n) -> [Z12] -> [D n] -- | Pretty printer for SATV element. -- --
--   satv_e_pp (satv_a [0,1,2,6,7,8]) == "<-1,+2,+0,+0,-1,-0>"
--   
satv_e_pp :: Show i => [D i] -> String type SATV i = ([D i], [D i]) -- | Pretty printer for SATV. satv_pp :: Show i => SATV i -> String -- | SATVa measure. -- --
--   satv_e_pp (satv_a [0,1,2,6,7,8]) == "<-1,+2,+0,+0,-1,-0>"
--   satv_e_pp (satv_a [0,1,2,3,4]) == "<-0,-1,-2,+0,+0,+0>"
--   
satv_a :: Integral i => [Z12] -> [D i] -- | SATVb measure. -- --
--   satv_e_pp (satv_b [0,1,2,6,7,8]) == "<+4,-4,-5,-4,+4,+3>"
--   satv_e_pp (satv_b [0,1,2,3,4]) == "<+4,+3,+2,-3,-4,-2>"
--   
satv_b :: Integral i => [Z12] -> [D i] -- | SATV measure. -- --
--   satv_pp (satv [0,3,6,9]) == "(<+0,+0,-0,+0,+0,-0>,<-3,-3,+4,-3,-3,+2>)"
--   satv_pp (satv [0,1,3,4,8]) == "(<-2,+1,-2,-1,-2,+0>,<+2,-3,+2,+2,+2,-2>)"
--   satv_pp (satv [0,1,2,6,7,8]) == "(<-1,+2,+0,+0,-1,-0>,<+4,-4,-5,-4,+4,+3>)"
--   satv_pp (satv [0,4]) == "(<+0,+0,+0,-0,+0,+0>,<-1,-1,-1,+1,-1,-1>)"
--   satv_pp (satv [0,1,3,4,6,9]) == "(<+2,+2,-0,+0,+2,-1>,<-3,-4,+5,-4,-3,+2>)"
--   satv_pp (satv [0,1,3,6,7,9]) == "(<+2,+2,-1,+0,+2,-0>,<-3,-4,+4,-4,-3,+3>)"
--   satv_pp (satv [0,1,2,3,6]) == "(<-1,-2,-2,+0,+1,-1>,<+3,+2,+2,-3,-3,+1>)"
--   satv_pp (satv [0,1,2,3,4,6]) == "(<-1,-2,-2,+0,+1,+1>,<+4,+4,+3,-4,-4,-2>)"
--   satv_pp (satv [0,1,3,6,8]) == "(<+1,-2,-2,+0,-1,-1>,<-3,+2,+2,-3,+3,+1>)"
--   satv_pp (satv [0,2,3,5,7,9]) == "(<+1,-2,-2,+0,-1,+1>,<-4,+4,+3,-4,+4,-2>)"
--   
satv :: Integral i => [Z12] -> SATV i -- | SATV reorganised by R. -- --
--   satv_minmax (satv [0,1,2,6,7,8]) == ([4,2,0,0,4,3],[1,4,5,4,1,0])
--   
satv_minmax :: SATV i -> ([i], [i]) -- | Absolute difference. abs_dif :: Num a => a -> a -> a -- | Sum of numerical components of a and b parts of -- SATV. -- --
--   satv_n_sum (satv [0,1,2,6,7,8]) == [5,6,5,4,5,3]
--   satv_n_sum (satv [0,3,6,9]) = [3,3,4,3,3,2]
--   
satv_n_sum :: Num c => SATV c -> [c] two_part_difference_vector :: Integral i => [D i] -> SATV i -> [i] two_part_difference_vector_set :: Integral i => SATV i -> SATV i -> ([i], [i]) -- | SATSIM metric. -- --
--   satsim [0,1,2,6,7,8] [0,3,6,9] == 25/46
--   satsim [0,4] [0,1,3,4,6,9] == 25/34
--   satsim [0,4] [0,1,3,6,7,9] == 25/34
--   satsim [0,1,2,3,6] [0,1,2,3,4,6] == 1/49
--   satsim [0,1,3,6,8] [0,2,3,5,7,9] == 1/49
--   satsim [0,1,2,3,4] [0,1,4,5,7] == 8/21
--   satsim [0,1,2,3,4] [0,2,4,6,8] == 4/7
--   satsim [0,1,4,5,7] [0,2,4,6,8] == 4/7
--   
satsim :: Integral a => [Z12] -> [Z12] -> Ratio a -- | Table of satsim measures for all SC pairs. -- --
--   length satsim_table == 24310
--   
satsim_table :: Integral i => [(([Z12], [Z12]), Ratio i)] -- | Histogram of values at satsim_table. -- --
--   satsim_table_histogram == T.histogram (map snd satsim_table)
--   
satsim_table_histogram :: Integral i => [(Ratio i, i)] instance Eq R instance Show R -- | Robert Morris. "A Similarity Index for Pitch-Class Sets". Perspectives -- of New Music, 18(2):445-460, 1980. module Music.Theory.Metric.Morris_1980 -- | SIM -- --
--   icv [0,1,3,6] == [1,1,2,0,1,1] && icv [0,2,4,7] == [0,2,1,1,2,0]
--   sim [0,1,3,6] [0,2,4,7] == 6
--   sim [0,1,2,4,5,8] [0,1,3,7] == 9
--   
sim :: Integral a => [Z12] -> [Z12] -> a -- | ASIM -- --
--   asim [0,1,3,6] [0,2,4,7] == 6/12
--   asim [0,1,2,4,5,8] [0,1,3,7] == 9/21
--   asim [0,1,2,3,4] [0,1,4,5,7] == 2/5
--   asim [0,1,2,3,4] [0,2,4,6,8] == 3/5
--   asim [0,1,4,5,7] [0,2,4,6,8] == 3/5
--   
asim :: Integral n => [Z12] -> [Z12] -> Ratio n -- | John Rahn. Basic Atonal Theory. Longman, New York, 1980. module Music.Theory.Z12.Rahn_1980 -- | Rahn prime form (comparison is rightmost inwards). -- --
--   rahn_cmp [0,1,3,6,8,9] [0,2,3,6,7,9] == GT
--   
rahn_cmp :: Ord a => [a] -> [a] -> Ordering -- | Rahn prime form, ie. ti_cmp_prime of rahn_cmp. -- --
--   rahn_prime [0,1,3,6,8,9] == [0,2,3,6,7,9]
--   
-- --
--   import Music.Theory.Z12.Forte_1973
--   
-- --
--   let s = [[0,1,3,7,8]
--           ,[0,1,3,6,8,9],[0,1,3,5,8,9]
--           ,[0,1,2,4,7,8,9]
--           ,[0,1,2,4,5,7,9,10]]
--   in all (\p -> forte_prime p /= rahn_prime p) s == True
--   
rahn_prime :: [Z12] -> [Z12] -- | Marcus Castrén. RECREL: A Similarity Measure for Set-Classes. -- PhD thesis, Sibelius Academy, Helsinki, 1994. module Music.Theory.Z12.Castren_1994 -- | Is p symmetrical under inversion. -- --
--   import Music.Theory.Z12.Forte_1973
--   map inv_sym (scs_n 2) == [True,True,True,True,True,True]
--   map (fromEnum.inv_sym) (scs_n 3) == [1,0,0,0,0,1,0,0,1,1,0,1]
--   
inv_sym :: [Z12] -> Bool -- | If p is not inv_sym then (p,invert 0 p) else -- Nothing. -- --
--   sc_t_ti [0,2,4] == Nothing
--   sc_t_ti [0,1,3] == Just ([0,1,3],[0,2,3])
--   
sc_t_ti :: [Z12] -> Maybe ([Z12], [Z12]) -- | Transpositional equivalence variant of Forte's sc_table. The -- inversionally related classes are distinguished by labels A -- and B; the class providing the best normal order -- (Forte 1973) is always the A class. If neither A nor -- B appears in the name of a set-class, it is inversionally -- symmetrical. -- --
--   (length sc_table,length t_sc_table) == (224,352)
--   lookup "5-Z18B" t_sc_table == Just [0,2,3,6,7]
--   
t_sc_table :: [(SC_Name, [Z12])] -- | Lookup a set-class name. The input set is subject to t_prime -- before lookup. -- --
--   t_sc_name [0,2,3,6,7] == "5-Z18B"
--   t_sc_name [0,1,4,6,7,8] == "6-Z17B"
--   
t_sc_name :: [Z12] -> SC_Name -- | Lookup a set-class given a set-class name. -- --
--   t_sc "6-Z17A" == [0,1,2,4,7,8]
--   
t_sc :: SC_Name -> [Z12] -- | List of set classes. t_scs :: [[Z12]] -- | Cardinality n subset of t_scs. -- --
--   map (length . t_scs_n) [2..10] == [6,19,43,66,80,66,43,19,6]
--   
t_scs_n :: Integral i => i -> [[Z12]] -- | T-related q that are subsets of p. -- --
--   t_subsets [0,1,2,3,4] [0,1]  == [[0,1],[1,2],[2,3],[3,4]]
--   t_subsets [0,1,2,3,4] [0,1,4] == [[0,1,4]]
--   t_subsets [0,2,3,6,7] [0,1,4] == [[2,3,6]]
--   
t_subsets :: [Z12] -> [Z12] -> [[Z12]] -- | T/I-related q that are subsets of p. -- --
--   ti_subsets [0,1,2,3,4] [0,1]  == [[0,1],[1,2],[2,3],[3,4]]
--   ti_subsets [0,1,2,3,4] [0,1,4] == [[0,1,4],[0,3,4]]
--   ti_subsets [0,2,3,6,7] [0,1,4] == [[2,3,6],[3,6,7]]
--   
ti_subsets :: [Z12] -> [Z12] -> [[Z12]] -- | Trivial run length encoder. -- --
--   rle "abbcccdde" == [(1,'a'),(2,'b'),(3,'c'),(2,'d'),(1,'e')]
--   
rle :: (Eq a, Integral i) => [a] -> [(i, a)] -- | Inverse of rle. -- --
--   rle_decode [(5,'a'),(4,'b')] == "aaaaabbbb"
--   
rle_decode :: Integral i => [(i, a)] -> [a] -- | Length of rle encoded sequence. -- --
--   rle_length [(5,'a'),(4,'b')] == 9
--   
rle_length :: Integral i => [(i, a)] -> i -- | T-equivalence n-class vector (subset-class vector, nCV). -- --
--   t_n_class_vector 2 [0..4] == [4,3,2,1,0,0]
--   rle (t_n_class_vector 3 [0..4]) == [(1,3),(2,2),(2,1),(4,0),(1,1),(9,0)]
--   rle (t_n_class_vector 4 [0..4]) == [(1,2),(3,1),(39,0)]
--   
t_n_class_vector :: (Num a, Integral i) => i -> [Z12] -> [a] -- | T/I-equivalence n-class vector (subset-class vector, nCV). -- --
--   ti_n_class_vector 2 [0..4] == [4,3,2,1,0,0]
--   ti_n_class_vector 3 [0,1,2,3,4] == [3,4,2,0,0,1,0,0,0,0,0,0]
--   rle (ti_n_class_vector 4 [0,1,2,3,4]) == [(2,2),(1,1),(26,0)]
--   
ti_n_class_vector :: (Num b, Integral i) => i -> [Z12] -> [b] -- | icv scaled by sum of icv. -- --
--   dyad_class_percentage_vector [0,1,2,3,4] == [40,30,20,10,0,0]
--   dyad_class_percentage_vector [0,1,4,5,7] == [20,10,20,20,20,10]
--   
dyad_class_percentage_vector :: Integral i => [Z12] -> [i] -- | rel metric. -- --
--   rel [0,1,2,3,4] [0,1,4,5,7] == 40
--   rel [0,1,2,3,4] [0,2,4,6,8] == 60
--   rel [0,1,4,5,7] [0,2,4,6,8] == 60
--   
rel :: Integral i => [Z12] -> [Z12] -> Ratio i -- | David Lewin. "A Response to a Response: On PC Set Relatedness". -- Perspectives of New Music, 18(1-2):498-502, 1980. module Music.Theory.Z12.Lewin_1980 -- | REL function with given ncv function (see t_rel and -- ti_rel). rel :: Floating n => (Int -> [a] -> [n]) -> [a] -> [a] -> n -- | T-equivalence REL function. -- -- Kuusi 2001, 7.5.2 -- --
--   let (~=) p q = abs (p - q) < 1e-2
--   t_rel [0,1,2,3,4] [0,2,3,6,7] ~= 0.44
--   t_rel [0,1,2,3,4] [0,2,4,6,8] ~= 0.28
--   t_rel [0,2,3,6,7] [0,2,4,6,8] ~= 0.31
--   
t_rel :: Floating n => [Z12] -> [Z12] -> n -- | T/I-equivalence REL function. -- -- Buchler 1998, Fig. 3.38 -- --
--   let (~=) p q = abs (p - q) < 1e-3
--   let a = [0,2,3,5,7]::[Z12]
--   let b = [0,2,3,4,5,8]::[Z12]
--   let g = [0,1,2,3,5,6,8,10]::[Z12]
--   let j = [0,2,3,4,5,6,8]::[Z12]
--   ti_rel a b ~= 0.593
--   ti_rel a g ~= 0.648
--   ti_rel a j ~= 0.509
--   ti_rel b g ~= 0.712
--   ti_rel b j ~= 0.892
--   ti_rel g j ~= 0.707
--   
ti_rel :: Floating n => [Z12] -> [Z12] -> n -- | Serial (ordered) pitch-class operations on Z12. module Music.Theory.Z12.SRO -- | Transpose p by n. -- --
--   tn 4 [1,5,6] == [5,9,10]
--   
tn :: Z12 -> [Z12] -> [Z12] -- | Invert p about n. -- --
--   invert 6 [4,5,6] == [8,7,6]
--   invert 0 [0,1,3] == [0,11,9]
--   
invert :: Z12 -> [Z12] -> [Z12] -- | Composition of invert about 0 and tn. -- --
--   tni 4 [1,5,6] == [3,11,10]
--   (invert 0 . tn  4) [1,5,6] == [7,3,2]
--   
tni :: Z12 -> [Z12] -> [Z12] -- | Modulo 12 multiplication -- --
--   mn 11 [0,1,4,9] == tni 0 [0,1,4,9]
--   
mn :: Z12 -> [Z12] -> [Z12] -- | M5, ie. mn 5. -- --
--   m5 [0,1,3] == [0,5,3]
--   
m5 :: [Z12] -> [Z12] -- | T-related sequences of p. -- --
--   length (t_related [0,3,6,9]) == 12
--   
t_related :: [Z12] -> [[Z12]] -- | T/I-related sequences of p. -- --
--   length (ti_related [0,1,3]) == 24
--   length (ti_related [0,3,6,9]) == 24
--   ti_related [0] == map return [0..11]
--   
ti_related :: [Z12] -> [[Z12]] -- | R/T/I-related sequences of p. -- --
--   length (rti_related [0,1,3]) == 48
--   length (rti_related [0,3,6,9]) == 24
--   
rti_related :: [Z12] -> [[Z12]] -- | T/M/I-related sequences of p. tmi_related :: [Z12] -> [[Z12]] -- | R/T/M/I-related sequences of p. rtmi_related :: [Z12] -> [[Z12]] -- | r/R/T/M/I-related sequences of p. rrtmi_related :: [Z12] -> [[Z12]] -- | Variant of tn, transpose p so first element is n. -- --
--   tn_to 5 [0,1,3] == [5,6,8]
--   map (tn_to 0) [[0,1,3],[1,3,0],[3,0,1]] == [[0,1,3],[0,2,11],[0,9,10]]
--   
tn_to :: Z12 -> [Z12] -> [Z12] -- | Variant of invert, inverse about nth element. -- --
--   map (invert_ix 0) [[0,1,3],[3,4,6]] == [[0,11,9],[3,2,0]]
--   map (invert_ix 1) [[0,1,3],[3,4,6]] == [[2,1,11],[5,4,2]]
--   
invert_ix :: Int -> [Z12] -> [Z12] -- | The standard t-matrix of p. -- --
--   tmatrix [0,1,3] == [[0,1,3]
--                      ,[11,0,2]
--                      ,[9,10,0]]
--   
tmatrix :: [Z12] -> [[Z12]] -- | Robert Morris. /Composition with Pitch-Classes: A Theory of -- Compositional Design/. Yale University Press, New Haven, 1987. module Music.Theory.Z12.Morris_1987 -- | INT operator. -- --
--   int [0,1,3,6,10] == [1,2,3,4]
--   
int :: [Z12] -> [Z12] -- | Serial Operator,of the form rRTMI. data SRO SRO :: Z12 -> Bool -> Z12 -> Bool -> Bool -> SRO -- | Serial operation. -- --
--   >>> sro T4 156
--   59A
--   
-- --
--   sro (rnrtnmi "T4") (pco "156") == [5,9,10]
--   
-- --
--   >>> echo 024579 | sro RT4I
--   79B024
--   
-- --
--   sro (SRO 0 True 4 False True) [0,2,4,5,7,9] == [7,9,11,0,2,4]
--   
-- --
--   >>> sro T4I 156
--   3BA
--   
-- --
--   sro (rnrtnmi "T4I") (pco "156") == [3,11,10]
--   sro (SRO 0 False 4 False True) [1,5,6] == [3,11,10]
--   
-- --
--   >>> echo 156 | sro T4  | sro T0I
--   732
--   
-- --
--   (sro (rnrtnmi "T0I") . sro (rnrtnmi "T4")) (pco "156") == [7,3,2]
--   
-- --
--   >>> echo 024579 | sro RT4I
--   79B024
--   
-- --
--   sro (rnrtnmi "RT4I") (pco "024579") == [7,9,11,0,2,4]
--   
-- --
--   sro (SRO 1 True 1 True False) [0,1,2,3] == [11,6,1,4]
--   sro (SRO 1 False 4 True True) [0,1,2,3] == [11,6,1,4]
--   
sro :: SRO -> [Z12] -> [Z12] -- | The total set of serial operations. sros :: [Z12] -> [(SRO, [Z12])] -- | The set of transposition SROs. sro_Tn :: [SRO] -- | The set of transposition and inversion SROs. sro_TnI :: [SRO] -- | The set of retrograde and transposition and inversion SROs. sro_RTnI :: [SRO] -- | The set of transposition,M5 and inversion SROs. sro_TnMI :: [SRO] -- | The set of retrograde,transposition,M5 and inversion -- SROs. sro_RTnMI :: [SRO] instance Eq SRO instance Show SRO -- | Haskell implementations of pct operations. See -- http://slavepianos.org/rd/?t=pct. module Music.Theory.Z12.Drape_1999 -- | Cardinality filter -- --
--   cf [0,3] (cg [1..4]) == [[1,2,3],[1,2,4],[1,3,4],[2,3,4],[]]
--   
cf :: Integral n => [n] -> [[a]] -> [[a]] -- | Combinatorial sets formed by considering each set as possible values -- for slot. -- --
--   cgg [[0,1],[5,7],[3]] == [[0,5,3],[0,7,3],[1,5,3],[1,7,3]]
--   
cgg :: [[a]] -> [[a]] -- | Combinations generator, ie. synonym for powerset. -- --
--   sort (cg [0,1,3]) == [[],[0],[0,1],[0,1,3],[0,3],[1],[1,3],[3]]
--   
cg :: [a] -> [[a]] -- | Powerset filtered by cardinality. -- --
--   >>> cg -r3 0159
--   015
--   019
--   059
--   159
--   
-- --
--   cg_r 3 [0,1,5,9] == [[0,1,5],[0,1,9],[0,5,9],[1,5,9]]
--   
cg_r :: Integral n => n -> [a] -> [[a]] -- | Cyclic interval segment. ciseg :: [Z12] -> [Z12] -- | Synonynm for complement. -- --
--   >>> cmpl 02468t
--   13579B
--   
-- --
--   cmpl [0,2,4,6,8,10] == [1,3,5,7,9,11]
--   
cmpl :: [Z12] -> [Z12] -- | Form cycle. -- --
--   >>> cyc 056
--   0560
--   
-- --
--   cyc [0,5,6] == [0,5,6,0]
--   
cyc :: [a] -> [a] -- | Diatonic set name. d for diatonic set, m for melodic -- minor set, o for octotonic set. d_nm :: Integral a => [a] -> Maybe Char -- | Diatonic implications. dim :: [Z12] -> [(Z12, [Z12])] -- | Variant of dim that is closer to the pct form. -- --
--   >>> dim 016
--   T1d
--   T1m
--   T0o
--   
-- --
--   dim_nm [0,1,6] == [(1,'d'),(1,'m'),(0,'o')]
--   
dim_nm :: [Z12] -> [(Z12, Char)] -- | Diatonic interval set to interval set. -- --
--   >>> dis 24
--   1256
--   
-- --
--   dis [2,4] == [1,2,5,6]
--   
dis :: Integral t => [Int] -> [t] -- | Degree of intersection. -- --
--   >>> echo 024579e | doi 6 | sort -u
--   024579A
--   024679B
--   
-- --
--   let p = [0,2,4,5,7,9,11]
--   in doi 6 p p == [[0,2,4,5,7,9,10],[0,2,4,6,7,9,11]]
--   
-- --
--   >>> echo 01234 | doi 2 7-35 | sort -u
--   13568AB
--   
-- --
--   doi 2 (T.sc "7-35") [0,1,2,3,4] == [[1,3,5,6,8,10,11]]
--   
doi :: Int -> [Z12] -> [Z12] -> [[Z12]] -- | Forte name. fn :: [Z12] -> String -- | p has_ess q is true iff p can embed q in sequence. has_ess :: [Z12] -> [Z12] -> Bool -- | Embedded segment search. -- --
--   >>> echo 23a | ess 0164325
--   2B013A9
--   923507A
--   
-- --
--   ess [2,3,10] [0,1,6,4,3,2,5] == [[9,2,3,5,0,7,10],[2,11,0,1,3,10,9]]
--   
ess :: [Z12] -> [Z12] -> [[Z12]] -- | Can the set-class q (under prime form algorithm pf) be drawn from the -- pcset p. has_sc_pf :: Integral a => ([a] -> [a]) -> [a] -> [a] -> Bool -- | Can the set-class q be drawn from the pcset p. has_sc :: [Z12] -> [Z12] -> Bool -- | Interval cycle filter. -- --
--   >>> echo 22341 | icf
--   22341
--   
-- --
--   icf [[2,2,3,4,1]] == [[2,2,3,4,1]]
--   
icf :: (Num a, Eq a) => [[a]] -> [[a]] -- | Interval class set to interval sets. -- --
--   >>> ici -c 123
--   123
--   129
--   1A3
--   1A9
--   
-- --
--   ici_c [1,2,3] == [[1,2,3],[1,2,9],[1,10,3],[1,10,9]]
--   
ici :: Num t => [Int] -> [[t]] -- | Interval class set to interval sets, concise variant. -- --
--   ici_c [1,2,3] == [[1,2,3],[1,2,9],[1,10,3],[1,10,9]]
--   
ici_c :: [Int] -> [[Int]] -- | Interval-class segment. -- --
--   >>> icseg 013265e497t8
--   12141655232
--   
-- --
--   icseg [0,1,3,2,6,5,11,4,9,7,10,8] == [1,2,1,4,1,6,5,5,2,3,2]
--   
icseg :: [Z12] -> [Z12] -- | Interval segment (INT). iseg :: [Z12] -> [Z12] -- | Imbrications. imb :: Integral n => [n] -> [a] -> [[a]] -- | issb gives the set-classes that can append to p to -- give q. -- --
--   >>> issb 3-7 6-32
--   3-7
--   3-2
--   3-11
--   
-- --
--   issb (T.sc "3-7") (T.sc "6-32") == ["3-2","3-7","3-11"]
--   
issb :: [Z12] -> [Z12] -> [String] -- | Matrix search. -- --
--   >>> mxs 024579 642 | sort -u
--   6421B9
--   B97642
--   
-- --
--   T.set (mxs [0,2,4,5,7,9] [6,4,2]) == [[6,4,2,1,11,9],[11,9,7,6,4,2]]
--   
mxs :: [Z12] -> [Z12] -> [[Z12]] -- | Normalize. -- --
--   >>> nrm 0123456543210
--   0123456
--   
-- --
--   nrm [0,1,2,3,4,5,6,5,4,3,2,1,0] == [0,1,2,3,4,5,6]
--   
nrm :: Ord a => [a] -> [a] -- | Normalize, retain duplicate elements. nrm_r :: Ord a => [a] -> [a] -- | Pitch-class invariances (called pi at pct). -- --
--   >>> pi 0236 12
--   0236
--   6320
--   532B
--   B235
--   
-- --
--   pci [0,2,3,6] [1,2] == [[0,2,3,6],[5,3,2,11],[6,3,2,0],[11,2,3,5]]
--   
pci :: [Z12] -> [Z12] -> [[Z12]] -- | Relate sets. -- --
--   >>> rs 0123 641e
--   T1M
--   
-- --
--   import Music.Theory.Z12.Morris_1987.Parse
--   rs [0,1,2,3] [6,4,1,11] == [(rnrtnmi "T1M",[1,6,11,4])
--                              ,(rnrtnmi "T4MI",[4,11,6,1])]
--   
rs :: [Z12] -> [Z12] -> [(SRO, [Z12])] -- | Relate segments. -- --
--   >>> rsg 156 3BA
--   T4I
--   
-- --
--   rsg [1,5,6] [3,11,10] == [rnrtnmi "T4I",rnrtnmi "r1RT4MI"]
--   
-- --
--   >>> rsg 0123 05t3
--   T0M
--   
-- --
--   rsg [0,1,2,3] [0,5,10,3] == [rnrtnmi "T0M",rnrtnmi "RT3MI"]
--   
-- --
--   >>> rsg 0123 4e61
--   RT1M
--   
-- --
--   rsg [0,1,2,3] [4,11,6,1] == [rnrtnmi "T4MI",rnrtnmi "RT1M"]
--   
-- --
--   >>> echo e614 | rsg 0123
--   r3RT1M
--   
-- --
--   rsg [0,1,2,3] [11,6,1,4] == [rnrtnmi "r1T4MI",rnrtnmi "r1RT1M"]
--   
rsg :: [Z12] -> [Z12] -> [SRO] -- | Subsets. sb :: [[Z12]] -> [[Z12]] -- | Super set-class. -- --
--   >>> spsc 4-11 4-12
--   5-26[02458]
--   
-- --
--   spsc [T.sc "4-11",T.sc "4-12"] == ["5-26"]
--   
-- --
--   >>> spsc 3-11 3-8
--   4-27[0258]
--   4-Z29[0137]
--   
-- --
--   spsc [T.sc "3-11",T.sc "3-8"] == ["4-27","4-Z29"]
--   
-- --
--   >>> spsc `fl 3`
--   6-Z17[012478]
--   
-- --
--   spsc (cf [3] T.scs) == ["6-Z17"]
--   
spsc :: [[Z12]] -> [String] -- | Parsers for pitch class sets and sequences, and for SROs. module Music.Theory.Z12.Morris_1987.Parse -- | Parse a Morris format serial operator descriptor. -- --
--   rnrtnmi "r2RT3MI" == SRO 2 True 3 True True
--   
rnrtnmi :: String -> SRO -- | Parse a pitch class object string. Each Char is either a -- number, a space which is ignored, or a letter name for the numbers 10 -- (t or a or A) or 11 (e or -- B or b). -- --
--   pco "13te" == [1,3,10,11]
--   pco "13te" == pco "13ab"
--   
pco :: String -> [Z12] -- | Regular matrix array data, CSV, column & row indexing. module Music.Theory.Array.CSV -- | A indexed case-insensitive column references. The column -- following Z is AA. data Column_Ref Column_Ref :: String -> Column_Ref column_ref_string :: Column_Ref -> String -- | Inclusive range of column references. type Column_Range = (Column_Ref, Column_Ref) -- | 1-indexed row reference. type Row_Ref = Int -- | Zero index of Row_Ref. row_index :: Row_Ref -> Int -- | Inclusive range of row references. type Row_Range = (Row_Ref, Row_Ref) -- | Cell reference, column then row. type Cell_Ref = (Column_Ref, Row_Ref) -- | Inclusive range of cell references. type Cell_Range = (Cell_Ref, Cell_Ref) -- | Case folding letter to index function. Only valid for ASCII letters. -- --
--   map letter_index ['A' .. 'Z'] == [0 .. 25]
--   map letter_index ['a','d' .. 'm'] == [0,3 .. 12]
--   
letter_index :: Char -> Int -- | Inverse of letter_index. -- --
--   map index_letter [0,3 .. 12] == ['A','D' .. 'M']
--   
index_letter :: Int -> Char -- | Translate column reference to 0-index. -- --
--   :set -XOverloadedStrings
--   map column_index ["A","c","z","ac","XYZ"] == [0,2,25,28,17575]
--   
column_index :: Column_Ref -> Int -- | Column reference to interior index within specified range. Type -- specialised index. -- --
--   map (Data.Ix.index ('A','Z')) ['A','C','Z'] == [0,2,25]
--   map (interior_column_index ("A","Z")) ["A","C","Z"] == [0,2,25]
--   
-- --
--   map (Data.Ix.index ('B','C')) ['B','C'] == [0,1]
--   map (interior_column_index ("B","C")) ["B","C"] == [0,1]
--   
interior_column_index :: Column_Range -> Column_Ref -> Int -- | Inverse of column_index. -- --
--   let c = ["A","Z","AA","AZ","BA","BZ","CA"]
--   in map column_ref [0,25,26,51,52,77,78] == c
--   
-- --
--   column_ref (0+25+1+25+1+25+1) == "CA"
--   
column_ref :: Int -> Column_Ref -- | Type specialised pred. -- --
--   column_ref_pred "DF" == "DE"
--   
column_ref_pred :: Column_Ref -> Column_Ref -- | Type specialised succ. -- --
--   column_ref_succ "DE" == "DF"
--   
column_ref_succ :: Column_Ref -> Column_Ref -- | Bimap of column_index. -- --
--   column_indices ("b","p") == (1,15)
--   column_indices ("B","IT") == (1,253)
--   
column_indices :: Column_Range -> (Int, Int) -- | Type specialised range. -- --
--   column_range ("L","R") == ["L","M","N","O","P","Q","R"]
--   Data.Ix.range ('L','R') == "LMNOPQR"
--   
column_range :: Column_Range -> [Column_Ref] -- | Type specialised inRange. -- --
--   map (column_in_range ("L","R")) ["A","N","Z"] == [False,True,False]
--   map (column_in_range ("L","R")) ["L","N","R"] == [True,True,True]
--   
-- --
--   map (Data.Ix.inRange ('L','R')) ['A','N','Z'] == [False,True,False]
--   map (Data.Ix.inRange ('L','R')) ['L','N','R'] == [True,True,True]
--   
column_in_range :: Column_Range -> Column_Ref -> Bool -- | Type specialised rangeSize. -- --
--   map column_range_size [("A","Z"),("AA","ZZ")] == [26,26 * 26]
--   Data.Ix.rangeSize ('A','Z') == 26
--   
column_range_size :: Column_Range -> Int -- | Type specialised range. row_range :: Row_Range -> [Row_Ref] -- | The standard uppermost leftmost cell reference, A1. -- --
--   Just cell_ref_minima == parse_cell_ref "A1"
--   
cell_ref_minima :: Cell_Ref -- | Cell reference parser for standard notation of (column,row). -- --
--   parse_cell_ref "CC348" == Just ("CC",348)
--   
parse_cell_ref :: String -> Maybe Cell_Ref -- | Cell reference pretty printer. -- --
--   cell_ref_pp ("CC",348) == "CC348"
--   
cell_ref_pp :: Cell_Ref -> String -- | Translate cell reference to 0-indexed pair. -- --
--   cell_index ("CC",348) == (80,347)
--   Data.Ix.index (("AA",1),("ZZ",999)) ("CC",348) == 54293
--   
cell_index :: Cell_Ref -> (Int, Int) -- | Type specialised range, cells are in column-order. -- --
--   cell_range (("AA",1),("AC",1)) == [("AA",1),("AB",1),("AC",1)]
--   
-- --
--   let r = [("AA",1),("AA",2),("AB",1),("AB",2),("AC",1),("AC",2)]
--   in cell_range (("AA",1),("AC",2)) == r
--   
-- --
--   Data.Ix.range (('A',1),('C',1)) == [('A',1),('B',1),('C',1)]
--   
-- --
--   let r = [('A',1),('A',2),('B',1),('B',2),('C',1),('C',2)]
--   in Data.Ix.range (('A',1),('C',2)) == r
--   
cell_range :: Cell_Range -> [Cell_Ref] -- | Variant of cell_range in row-order. -- --
--   let r = [(AA,1),(AB,1),(AC,1),(AA,2),(AB,2),(AC,2)]
--   in cell_range_row_order (("AA",1),("AC",2)) == r
--   
cell_range_row_order :: Cell_Range -> [Cell_Ref] -- | When reading a CSV file is the first row a header? type CSV_Has_Header = Bool type CSV_Delimiter = Char type CSV_Allow_Linebreaks = Bool -- | When writing a CSV file should the delimiters be aligned, ie. should -- columns be padded with spaces, and if so at which side of the data? data CSV_Align_Columns CSV_No_Align :: CSV_Align_Columns CSV_Align_Left :: CSV_Align_Columns CSV_Align_Right :: CSV_Align_Columns -- | CSV options. type CSV_Opt = (CSV_Has_Header, CSV_Delimiter, CSV_Allow_Linebreaks, CSV_Align_Columns) -- | Default CSV options, no header, comma delimiter, no linebreaks, no -- alignment. def_csv_opt :: CSV_Opt -- | Plain list representation of a two-dimensional table of a in -- row-order. Tables are regular, ie. all rows have equal numbers of -- columns. type Table a = [[a]] -- | CSV table, ie. a table with perhaps a header. type CSV_Table a = (Maybe [String], Table a) -- | Read Table from CSV file. csv_table_read :: CSV_Opt -> (String -> a) -> FilePath -> IO (CSV_Table a) -- | Read Table only with def_csv_opt. csv_table_read' :: (String -> a) -> FilePath -> IO (Table a) -- | Read and process CSV Table. csv_table_with :: CSV_Opt -> (String -> a) -> FilePath -> (CSV_Table a -> b) -> IO b csv_table_align :: CSV_Align_Columns -> Table String -> Table String -- | Write Table to CSV file. csv_table_write :: (a -> String) -> CSV_Opt -> FilePath -> CSV_Table a -> IO () -- | Write Table only (no header). csv_table_write' :: (a -> String) -> CSV_Opt -> FilePath -> Table a -> IO () -- | 0-indexed (row,column) cell lookup. table_lookup :: Table a -> (Int, Int) -> a -- | Row data. table_row :: Table a -> Row_Ref -> [a] -- | Column data. table_column :: Table a -> Column_Ref -> [a] -- | Lookup value across columns. table_column_lookup :: Eq a => Table a -> (Column_Ref, Column_Ref) -> a -> Maybe a -- | Table cell lookup. table_cell :: Table a -> Cell_Ref -> a -- | 0-indexed (row,column) cell lookup over column range. table_lookup_row_segment :: Table a -> (Int, (Int, Int)) -> [a] -- | Range of cells from row. table_row_segment :: Table a -> (Row_Ref, Column_Range) -> [a] -- | Translate Table to Array. It is assumed that the -- Table is regular, ie. all rows have an equal number of columns. -- --
--   let a = table_to_array [[0,1,3],[2,4,5]]
--   in (bounds a,indices a,elems a)
--   
-- --
--   > (((A,1),(C,2))
--   > ,[(A,1),(A,2),(B,1),(B,2),(C,1),(C,2)]
--   > ,[0,2,1,4,3,5])
--   
table_to_array :: Table a -> Array Cell_Ref a -- | table_to_array of csv_table_read. csv_array_read :: CSV_Opt -> (String -> a) -> FilePath -> IO (Array Cell_Ref a) instance Ix Column_Ref instance Enum Column_Ref instance Ord Column_Ref instance Eq Column_Ref instance Show Column_Ref instance Read Column_Ref instance IsString Column_Ref -- | Functions for reading midi note data from CSV files. module Music.Theory.Array.CSV.Midi -- | Variant of reads requiring exact match. reads_exact :: Read a => String -> Maybe a -- | Variant of reads_exact that errors on failure. reads_err :: Read a => String -> a -- | The required header field. csv_midi_note_data_hdr :: [String] -- | Midi note data, header is time,on/off,note,velocity. -- Translation values for on/off are consulted. -- --
--   let fn = "/home/rohan/cvs/uc/uc-26/daily-practice/2014-08-13.1.csv"
--   csv_midi_note_data_read' ("ON","OFF") fn :: IO [(Double,Either String String,Double,Double)]
--   
csv_midi_note_data_read' :: (Read t, Real t, Read n, Real n) => (m, m) -> FilePath -> IO [(t, Either m String, n, n)] -- | Variant of csv_midi_note_data_read' that errors on non on/off -- data. csv_midi_note_data_read :: (Read t, Real t, Read n, Real n) => (m, m) -> FilePath -> IO [(t, m, n, n)] -- | Tseq form of csv_read_midi_note_data. midi_tseq_read :: (Read t, Real t, Read n, Real n) => FilePath -> IO (Tseq t (On_Off (n, n))) -- | Translate from Tseq form to Wseq form. midi_tseq_to_midi_wseq :: (Num t, Eq n) => Tseq t (On_Off (n, n)) -> Wseq t (n, n) -- | Off-velocity is zero. midi_wseq_to_midi_tseq :: (Num t, Ord t) => Wseq t (n, n) -> Tseq t (On_Off (n, n)) -- | Writer. csv_midi_note_data_write :: (Eq m, Show t, Real t, Show n, Real n) => (m, m) -> FilePath -> [(t, m, n, n)] -> IO () -- | Tseq form of csv_midi_note_data_write. midi_tseq_write :: (Show t, Real t, Show n, Real n) => FilePath -> Tseq t (On_Off (n, n)) -> IO ()