コードツール「フレット君」
コードを指定して、ウクレレのどのフレットを押えるか表示するツール「フレット君」を作ってみました。対応しているコードは、例えばCの場合、C、C7、Cm、Cm7、CM7、Cm7-5、Cdim、Caug、C9、Cadd9、Csus4、C7sus4です。
ダウンロード:
Windows用実行形式 + ソースコード
使い方:
コマンドプロンプトからfletkun.exeを実行します。コマンドライン引数にコードを指定します。こんな感じ。
C:\usr\home\s-tanaka\0000\haskell\fletkun>fletkun C 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- | | | C | | | | E | | | G | | | | | C ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- E | | | G | | | | | C | | | | E | | | G ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- C | | | | E | | | G | | | | | C | | | ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- G | | | | | C | | | | E | | | G | | | C:\usr\home\s-tanaka\0000\haskell\fletkun>fletkun G7 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- | | B | | | D | | | F | | G | | | | B | ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- | F | | G | | | | B | | | D | | | F | | G ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- | | D | | | F | | G | | | | B | | | D | ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- G | | | | B | | | D | | | F | | G | | | C:\usr\home\s-tanaka\0000\haskell\fletkun>fletkun Am7 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- A | | | C | | | | E | | | G | | A | | | C ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- E | | | G | | A | | | C | | | | E | | | G ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- C | | | | E | | | G | | A | | | C | | | ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---- G | | A | | | C | | | | E | | | G | | A |
ファイル: fletkun.hs
module Main (main) where import System.Environment (getArgs, getProgName) import Text.ParserCombinators.Parsec import Text.Printf (printf) data Note = C | C' | D | D' | E | F | F' | G | G' | A | A' | B deriving (Eq, Ord, Enum) instance Show Note where show C = " C " show C' = " C# " show D = " D " show D' = "D#Eb" show E = " E " show F = " F " show F' = " F# " show G = " G " show G' = "G#Ab" show A = " A " show A' = "A#Bb" show B = " B " data Code = Major Note | Minor Note | Seventh Note | Major7th Note | Minor7th Note | Minor7thb5th Note | Dim Note | Aug Note | Ninth Note | Add9th Note | SeventhSus4 Note | Sus4 Note parseCode :: String -> Code parseCode s = case parse code "" s of Right v -> v Left e -> error $ show e where code :: Parser Code code = do c <- ext =<< note eof return c note = try (string "C#" >> return C') <|> try (string "C" >> return C) <|> try (string "D#" >> return D') <|> try (string "D" >> return D) <|> try (string "Eb" >> return D') <|> try (string "E" >> return E) <|> try (string "F#" >> return F') <|> try (string "F" >> return F) <|> try (string "G#" >> return G') <|> try (string "G" >> return G) <|> try (string "Ab" >> return G') <|> try (string "A#" >> return A') <|> try (string "A" >> return A) <|> try (string "Bb" >> return A') <|> try (string "B" >> return B) ext n = try (string "m7-5" >> return (Minor7thb5th n)) <|> try (string "m7" >> return (Minor7th n)) <|> try (string "m" >> return (Minor n)) <|> try (string "7sus4" >> return (SeventhSus4 n)) <|> try (string "7" >> return (Seventh n)) <|> try (string "M7" >> return (Major7th n)) <|> try (string "dim" >> return (Dim n)) <|> try (string "aug" >> return (Aug n)) <|> try (string "9" >> return (Ninth n)) <|> try (string "add9" >> return (Add9th n)) <|> try (string "sus4" >> return (Sus4 n)) <|> try (string "" >> return (Major n)) notesFrom :: Note -> [Note] notesFrom note = dropWhile (note /=) $ cycle [C .. B] notesInCode :: Code -> [Note] notesInCode code = case code of Major n -> notesInCode' n [0, 4, 7] Minor n -> notesInCode' n [0, 3, 7] Seventh n -> notesInCode' n [0, 4, 7, 10] Major7th n -> notesInCode' n [0, 4, 7, 11] Minor7th n -> notesInCode' n [0, 3, 7, 10] Minor7thb5th n -> notesInCode' n [0, 3, 6, 10] Dim n -> notesInCode' n [0, 3, 6, 9] Aug n -> notesInCode' n [0, 3, 8] Ninth n -> notesInCode' n [0, 4, 7, 10, 14] Add9th n -> notesInCode' n [0, 4, 7, 14] SeventhSus4 n -> notesInCode' n [0, 5, 7, 10] Sus4 n -> notesInCode' n [0, 5, 7] where notesInCode' n is = map (notesFrom n !!) is printFingerBoard :: Int -> [Note] -> IO () printFingerBoard numOfFlets ns = head >> sep >> str A >> sep >> str E >> sep >> str C >> sep >> str G where join :: String -> [String] -> String join _ [] = "" join _ (x:[]) = x join s (x:xs) = x ++ concatMap (s ++) xs head = putStrLn $ join "|" $ map (printf " %2d ") [0 .. numOfFlets] sep = putStrLn $ join "+" $ replicate (numOfFlets + 1) "----" str n = putStrLn $ join "|" $ map str' $ take (numOfFlets + 1) $ notesFrom n str' n | elem n ns = show n | otherwise = " " main :: IO () main = do prog <- getProgName args <- getArgs if null args then putStrLn $ usage prog else printFingerBoard 15 $ notesInCode $ parseCode $ args !! 0 where usage p = "usage: " ++ p ++ " <code>" -- Local Variables: -- compile-command: "ghc -W -fno-warn-unused-matches --make -o fletkun fletkun" -- End:
BUGS:
表示される音が間違っていたらこっそり教えてください;-) 真面目にチェックできてません。あー、後、C6ぐらいは表示できるようにすべきでした。まぁ、またそのうち…
参照:
ぷよさんのコードフォーム検索ツール