module Music.Theory.Tuning where
import qualified Data.Fixed as Fixed
import Data.Ratio
import qualified Music.Theory.Function as T
import qualified Music.Theory.List as T
import qualified Music.Theory.Math as T
import qualified Music.Theory.Ord as T
fmidi_to_cps_k0 :: Floating a => (a,a) -> a -> a
fmidi_to_cps_k0 :: forall a. Floating a => (a, a) -> a -> a
fmidi_to_cps_k0 (a
k0,a
f0) a
i = a
f0 forall a. Num a => a -> a -> a
* (a
2 forall a. Floating a => a -> a -> a
** ((a
i forall a. Num a => a -> a -> a
- a
k0) forall a. Num a => a -> a -> a
* (a
1 forall a. Fractional a => a -> a -> a
/ a
12)))
fmidi_to_cps_f0 :: Floating a => a -> a -> a
fmidi_to_cps_f0 :: forall a. Floating a => a -> a -> a
fmidi_to_cps_f0 a
f0 = forall a. Floating a => (a, a) -> a -> a
fmidi_to_cps_k0 (a
69,a
f0)
fmidi_to_cps :: Floating a => a -> a
fmidi_to_cps :: forall a. Floating a => a -> a
fmidi_to_cps = forall a. Floating a => (a, a) -> a -> a
fmidi_to_cps_k0 (a
69,a
440)
midi_to_cps_k0 :: (Integral i,Floating f) => (f,f) -> i -> f
midi_to_cps_k0 :: forall i f. (Integral i, Floating f) => (f, f) -> i -> f
midi_to_cps_k0 (f, f)
o = forall a. Floating a => (a, a) -> a -> a
fmidi_to_cps_k0 (f, f)
o forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral
midi_to_cps :: (Integral i,Floating f) => i -> f
midi_to_cps :: forall i f. (Integral i, Floating f) => i -> f
midi_to_cps = forall i f. (Integral i, Floating f) => (f, f) -> i -> f
midi_to_cps_k0 (f
69,f
440)
cents_to_fratio :: Floating a => a -> a
cents_to_fratio :: forall a. Floating a => a -> a
cents_to_fratio a
n = a
2 forall a. Floating a => a -> a -> a
** (a
n forall a. Fractional a => a -> a -> a
/ a
1200)
fratio_to_cents :: (Real r,Floating n) => r -> n
fratio_to_cents :: forall r n. (Real r, Floating n) => r -> n
fratio_to_cents = (n
1200 forall a. Num a => a -> a -> a
*) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Floating a => a -> a -> a
logBase n
2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Real a, Fractional b) => a -> b
realToFrac
cps_shift_cents :: Floating a => a -> a -> a
cps_shift_cents :: forall a. Floating a => a -> a -> a
cps_shift_cents a
f = (forall a. Num a => a -> a -> a
* a
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Floating a => a -> a
cents_to_fratio
cps_difference_cents :: (Real r,Fractional r,Floating n) => r -> r -> n
cps_difference_cents :: forall r n. (Real r, Fractional r, Floating n) => r -> r -> n
cps_difference_cents r
p r
q = forall r n. (Real r, Floating n) => r -> n
fratio_to_cents (r
q forall a. Fractional a => a -> a -> a
/ r
p)
oct_diff_to_ratio :: Integral a => Ratio a -> Int -> Ratio a
oct_diff_to_ratio :: forall a. Integral a => Ratio a -> Int -> Ratio a
oct_diff_to_ratio Ratio a
r Int
n = if Int
n forall a. Ord a => a -> a -> Bool
>= Int
0 then forall n t. Integral n => n -> (t -> t) -> t -> t
T.recur_n Int
n (forall a. Num a => a -> a -> a
* Ratio a
r) Ratio a
1 else forall n t. Integral n => n -> (t -> t) -> t -> t
T.recur_n (forall a. Num a => a -> a
negate Int
n) (forall a. Fractional a => a -> a -> a
/ Ratio a
r) Ratio a
1
ratio_to_pc :: Int -> Rational -> Int
ratio_to_pc :: Int -> Rational -> Int
ratio_to_pc Int
n = forall i. Integral i => i -> i
T.mod12 forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
+ Int
n) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (RealFrac a, Integral b) => a -> b
round forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Fractional a => a -> a -> a
/ Approximate_Ratio
100) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i. Integral i => Ratio i -> Approximate_Ratio
ratio_to_cents
fold_ratio_to_octave_nonrec :: (Ord n,Fractional n) => n -> n
fold_ratio_to_octave_nonrec :: forall n. (Ord n, Fractional n) => n -> n
fold_ratio_to_octave_nonrec n
n =
if n
n forall a. Ord a => a -> a -> Bool
>= n
1 Bool -> Bool -> Bool
&& n
n forall a. Ord a => a -> a -> Bool
< n
2
then n
n
else if n
n forall a. Ord a => a -> a -> Bool
>= n
2 Bool -> Bool -> Bool
&& n
n forall a. Ord a => a -> a -> Bool
< n
4
then n
n forall a. Fractional a => a -> a -> a
/ n
2
else if n
n forall a. Ord a => a -> a -> Bool
< n
1 Bool -> Bool -> Bool
&& n
n forall a. Ord a => a -> a -> Bool
>= (n
1forall a. Fractional a => a -> a -> a
/n
2)
then n
n forall a. Num a => a -> a -> a
* n
2
else forall a. HasCallStack => [Char] -> a
error [Char]
"fold_ratio_to_octave_nonrec"
fold_ratio_to_octave_err :: (Ord n,Fractional n) => n -> n
fold_ratio_to_octave_err :: forall n. (Ord n, Fractional n) => n -> n
fold_ratio_to_octave_err =
let f :: a -> a
f a
n =
if a
n forall a. Ord a => a -> a -> Bool
<= a
0
then forall a. HasCallStack => [Char] -> a
error [Char]
"fold_ratio_to_octave_err?"
else if a
n forall a. Ord a => a -> a -> Bool
>= a
2 then a -> a
f (a
n forall a. Fractional a => a -> a -> a
/ a
2) else if a
n forall a. Ord a => a -> a -> Bool
< a
1 then a -> a
f (a
n forall a. Num a => a -> a -> a
* a
2) else a
n
in forall n. (Ord n, Fractional n) => n -> n
f
fold_ratio_to_octave :: (Ord n,Fractional n) => n -> Maybe n
fold_ratio_to_octave :: forall n. (Ord n, Fractional n) => n -> Maybe n
fold_ratio_to_octave n
n = if n
n forall a. Ord a => a -> a -> Bool
<= n
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall n. (Ord n, Fractional n) => n -> n
fold_ratio_to_octave_err n
n)
ratio_interval_class_by :: (Ord t, Integral i) => (Ratio i -> t) -> Ratio i -> Ratio i
ratio_interval_class_by :: forall t i.
(Ord t, Integral i) =>
(Ratio i -> t) -> Ratio i -> Ratio i
ratio_interval_class_by Ratio i -> t
cmp_f Ratio i
i =
let f :: Ratio i -> Ratio i
f = forall n. (Ord n, Fractional n) => n -> n
fold_ratio_to_octave_err
in forall a t. Ord a => (t -> a) -> t -> t -> t
T.min_by Ratio i -> t
cmp_f (Ratio i -> Ratio i
f Ratio i
i) (Ratio i -> Ratio i
f (forall a. Fractional a => a -> a
recip Ratio i
i))
ratio_interval_class :: Integral i => Ratio i -> Ratio i
ratio_interval_class :: forall i. Integral i => Ratio i -> Ratio i
ratio_interval_class = forall t i.
(Ord t, Integral i) =>
(Ratio i -> t) -> Ratio i -> Ratio i
ratio_interval_class_by forall t. Integral t => Ratio t -> t
T.ratio_nd_sum
type Approximate_Ratio = Double
approximate_ratio :: Rational -> Approximate_Ratio
approximate_ratio :: Rational -> Approximate_Ratio
approximate_ratio = forall a. Fractional a => Rational -> a
fromRational
type Cents = Double
type Cents_I = Int
approximate_ratio_to_cents :: Approximate_Ratio -> Cents
approximate_ratio_to_cents :: Approximate_Ratio -> Approximate_Ratio
approximate_ratio_to_cents = forall r n. (Real r, Floating n) => r -> n
fratio_to_cents
ratio_to_cents :: Integral i => Ratio i -> Cents
ratio_to_cents :: forall i. Integral i => Ratio i -> Approximate_Ratio
ratio_to_cents = Approximate_Ratio -> Approximate_Ratio
approximate_ratio_to_cents forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Real a, Fractional b) => a -> b
realToFrac
reconstructed_ratio :: Double -> Cents -> Rational
reconstructed_ratio :: Approximate_Ratio -> Approximate_Ratio -> Rational
reconstructed_ratio Approximate_Ratio
epsilon Approximate_Ratio
c = forall a. RealFrac a => a -> a -> Rational
approxRational (forall a. Floating a => a -> a
cents_to_fratio Approximate_Ratio
c) Approximate_Ratio
epsilon
syntonic_comma :: Rational
syntonic_comma :: Rational
syntonic_comma = Integer
81 forall a. Integral a => a -> a -> Ratio a
% Integer
80
pythagorean_comma :: Rational
pythagorean_comma :: Rational
pythagorean_comma = Rational
531441 forall a. Fractional a => a -> a -> a
/ Rational
524288
mercators_comma :: Rational
mercators_comma :: Rational
mercators_comma = Rational
19383245667680019896796723 forall a. Fractional a => a -> a -> a
/ Rational
19342813113834066795298816
twelve_tone_equal_temperament_comma :: (Floating a,Eq a) => a
twelve_tone_equal_temperament_comma :: forall a. (Floating a, Eq a) => a
twelve_tone_equal_temperament_comma = a
12 forall a. (Floating a, Eq a) => a -> a -> a
`T.nth_root` a
2
cents_et12_diff :: Integral n => n -> n
cents_et12_diff :: forall i. Integral i => i -> i
cents_et12_diff n
n =
let m :: n
m = n
n forall a. Integral a => a -> a -> a
`mod` n
100
in if n
m forall a. Ord a => a -> a -> Bool
> n
50 then n
m forall a. Num a => a -> a -> a
- n
100 else n
m
fcents_et12_diff :: Real n => n -> n
fcents_et12_diff :: forall n. Real n => n -> n
fcents_et12_diff n
n =
let m :: n
m = n
n forall a. Real a => a -> a -> a
`Fixed.mod'` n
100
in if n
m forall a. Ord a => a -> a -> Bool
> n
50 then n
m forall a. Num a => a -> a -> a
- n
100 else n
m
cents_interval_class :: Integral a => a -> a
cents_interval_class :: forall i. Integral i => i -> i
cents_interval_class a
n =
let n' :: a
n' = a
n forall a. Integral a => a -> a -> a
`mod` a
1200
in if a
n' forall a. Ord a => a -> a -> Bool
> a
600 then a
1200 forall a. Num a => a -> a -> a
- a
n' else a
n'
fcents_interval_class :: Real a => a -> a
fcents_interval_class :: forall n. Real n => n -> n
fcents_interval_class a
n =
let n' :: a
n' = a
n forall a. Real a => a -> a -> a
`Fixed.mod'` a
1200
in if a
n' forall a. Ord a => a -> a -> Bool
> a
600 then a
1200 forall a. Num a => a -> a -> a
- a
n' else a
n'
cents_diff_pp :: (Num a, Ord a, Show a) => a -> String
cents_diff_pp :: forall a. (Num a, Ord a, Show a) => a -> [Char]
cents_diff_pp a
n =
case forall a. Ord a => a -> a -> Ordering
compare a
n a
0 of
Ordering
LT -> forall a. Show a => a -> [Char]
show a
n
Ordering
EQ -> [Char]
""
Ordering
GT -> Char
'+' forall a. a -> [a] -> [a]
: forall a. Show a => a -> [Char]
show a
n
cents_diff_br :: (Num a, Ord a, Show a) => (String,String) -> a -> String
cents_diff_br :: forall a. (Num a, Ord a, Show a) => ([Char], [Char]) -> a -> [Char]
cents_diff_br ([Char], [Char])
br =
let f :: [Char] -> [Char]
f [Char]
s = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
s then [Char]
s else forall a. ([a], [a]) -> [a] -> [a]
T.bracket_l ([Char], [Char])
br [Char]
s
in [Char] -> [Char]
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Num a, Ord a, Show a) => a -> [Char]
cents_diff_pp
cents_diff_text :: (Num a, Ord a, Show a) => a -> String
cents_diff_text :: forall a. (Num a, Ord a, Show a) => a -> [Char]
cents_diff_text = forall a. (Num a, Ord a, Show a) => ([Char], [Char]) -> a -> [Char]
cents_diff_br ([Char]
"(",[Char]
")")
cents_diff_md :: (Num a, Ord a, Show a) => a -> String
cents_diff_md :: forall a. (Num a, Ord a, Show a) => a -> [Char]
cents_diff_md = forall a. (Num a, Ord a, Show a) => ([Char], [Char]) -> a -> [Char]
cents_diff_br ([Char]
"^",[Char]
"^")
cents_diff_html :: (Num a, Ord a, Show a) => a -> String
cents_diff_html :: forall a. (Num a, Ord a, Show a) => a -> [Char]
cents_diff_html = forall a. (Num a, Ord a, Show a) => ([Char], [Char]) -> a -> [Char]
cents_diff_br ([Char]
"<SUP>",[Char]
"</SUP>")
type Savarts = Double
fratio_to_savarts :: Floating a => a -> a
fratio_to_savarts :: forall a. Floating a => a -> a
fratio_to_savarts a
r = a
1000 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a -> a
logBase a
10 a
r
savarts_to_fratio :: Floating a => a -> a
savarts_to_fratio :: forall a. Floating a => a -> a
savarts_to_fratio a
s = a
10 forall a. Floating a => a -> a -> a
** (a
s forall a. Fractional a => a -> a -> a
/ a
1000)
savarts_to_cents :: Floating a => a -> a
savarts_to_cents :: forall a. Floating a => a -> a
savarts_to_cents a
s = a
s forall a. Num a => a -> a -> a
* (a
6 forall a. Fractional a => a -> a -> a
/ (a
5 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a -> a
logBase a
10 a
2))
cents_to_savarts :: Floating a => a -> a
cents_to_savarts :: forall a. Floating a => a -> a
cents_to_savarts a
c = a
c forall a. Fractional a => a -> a -> a
/ (a
6 forall a. Fractional a => a -> a -> a
/ (a
5 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a -> a
logBase a
10 a
2))