summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2014-01-17 05:42:53 -0500
committerAndrew Cady <d@jerkface.net>2014-01-17 05:42:53 -0500
commit4d4f7d74c370040ee102367d1c06953aa33896b9 (patch)
treec3fd93505280194f8bc0f87722f3565bf7ba36cd
parent5736ae0a30c2a4844c0f26d6847356193482ee61 (diff)
live playback works! connect via aplaymidi to play midi files
-rw-r--r--axis.hs92
1 files changed, 67 insertions, 25 deletions
diff --git a/axis.hs b/axis.hs
index 3108779..bfbe169 100644
--- a/axis.hs
+++ b/axis.hs
@@ -16,6 +16,8 @@ import Graphics.UI.SDL.Primitives as SDL.Primitive
16import Data.Int (Int16) 16import Data.Int (Int16)
17import qualified System.Exit as Exit 17import qualified System.Exit as Exit
18import Data.List (elemIndex, elemIndices) 18import Data.List (elemIndex, elemIndices)
19import GHC.Word
20import Data.Bits
19 21
20netwireIsCool :: (Monad m) => Wire (Timed NominalDiffTime ()) () m a String 22netwireIsCool :: (Monad m) => Wire (Timed NominalDiffTime ()) () m a String
21netwireIsCool = 23netwireIsCool =
@@ -30,6 +32,44 @@ netwireIsCool =
30 holdFor 0.5 . periodic 1 . pure "Hoo..." <|> 32 holdFor 0.5 . periodic 1 . pure "Hoo..." <|>
31 pure "...ray!" 33 pure "...ray!"
32 34
35smartShowPitch p = showPitch p -- TODO: use flat for Eb, Bb; use unicode flat/sharp chars
36
37_USE_HEXAGONS = True
38
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` 8) c
43
44drawHexircle = _drawHexircle False
45drawFilledHexircle = _drawHexircle True
46
47_KEY_COLOR = (SDL.Color 0 0 255)
48_KEY_BG_COLOR = (SDL.Color 0 0 0)
49_KEY_TEXT_COLOR = (SDL.Color 128 128 0)
50
51_KEY_COLOR_PIXEL = let (SDL.Color r g b) = _KEY_COLOR in (rgbColor r g b)
52_KEY_BG_COLOR_PIXEL = let (SDL.Color r g b) = _KEY_BG_COLOR in (rgbColor r g b)
53
54drawKeys pitches videoSurface font axis_key_locations axis_key_size = do
55
56 forM_ pitches $ \pitch -> do
57 forM_ (elemIndices pitch pitchIndex) $ \idx -> do
58 let (x, y) = axis_key_locations !! idx
59 drawFilledHexircle videoSurface (fromIntegral x) (fromIntegral y) (fromIntegral axis_key_size) _KEY_COLOR_PIXEL
60 centerText videoSurface x y font _KEY_TEXT_COLOR _KEY_COLOR (smartShowPitch pitch)
61
62eraseKeys pitches videoSurface font axis_key_locations axis_key_size = do
63
64 forM_ pitches $ \pitch -> do
65 forM_ (elemIndices pitch pitchIndex) $ \idx -> do
66 let (x, y) = axis_key_locations !! idx
67 drawFilledHexircle videoSurface (fromIntegral x) (fromIntegral y) (fromIntegral axis_key_size) _KEY_BG_COLOR_PIXEL
68 drawHexircle videoSurface (fromIntegral x) (fromIntegral y) (fromIntegral axis_key_size) _KEY_COLOR_PIXEL
69
70fi = fromIntegral
71rgbColor r g b = SDL.Pixel (shiftL (fi r) 24 .|. shiftL (fi g) 16 .|. shiftL (fi b) 8 .|. (fi 255))
72
33main = 73main =
34 withAlsaInit $ \h public private q publicAddr privateAddr -> do 74 withAlsaInit $ \h public private q publicAddr privateAddr -> do
35 cmdlineAlsaConnect h public -- fail early if bad command lines 75 cmdlineAlsaConnect h public -- fail early if bad command lines
@@ -51,20 +91,15 @@ main =
51 _ <- SDL.grabInput True 91 _ <- SDL.grabInput True
52 warpMouse 92 warpMouse
53 93
54 let pixelFormat = SDL.surfaceGetPixelFormat videoSurface 94--let pixelFormat = SDL.surfaceGetPixelFormat videoSurface
55 blue <- SDL.mapRGB pixelFormat 0 255 255 -- why is it blue??? 95 pixelFormat <- SDL.surfaceGetPixelFormat <$> SDL.createRGBSurfaceEndian [] 1 1 24
56 -- _ <- SDL.setRelativeMouseMode True -- SDL2. Should I use it? 96 -- _ <- SDL.setRelativeMouseMode True -- SDL2. Should I use it?
57 97
58 let (axis_key_size, axis_key_locations) = getKeyLocations videoClipRect 98 let (axis_key_size, axis_key_locations) = getKeyLocations videoClipRect
59 99
60 forM_ axis_key_locations $ \(x, y) -> do 100 let allPitches = map (+ 35) [0 .. 49]
61 --SDL.Primitive.filledCircle videoSurface (fromIntegral x) (fromIntegral y) (fromIntegral axis_key_size) blue >>= return 101--drawKeys allPitches videoSurface font blue axis_key_locations axis_key_size
62 drawHexagonSDL videoSurface (fromIntegral x) (fromIntegral y) (fromIntegral axis_key_size) blue >>= return 102 eraseKeys allPitches videoSurface font axis_key_locations axis_key_size
63
64 forM_ [0 .. length axis_key_locations - 1] $ \i -> do
65 let (centerx, centery) = axis_key_locations !! i
66 centerText videoSurface centerx centery font (showPitch $ pitchIndex !! i)
67-- centerText videoSurface centerx centery font (show i)
68 103
69 putStrLn "Initialized." 104 putStrLn "Initialized."
70 105
@@ -77,22 +112,28 @@ main =
77 let x' = either (const "") id ex 112 let x' = either (const "") id ex
78 113
79 Control.Monad.when (x /= x' && x' /= "") $ do 114 Control.Monad.when (x /= x' && x' /= "") $ do
80 textBand videoSurface videoClipRect (SDL.Rect 0 0 0 70) font x' 115-- textBand videoSurface videoClipRect (SDL.Rect 0 0 0 70) font x'
81 return () 116 return ()
82 117
83 Control.Monad.when (midiKeysDown' /= midiKeysDown) $ do 118 Control.Monad.when (midiKeysDown' /= midiKeysDown) $ do
84 --let chord = showChord midiKeysDown' 119 --let chord = showChord midiKeysDown'
85 --let chord = show $ pitchList midiKeysDown' 120 --let chord = show $ pitchList midiKeysDown'
121 let ignoreThese = Set.intersection midiKeysDown' midiKeysDown
122 let drawThese = pitchList $ Set.difference midiKeysDown' ignoreThese
123 let eraseThese = pitchList $ Set.difference midiKeysDown ignoreThese
124
86 let chord = show $ map (\i->elemIndices i pitchIndex) $ pitchList midiKeysDown' 125 let chord = show $ map (\i->elemIndices i pitchIndex) $ pitchList midiKeysDown'
87 textBand videoSurface videoClipRect (SDL.Rect 0 70 0 70) font chord 126 drawKeys drawThese videoSurface font axis_key_locations axis_key_size
127 eraseKeys eraseThese videoSurface font axis_key_locations axis_key_size
128-- textBand videoSurface videoClipRect (SDL.Rect 0 70 0 70) font chord
88 return () 129 return ()
89 130
90 Control.Monad.when (keysDown' /= keysDown) $ do 131-- Control.Monad.when (keysDown' /= keysDown) $ do
91 let chord = unwords $ map (\k -> drop 5 (show k)) $ Set.toList keysDown' 132-- let chord = unwords $ map (\k -> drop 5 (show k)) $ Set.toList keysDown'
92 textBand videoSurface videoClipRect (SDL.Rect 0 210 0 70) font chord 133-- textBand videoSurface videoClipRect (SDL.Rect 0 210 0 70) font chord
93 textBand videoSurface videoClipRect (SDL.Rect 0 280 0 70) font $ 134-- textBand videoSurface videoClipRect (SDL.Rect 0 280 0 70) font $
94 if keyDown SDL.SDLK_a keysDown' then "arpeggiate" else "" 135-- if keyDown SDL.SDLK_a keysDown' then "arpeggiate" else ""
95 return () 136-- return ()
96 137
97 Control.Monad.when(False) $ do 138 Control.Monad.when(False) $ do
98 139
@@ -114,24 +155,25 @@ main =
114 155
115zipzip ls = if (head ls) == [] then [] else (map head ls) : (zipzip $ map tail ls) 156zipzip ls = if (head ls) == [] then [] else (map head ls) : (zipzip $ map tail ls)
116 157
117drawHexagonSDL videoSurface centerx centery radius pixel = do 158drawHexagonSDL = _drawHexagonSDL False
159drawFilledHexagonSDL = _drawHexagonSDL True
160
161_drawHexagonSDL filled videoSurface centerx centery radius pixel = do
118 let r = fromIntegral radius 162 let r = fromIntegral radius
119--let points = map (\(x, y) -> (centerx + x + radius `div` 2, centery + y + radius `div` 2)) $
120 let points = map (\(x, y) -> (centerx + x, centery + y)) $ 163 let points = map (\(x, y) -> (centerx + x, centery + y)) $
121 map (\(x, y) -> (round x, round y)) $ 164 map (\(x, y) -> (round x, round y)) $
122 map (\i -> (r * cos(pi/3 * (i)), r * sin(pi/3 * (i)))) $ map fromIntegral [0 .. 5] 165 map (\i -> (r * cos(pi/3 * (i)), r * sin(pi/3 * (i)))) $ map fromIntegral [0 .. 5]
123 --filledPolygon :: Surface -> [(Int16, Int16)] -> Pixel -> IO Bool 166 (if not filled then SDL.Primitive.polygon else SDL.Primitive.filledPolygon) videoSurface points pixel
124 SDL.Primitive.polygon videoSurface points pixel >>= return
125 return ()
126 167
127centerText videoSurface x y font text = do 168centerText videoSurface x y font fgColor bgColor text = do
128--fontSurface <- SDL.TTF.renderUTF8Shaded font text (SDL.Color 0 255 0) (SDL.Color 80 80 80) -- useful for testing 169--fontSurface <- SDL.TTF.renderUTF8Shaded font text (SDL.Color 0 255 0) (SDL.Color 80 80 80) -- useful for testing
129 fontSurface <- SDL.TTF.renderUTF8Shaded font text (SDL.Color 0 255 0) (SDL.Color 0 0 0) 170 fontSurface <- SDL.TTF.renderUTF8Shaded font text fgColor bgColor
130 fontClipRect <- SDL.getClipRect fontSurface 171 fontClipRect <- SDL.getClipRect fontSurface
131 let (SDL.Rect _ _ w h) = fontClipRect 172 let (SDL.Rect _ _ w h) = fontClipRect
132 _ <- SDL.blitSurface fontSurface (Just fontClipRect) videoSurface (Just (SDL.Rect (fromIntegral(x) - w `div` 2) (fromIntegral(y) - h `div` 2) w h)) 173 _ <- SDL.blitSurface fontSurface (Just fontClipRect) videoSurface (Just (SDL.Rect (fromIntegral(x) - w `div` 2) (fromIntegral(y) - h `div` 2) w h))
133 return () 174 return ()
134 175
176-- TODO: make this generalize to different grid sizes
135colfrom top = map (+ top) $ map (* (-7)) [0 .. 6] 177colfrom top = map (+ top) $ map (* (-7)) [0 .. 6]
136pitchIndex = (\x -> x ++ x) $ concat $ map colfrom [81, 78, 82, 79, 83, 80, 84] 178pitchIndex = (\x -> x ++ x) $ concat $ map colfrom [81, 78, 82, 79, 83, 80, 84]
137 179