\begin{code}
module Music.Analysis.MusicXML2ABC where
import Music.Analysis.PF
import Music.Analysis.MusicXML.Level2 as Level2
import Music.Analysis.MusicXML.Level1 as Level1
import Music.Analysis.ABC as ABC
import Data.Ratio
\end{code}
\begin{code}
mk_Pitch :: Level1.Step -> ABC.Pitch
mk_Pitch x = case x of
Level1.C -> ABC.C; Level1.D -> ABC.D;
Level1.E -> ABC.E; Level1.F -> ABC.F;
Level1.G -> ABC.G; Level1.A -> ABC.A; Level1.B -> ABC.B;
mk_Accident :: Maybe Level1.Alter -> Maybe Level2.Accidental -> ABC.Accident
mk_Accident Nothing _ = ABC.Accident Nothing
mk_Accident (Just n) _ | n > 0 = ABC.Accident (Just (ABC.Sharp (truncate n)))
| n < 0 = ABC.Accident (Just (ABC.Flat (truncate n)))
| otherwise = ABC.Accident (Just (ABC.Natural))
mk_Duration :: Int -> Level2.Duration -> Maybe Level2.Type -> [Level2.Dot]
-> ABC.Duration
mk_Duration n x _ _ =
let d = duration (x%n, (0::Int) % 1)
in Duration (numerator d, denominator d)
where duration = hyloL
(maybe 0 (uncurry (+)))
(e2m . (const () -|- split p1 ((/2) >< pred)) . grd ((<=0).p2)) .
(id >< succ)
mk_Octave :: Level1.Octave -> ABC.Octave
mk_Octave o = Octave (o 4)
mk_Dotted :: [Level1.Dot] -> ABC.Dotted
mk_Dotted _ = ABC.Increase 0
mk_Note :: Int -> Level2.Note -> ABC.ABCNote
mk_Note n (Level2.Note_3 (Level2.Full_Note_1 (ax,ay,az),a2),b,c,d) =
ABC.Pitch (mk_Pitch ax) (mk_Octave az) (mk_Accident ay d)
(mk_Duration n a2 b c) (mk_Dotted c)
mk_Note n (Level2.Note_3 (Level2.Full_Note_3 _,a2),b,c,_) =
ABC.Rest True (mk_Duration n a2 b c)
mk_Music :: Level2.Score_Partwise -> ABC.ABCMusic
mk_Music musicxml =
ABC.ABCMusic (mk_MetaData musicxml) (mk_MusicDatas 1 musicxml)
mk_MusicDatas :: Int -> [[Level2.Music_Data]] -> [ABC.ABCMusicData]
mk_MusicDatas _ [] = []
mk_MusicDatas n (x:xs) =
let n' = get_Divisions_MusicData x
in mk_MusicData n x ++ ABC.Bar : mk_MusicDatas (maybe n id n') xs
mk_MetaData :: Level2.Score_Partwise -> ABC.ABCMetaData
mk_MetaData s = ABC.ABCMetaData (ABC.ABCIndex "1") (mk_Title s)
(get_Meter_MusicData (concat s))
(get_Key_MusicData (concat s))
ABC.ABCL
mk_Title :: Level2.Score_Partwise -> ABC.ABCTitle
mk_Title _ = ABC.ABCTitle "no title"
mk_Meter :: Level2.Time -> ABC.ABCMeter
mk_Meter (Level2.Time_5 l) = (ABC.ABCMeter . unwords)
(map (\((a,b),c) -> maybe "" (\y -> show y ++ "+") b ++
show a ++ "/" ++ show c) l)
get_Meter_MusicData :: [Level2.Music_Data] -> ABC.ABCMeter
get_Meter_MusicData = foldr
(\a b -> case a of;Level2.Music_Data_5 x -> get_Meter x;_ -> b) (ABC.ABCMeter "C")
get_Meter :: Level2.Attributes -> ABC.ABCMeter
get_Meter (_,_,[],_) = ABC.ABCMeter "C"
get_Meter (_,_,(x:_),_) = mk_Meter x
get_Key_MusicData :: [Level2.Music_Data] -> ABC.ABCKey
get_Key_MusicData = foldr
(\a b -> case a of;Level2.Music_Data_5 x -> get_Key x;_ -> b) (ABC.ABCKey "MusicDataC")
get_Key :: Level2.Attributes -> ABC.ABCKey
get_Key (_,[],_,_) = ABC.ABCKey "C"
get_Key (_,((Key_1 (a,b),_):_),_,_) =
ABC.ABCKey (get_KeyN (a + (maybe 0 get_Key_adjust b)) ++ maybe [] get_Key_1b b)
get_Key (_,((Key_2 [],_):_),_,_) = ABC.ABCKey "Key2"
get_Key (_,((Key_2 ((a,b):_),_):_),_,_) = ABC.ABCKey (show a ++ show b)
get_KeyN :: Int -> String
get_KeyN (8) = "Fb"
get_KeyN (7) = "Cb"
get_KeyN (6) = "Gb"
get_KeyN (5) = "Db"
get_KeyN (4) = "Ab"
get_KeyN (3) = "Eb"
get_KeyN (2) = "Bb"
get_KeyN (1) = "F"
get_KeyN 0 = "C"
get_KeyN 1 = "G"
get_KeyN 2 = "D"
get_KeyN 3 = "A"
get_KeyN 4 = "E"
get_KeyN 5 = "B"
get_KeyN 6 = "F#"
get_KeyN 7 = "C#"
get_KeyN 8 = "G#"
get_KeyN 9 = "D#"
get_KeyN 10 = "A#"
get_KeyN 11 = "E#"
get_KeyN 12 = "B#"
get_KeyN _ = "KeyN"
get_Key_1b :: Level2.Mode -> String
get_Key_1b (Major) = ""
get_Key_1b (Minor) = "m"
get_Key_1b m = take 3 (show m)
get_Key_adjust :: Level2.Mode -> Int
get_Key_adjust Major = 0
get_Key_adjust Minor = 3
get_Key_adjust Ionian = 0
get_Key_adjust Aeolian = 3
get_Key_adjust Mixolydian = 1
get_Key_adjust Dorian = 2
get_Key_adjust Phrygian = 4
get_Key_adjust Lydian = (1)
get_Key_adjust Locrian = (2)
mk_MusicData :: Int -> [Level2.Music_Data] -> [ABC.ABCMusicData]
mk_MusicData _ [] = []
mk_MusicData n ((Level2.Music_Data_1 x):xs) =
(ABC.Single (mk_Note n x)) : (mk_MusicData n xs)
mk_MusicData n ((Level2.Music_Data_5 x):xs) =
let n' = (maybe n id (get_Divisions x)) in mk_MusicData n' xs
get_Divisions :: Level2.Attributes -> Maybe Int
get_Divisions (Nothing,_,_,_) = Nothing
get_Divisions (Just n,_,_,_) = Just (n)
get_Divisions_MusicData :: [Level2.Music_Data] -> Maybe Int
get_Divisions_MusicData = foldr
(\a b -> case a of;Level2.Music_Data_5 x -> get_Divisions x;_ -> b) Nothing
\end{code}