module Music.Theory.Tuning.Scala.Interval where
import Data.Char
import Data.List
import Data.Maybe
import qualified Music.Theory.Read as Read
import qualified Music.Theory.Tuning.Scala as Scala
type INTERVAL = (Rational,String)
type INTNAM = (Int,[INTERVAL])
intnam_search_ratio :: INTNAM -> Rational -> Maybe INTERVAL
intnam_search_ratio :: INTNAM -> Rational -> Maybe INTERVAL
intnam_search_ratio (Int
_,[INTERVAL]
i) Rational
x = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((forall a. Eq a => a -> a -> Bool
== Rational
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [INTERVAL]
i
intnam_search_fratio :: (Fractional n,Ord n) => n -> INTNAM -> n -> Maybe INTERVAL
intnam_search_fratio :: forall n.
(Fractional n, Ord n) =>
n -> INTNAM -> n -> Maybe INTERVAL
intnam_search_fratio n
epsilon (Int
_,[INTERVAL]
i) n
x =
let near :: n -> n -> Bool
near n
p n
q = forall a. Num a => a -> a
abs (n
p forall a. Num a => a -> a -> a
- n
q) forall a. Ord a => a -> a -> Bool
< n
epsilon
in forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (n -> n -> Bool
near n
x forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Fractional a => Rational -> a
fromRational forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [INTERVAL]
i
intnam_search_ratio_name_err :: INTNAM -> Rational -> String
intnam_search_ratio_name_err :: INTNAM -> Rational -> String
intnam_search_ratio_name_err INTNAM
db = forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HasCallStack => Maybe a -> a
fromJust forall b c a. (b -> c) -> (a -> b) -> a -> c
. INTNAM -> Rational -> Maybe INTERVAL
intnam_search_ratio INTNAM
db
intnam_search_description_ci :: INTNAM -> String -> [INTERVAL]
intnam_search_description_ci :: INTNAM -> String -> [INTERVAL]
intnam_search_description_ci (Int
_,[INTERVAL]
i) String
x =
let downcase :: String -> String
downcase = forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower
x' :: String
x' = String -> String
downcase String
x
in forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Eq a => [a] -> [a] -> Bool
isInfixOf String
x' forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
downcase forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) [INTERVAL]
i
parse_intnam_entry :: String -> INTERVAL
parse_intnam_entry :: String -> INTERVAL
parse_intnam_entry String
str =
case String -> [String]
words String
str of
String
r:[String]
w -> (forall i. (Integral i, Read i) => String -> Ratio i
Read.read_ratio_with_div_err String
r,[String] -> String
unwords [String]
w)
[String]
_ -> forall a. HasCallStack => String -> a
error String
"parse_intnam_entry"
parse_intnam :: [String] -> INTNAM
parse_intnam :: [String] -> INTNAM
parse_intnam [String]
l =
case [String]
l of
String
_:String
n:[String]
i -> let n' :: Int
n' = forall a. Read a => String -> a
read String
n :: Int
i' :: [INTERVAL]
i' = forall a b. (a -> b) -> [a] -> [b]
map String -> INTERVAL
parse_intnam_entry [String]
i
in if Int
n' forall a. Eq a => a -> a -> Bool
== forall (t :: * -> *) a. Foldable t => t a -> Int
length [INTERVAL]
i' then (Int
n',[INTERVAL]
i') else forall a. HasCallStack => String -> a
error String
"parse_intnam"
[String]
_ -> forall a. HasCallStack => String -> a
error String
"parse_intnam"
load_intnam :: IO INTNAM
load_intnam :: IO INTNAM
load_intnam = do
[String]
l <- String -> IO [String]
Scala.load_dist_file_ln String
"intnam.par"
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> INTNAM
parse_intnam ([String] -> [String]
Scala.filter_comments [String]
l))