diff options
author | Andrew Cady <d@jerkface.net> | 2014-01-17 16:43:40 -0500 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2014-01-17 16:43:52 -0500 |
commit | 4a95b04896f297019f6d62b6c46c67c9f31076c9 (patch) | |
tree | 968b5edbca85db4b5c45be4aea442f2880d8a6cf | |
parent | e804a2b7c210560fd6c62d689fd21367792e1080 (diff) |
keys have different colors depending on channel
this is disabled by a constant, but it does work
-rw-r--r-- | AlsaSeq.hs | 8 | ||||
-rw-r--r-- | axis.hs | 65 |
2 files changed, 55 insertions, 18 deletions
@@ -1,5 +1,5 @@ | |||
1 | {-# LANGUAGE NondecreasingIndentation #-} | 1 | {-# LANGUAGE NondecreasingIndentation #-} |
2 | module AlsaSeq (withAlsaInit, parseAlsaEvents, forwardNoteEvent, cmdlineAlsaConnect, printChordLn, showChord, pitchList, showPitch, unPitch) where | 2 | module AlsaSeq (withAlsaInit, parseAlsaEvents, forwardNoteEvent, cmdlineAlsaConnect, printChordLn, showChord, pitchList, showPitch, unPitch, unChannel) where |
3 | import qualified Sound.ALSA.Exception as AlsaExc | 3 | import qualified Sound.ALSA.Exception as AlsaExc |
4 | import qualified Sound.ALSA.Sequencer.Address as Addr | 4 | import qualified Sound.ALSA.Sequencer.Address as Addr |
5 | import qualified Sound.ALSA.Sequencer as SndSeq | 5 | import qualified Sound.ALSA.Sequencer as SndSeq |
@@ -27,6 +27,7 @@ import Foreign.C.Error (Errno(Errno)) | |||
27 | import Control.Exception.Base (try) | 27 | import Control.Exception.Base (try) |
28 | 28 | ||
29 | unPitch = Event.unPitch | 29 | unPitch = Event.unPitch |
30 | unChannel = Event.unChannel | ||
30 | 31 | ||
31 | printChordLn set = printWords $ pitchWords set | 32 | printChordLn set = printWords $ pitchWords set |
32 | 33 | ||
@@ -42,10 +43,9 @@ showPitch x = | |||
42 | let (octave, pitch) = Haskore.Basic.Pitch.fromInt $ fromIntegral x | 43 | let (octave, pitch) = Haskore.Basic.Pitch.fromInt $ fromIntegral x |
43 | in Haskore.Basic.Pitch.classFormat pitch (show octave) | 44 | in Haskore.Basic.Pitch.classFormat pitch (show octave) |
44 | 45 | ||
45 | -- TODO: don't filter percussion here. | ||
46 | pitchWords set = map showPitch $ pitchList set | 46 | pitchWords set = map showPitch $ pitchList set |
47 | pitchList set = map Event.unPitch $ map (\ (c, n) -> n) $ filter (\ (Event.Channel c, n) -> c /= 20) $ Set.toList set | 47 | pitchList set = map Event.unPitch $ map (\ (c, n) -> n) $ Set.toList set |
48 | pitchLists set = map (\ (c, n) -> (Event.unChannel c, Event.unPitch n)) $ filter (\ (Event.Channel c, n) -> c /= 20) $ Set.toList set | 48 | pitchLists set = map (\ (c, n) -> (Event.unChannel c, Event.unPitch n)) $ Set.toList set |
49 | 49 | ||
50 | prettyNote :: Event.Note -> String | 50 | prettyNote :: Event.Note -> String |
51 | prettyNote (Event.Note noteChannel noteNote noteVelocity noteOffVelocity noteDuration) = | 51 | prettyNote (Event.Note noteChannel noteNote noteVelocity noteOffVelocity noteDuration) = |
@@ -15,7 +15,7 @@ import Graphics.UI.SDL.Keysym as SDL.Keysym | |||
15 | import Graphics.UI.SDL.Primitives as SDL.Primitive | 15 | import Graphics.UI.SDL.Primitives as SDL.Primitive |
16 | import Data.Int (Int16) | 16 | import Data.Int (Int16) |
17 | import qualified System.Exit as Exit | 17 | import qualified System.Exit as Exit |
18 | import Data.List (elemIndex, elemIndices) | 18 | import Data.List (elemIndex, elemIndices, filter) |
19 | import GHC.Word | 19 | import GHC.Word |
20 | import Data.Bits | 20 | import Data.Bits |
21 | 21 | ||
@@ -35,18 +35,11 @@ netwireIsCool = | |||
35 | smartShowPitch p = showPitch p -- TODO: use flat for Eb, Bb; use unicode flat/sharp chars | 35 | smartShowPitch p = showPitch p -- TODO: use flat for Eb, Bb; use unicode flat/sharp chars |
36 | 36 | ||
37 | _USE_HEXAGONS = False | 37 | _USE_HEXAGONS = False |
38 | 38 | _COLORIZE_BY_CHANNEL = False | |
39 | _drawHexircle f v x y s c = | ||
40 | if _USE_HEXAGONS | ||
41 | then _drawHexagonSDL f v x y s c | ||
42 | else (if f then SDL.Primitive.filledCircle else SDL.Primitive.circle) v x y (s * 7 `div` 9) c | ||
43 | |||
44 | drawHexircle = _drawHexircle False | ||
45 | drawFilledHexircle = _drawHexircle True | ||
46 | 39 | ||
47 | _AXIS_ROWS = 7 + 4 | 40 | _AXIS_ROWS = 7 + 4 |
48 | _AXIS_UNIQUE_COLS = 7 | 41 | _AXIS_UNIQUE_COLS = 7 |
49 | _AXIS_COLS_REPEAT = 1 | 42 | _AXIS_COLS_REPEAT = 2 |
50 | _AXIS_TOP_PITCH = 81 + (7 * (_AXIS_ROWS - 7) `div` 2) | 43 | _AXIS_TOP_PITCH = 81 + (7 * (_AXIS_ROWS - 7) `div` 2) |
51 | _AXIS_BOTTOM_PITCH = 81 - (7 * _AXIS_ROWS) - 3 | 44 | _AXIS_BOTTOM_PITCH = 81 - (7 * _AXIS_ROWS) - 3 |
52 | 45 | ||
@@ -54,8 +47,39 @@ _KEY_COLOR = (SDL.Color 0 0 255) | |||
54 | _KEY_BG_COLOR = (SDL.Color 0 0 0) | 47 | _KEY_BG_COLOR = (SDL.Color 0 0 0) |
55 | _KEY_TEXT_COLOR = (SDL.Color 128 128 0) | 48 | _KEY_TEXT_COLOR = (SDL.Color 128 128 0) |
56 | 49 | ||
57 | _KEY_COLOR_PIXEL = let (SDL.Color r g b) = _KEY_COLOR in (rgbColor r g b) | 50 | _KEY_COLOR_PIXEL = colorToPixel _KEY_COLOR |
58 | _KEY_BG_COLOR_PIXEL = let (SDL.Color r g b) = _KEY_BG_COLOR in (rgbColor r g b) | 51 | _KEY_BG_COLOR_PIXEL = colorToPixel _KEY_BG_COLOR |
52 | |||
53 | {- | ||
54 | http://en.wikipedia.org/wiki/Enhanced_Graphics_Adapter | ||
55 | 0 – black (#000000) 000000 0 | ||
56 | 1 – blue (#0000AA) 000001 1 | ||
57 | 2 – green (#00AA00) 000010 2 | ||
58 | 3 – cyan (#00AAAA) 000011 3 | ||
59 | 4 – red (#AA0000) 000100 4 | ||
60 | 5 – magenta (#AA00AA) 000101 5 | ||
61 | 6 – brown (#AA5500) 010100 20 | ||
62 | 7 – white / light gray (#AAAAAA) 000111 7 | ||
63 | 8 – dark gray / bright black (#555555) 111000 56 | ||
64 | 9 – bright blue (#5555FF) 111001 57 | ||
65 | 10 – bright green (#55FF55) 111010 58 | ||
66 | 11 – bright cyan (#55FFFF) 111011 59 | ||
67 | 12 – bright red (#FF5555) 111100 60 | ||
68 | 13 – bright magenta (#FF55FF) 111101 61 | ||
69 | 14 – bright yellow (#FFFF55) 111110 62 | ||
70 | 15 – bright white (#FFFFFF) 111111 63 | ||
71 | -} | ||
72 | |||
73 | _CGA = [(SDL.Color 0x00 0x00 0x00), (SDL.Color 0x00 0x00 0xAA), (SDL.Color 0x00 0xAA 0x00), (SDL.Color 0x00 0xAA 0xAA), (SDL.Color 0xAA 0x00 0x00), (SDL.Color 0xAA 0x00 0xAA), (SDL.Color 0xAA 0x55 0x00), (SDL.Color 0xAA 0xAA 0xAA), (SDL.Color 0x55 0x55 0x55), (SDL.Color 0x55 0x55 0xFF), (SDL.Color 0x55 0xFF 0x55), (SDL.Color 0x55 0xFF 0xFF), (SDL.Color 0xFF 0x55 0x55), (SDL.Color 0xFF 0x55 0xFF), (SDL.Color 0xFF 0xFF 0x55), (SDL.Color 0xFF 0xFF 0xFF)] | ||
74 | |||
75 | _drawHexircle f v x y s c = | ||
76 | if _USE_HEXAGONS | ||
77 | then _drawHexagonSDL f v x y s c | ||
78 | else (if f then SDL.Primitive.filledCircle else SDL.Primitive.circle) v x y (s * 7 `div` 9) c | ||
79 | |||
80 | drawHexircle = _drawHexircle False | ||
81 | drawFilledHexircle = _drawHexircle True | ||
82 | colorToPixel x = let (SDL.Color r g b) = x in rgbColor r g b | ||
59 | 83 | ||
60 | drawKeys pitches videoSurface font axis_key_locations axis_key_size = do | 84 | drawKeys pitches videoSurface font axis_key_locations axis_key_size = do |
61 | 85 | ||
@@ -68,14 +92,27 @@ drawKeys pitches videoSurface font axis_key_locations axis_key_size = do | |||
68 | reallyEraseKeys = eraseKeys_ True | 92 | reallyEraseKeys = eraseKeys_ True |
69 | eraseKeys = eraseKeys_ False | 93 | eraseKeys = eraseKeys_ False |
70 | 94 | ||
95 | |||
71 | smartDrawKeys really drawSet eraseSet videoSurface font axis_key_locations axis_key_size = do | 96 | smartDrawKeys really drawSet eraseSet videoSurface font axis_key_locations axis_key_size = do |
72 | 97 | ||
73 | let drawList = map (\ (_, n) -> unPitch n) $ Set.toList drawSet | 98 | let drawList = map (\ (_, n) -> unPitch n) $ Set.toList drawSet |
74 | let eraseList = map (\ (_, n) -> unPitch n) $ Set.toList eraseSet | 99 | let eraseList = map (\ (_, n) -> unPitch n) $ filter (\ (c, _) -> unChannel c /= 9) $ Set.toList eraseSet |
75 | 100 | ||
76 | drawKeys drawList videoSurface font axis_key_locations axis_key_size | ||
77 | eraseKeys_ really eraseList videoSurface font axis_key_locations axis_key_size | 101 | eraseKeys_ really eraseList videoSurface font axis_key_locations axis_key_size |
78 | 102 | ||
103 | forM_ (Set.toList drawSet) $ \ (c, n) -> do | ||
104 | let pitch = unPitch n | ||
105 | let chann = unChannel c | ||
106 | let color = if _COLORIZE_BY_CHANNEL | ||
107 | then _CGA !! (((fromIntegral chann) + 2) `mod` 16) | ||
108 | else _KEY_COLOR | ||
109 | Control.Monad.when(chann /= 9) $ -- TODO: do this elsewhere | ||
110 | forM_ (elemIndices pitch pitchIndex) $ \idx -> do | ||
111 | let (x, y) = axis_key_locations !! idx | ||
112 | drawFilledHexircle videoSurface (fromIntegral x) (fromIntegral y) (fromIntegral axis_key_size) (colorToPixel color) | ||
113 | drawHexircle videoSurface (fromIntegral x) (fromIntegral y) (fromIntegral axis_key_size) _KEY_COLOR_PIXEL | ||
114 | centerText videoSurface x y font _KEY_TEXT_COLOR color (smartShowPitch pitch) | ||
115 | |||
79 | eraseKeys_ really pitches videoSurface font axis_key_locations axis_key_size = do | 116 | eraseKeys_ really pitches videoSurface font axis_key_locations axis_key_size = do |
80 | 117 | ||
81 | forM_ pitches $ \pitch -> do | 118 | forM_ pitches $ \pitch -> do |