dear-implot.hs/Main.hs
Tristan Cacqueray 1fc62e7fc1 Add demo
2021-02-21 23:12:07 +00:00

109 lines
2.9 KiB
Haskell

{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
module Main (main) where
import Control.Exception
import Control.Monad.IO.Class
import Control.Monad.Managed
import Data.Binary.Get (getInt16le, isEmpty, runGet)
import qualified Data.ByteString as BS
import Data.ByteString.Lazy (fromStrict)
import Data.List (iterate')
import DearImGui
import DearImGui.OpenGL2
import qualified DearImGui.Plot as ImPlot
import DearImGui.SDL
import DearImGui.SDL.OpenGL
import GHC.Float (int2Float)
import GHC.Int (Int16)
import Graphics.GL
import Pipes
import Pipes.PulseSimple
import Pipes.Safe (runSafeT)
import SDL
main :: IO ()
main = do
-- Initialize SDL
initializeAll
runManaged do
-- Create a window using SDL. As we're using OpenGL, we need to enable OpenGL too.
win <- do
let title = "Hello, Dear ImGui!"
let config = defaultWindow {windowGraphicsContext = OpenGLContext defaultOpenGL}
managed $ bracket (createWindow title config) destroyWindow
-- Create an OpenGL context
glContext <- managed $ bracket (glCreateContext win) glDeleteContext
-- Create an ImGui context
_ <- managed $ bracket createContext destroyContext
-- Create an ImPlot context
_ <- managed $ bracket ImPlot.createContext ImPlot.destroyContext
-- Initialize ImGui's SDL2 backend
_ <- managed_ $ bracket_ (sdl2InitForOpenGL win glContext) sdl2Shutdown
-- Initialize ImGui's OpenGL backend
_ <- managed_ $ bracket_ openGL2Init openGL2Shutdown
liftIO $ runSafeT (runEffect (readPulse "dear-pulse" Nothing 25 >-> mainLoop win))
-- | Binary decoder
decodeSampleList :: BS.ByteString -> [Int16]
decodeSampleList = runGet get . fromStrict
where
get = do
empty <- isEmpty
if empty
then return []
else do
sample <- getInt16le
rest <- get
return (sample : rest)
mainLoop :: MonadIO m => Window -> Consumer' BS.ByteString m ()
mainLoop win = do
-- Process the event loop
untilNothingM pollEventWithImGui
-- Get audio buffer
buf <- await
let maxInt16 :: Int16
maxInt16 = maxBound
maxInt16f = int2Float $ fromIntegral maxInt16
samples :: [Float]
samples = map (\x' -> int2Float (fromIntegral x') / maxInt16f) $ decodeSampleList buf
-- Tell ImGui we're starting a new frame
openGL2NewFrame
sdl2NewFrame win
newFrame
-- Build the GUI
ImPlot.setNextPlotLimits (0, 1) (-1, 1)
liftIO $ bracket_ (ImPlot.beginPlot "Audio") ImPlot.endPlot do
ImPlot.plotLine "pulse-input" xs samples
-- Render
glClear GL_COLOR_BUFFER_BIT
render
openGL2RenderDrawData =<< getDrawData
glSwapWindow win
mainLoop win
where
untilNothingM m = m >>= maybe (return ()) (\_ -> untilNothingM m)
xs = range
range :: [Float]
range = take 1764 $ iterate' (+ step) 0.0
step :: Float
step = 1 / 1764