-- | 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 where

import Data.List {- base -}

import qualified Music.Theory.List as T
import qualified Music.Theory.Tuning as T

k_manisrenga :: Fractional n => [n]
k_manisrenga :: forall n. Fractional n => [n]
k_manisrenga = [n
219.5,n
266.5,n
227,n
233.5,n
258.5]

k_kanjutmesem :: Fractional n => [n]
k_kanjutmesem :: forall n. Fractional n => [n]
k_kanjutmesem = [n
224,n
253.5,n
237.5,n
232.5,n
264]

k_udanriris :: Fractional n => [n]
k_udanriris :: forall n. Fractional n => [n]
k_udanriris = [n
255.5,n
256.5,n
223.5,n
235.5,n
234]

k_pengawesari :: Fractional n => [n]
k_pengawesari :: forall n. Fractional n => [n]
k_pengawesari = [n
251.5,n
233.5,n
233.5,n
236,n
250]

k_rarasrum :: Fractional n => [n]
k_rarasrum :: forall n. Fractional n => [n]
k_rarasrum = [n
229.5,n
227.5,n
253,n
232,n
261.5]

k_hardjanagara :: Fractional n => [n]
k_hardjanagara :: forall n. Fractional n => [n]
k_hardjanagara = [n
216,n
249.5,n
216,n
262,n
261.5]

k_madukentir :: Fractional n => [n]
k_madukentir :: forall n. Fractional n => [n]
k_madukentir = [n
268.5,n
242,n
243,n
230,n
221]

k_surak :: Fractional n => [n]
k_surak :: forall n. Fractional n => [n]
k_surak = [n
206,n
231.5,n
238.5,n
265,n
264.5]

-- | 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]]
k_set :: forall n. Fractional n => [[n]]
k_set = [forall n. Fractional n => [n]
k_manisrenga
        ,forall n. Fractional n => [n]
k_kanjutmesem
        ,forall n. Fractional n => [n]
k_udanriris
        ,forall n. Fractional n => [n]
k_pengawesari
        ,forall n. Fractional n => [n]
k_rarasrum
        ,forall n. Fractional n => [n]
k_hardjanagara
        ,forall n. Fractional n => [n]
k_madukentir
        ,forall n. Fractional n => [n]
k_surak]

-- | 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]
calculate_averages :: forall n. Fractional n => [[n]] -> [n]
calculate_averages [[n]]
set =
    let n :: n
n = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (t :: * -> *) a. Foldable t => t a -> Int
length [[n]]
set)
        z :: [n]
z = forall a b. (a -> b) -> [a] -> [b]
map forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (forall a. [[a]] -> [[a]]
transpose [[n]]
set)
    in forall a b. (a -> b) -> [a] -> [b]
map (forall a. Fractional a => a -> a -> a
/ n
n) [n]
z

-- | Averages of /K/ set, p. 10.
--
-- > k_averages == [233.8125,245.0625,234.0,240.8125,251.875]
k_averages :: Fractional n => [n]
k_averages :: forall n. Fractional n => [n]
k_averages = forall n. Fractional n => [[n]] -> [n]
calculate_averages forall n. Fractional n => [[n]]
k_set

gm_1,gm_2,gm_3,gm_4,gm_5,gm_6,gm_7,gm_8 :: Fractional n => [n]
gm_1 :: forall n. Fractional n => [n]
gm_1 = [n
237,n
251,n
248,n
242,n
258]
gm_2 :: forall n. Fractional n => [n]
gm_2 = [n
252,n
239,n
242,n
236.5,n
253.5]
gm_3 :: forall n. Fractional n => [n]
gm_3 = [n
237,n
238.5,n
232.5,n
262,n
238]
gm_4 :: forall n. Fractional n => [n]
gm_4 = [n
226,n
252,n
260,n
234,n
256]
gm_5 :: forall n. Fractional n => [n]
gm_5 = [n
232,n
239,n
248,n
232,n
259.5]
gm_6 :: forall n. Fractional n => [n]
gm_6 = [n
218,n
238.5,n
244.5,n
244.5,n
260]
gm_7 :: forall n. Fractional n => [n]
gm_7 = [n
238,n
230,n
257,n
243,n
250.5]
gm_8 :: forall n. Fractional n => [n]
gm_8 = [n
232,n
234,n
249,n
251,n
257]

-- | 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]]
gm_set :: forall n. Fractional n => [[n]]
gm_set = [forall n. Fractional n => [n]
gm_1,forall n. Fractional n => [n]
gm_2,forall n. Fractional n => [n]
gm_3,forall n. Fractional n => [n]
gm_4,forall n. Fractional n => [n]
gm_5,forall n. Fractional n => [n]
gm_6,forall n. Fractional n => [n]
gm_7,forall n. Fractional n => [n]
gm_8]

-- | Averages of /GM/ set, p. 10.
--
-- > gm_averages == [234.0,240.25,247.625,243.125,254.0625]
gm_averages :: Fractional n => [n]
gm_averages :: forall n. Fractional n => [n]
gm_averages = forall n. Fractional n => [[n]] -> [n]
calculate_averages forall n. Fractional n => [[n]]
gm_set

-- | Association list giving interval boundaries for interval class
-- categories (pp.10-11).
i_categories :: Num n => [((n,n),String)]
i_categories :: forall n. Num n => [((n, n), String)]
i_categories =
    [((n
206,n
238),String
"S")
    ,((n
238,n
240),String
"S-E")
    ,((n
240,n
248),String
"E")
    ,((n
248,n
250),String
"E-L")
    ,((n
250,n
269),String
"L")]

-- | Categorise an interval.
i_category :: (Ord a, Num a) => a -> String
i_category :: forall a. (Ord a, Num a) => a -> String
i_category a
x =
    let f :: a -> (a, a) -> Bool
f a
n (a
i,a
j) = a
i forall a. Ord a => a -> a -> Bool
<= a
n Bool -> Bool -> Bool
&& a
n forall a. Ord a => a -> a -> Bool
< a
j
    in forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"U" forall a b. (a, b) -> b
snd (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (forall {a}. Ord a => a -> (a, a) -> Bool
f a
x forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) forall n. Num n => [((n, n), String)]
i_categories)

-- | 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]
i_category_table :: forall a. (Ord a, Num a) => [[a]] -> [String]
i_category_table = forall a b. (a -> b) -> [a] -> [b]
map (forall a. [a] -> [[a]] -> [a]
intercalate String
"  " forall b c a. (b -> c) -> (a -> b) -> a -> c
.  forall a b. (a -> b) -> [a] -> [b]
map (forall a. a -> Int -> [a] -> [a]
T.pad_right Char
' ' Int
3 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Ord a, Num a) => a -> String
i_category))

-- | 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]
polansky_1984_r :: [Rational]
polansky_1984_r =
    let vi :: Rational
vi = Rational
12forall a. Fractional a => a -> a -> a
/Rational
7
        v :: Rational
v = Rational
128forall a. Fractional a => a -> a -> a
/Rational
147 forall a. Num a => a -> a -> a
* Rational
vi
        i' :: Rational
i' = Rational
21forall a. Fractional a => a -> a -> a
/Rational
16 forall a. Num a => a -> a -> a
* Rational
v
    in [Rational
1,Rational
8forall a. Fractional a => a -> a -> a
/Rational
7,Rational
21forall a. Fractional a => a -> a -> a
/Rational
16,Rational
v,Rational
vi,Rational
i']

-- | '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 :: [T.Cents]
polansky_1984_c :: [Cents]
polansky_1984_c = forall a b. (a -> b) -> [a] -> [b]
map forall i. Integral i => Ratio i -> Cents
T.ratio_to_cents [Rational]
polansky_1984_r