commit
56b97230f4
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
module Common
|
module Common
|
||||||
( arrangeEvents
|
( arrangeEvents
|
||||||
|
, arrangeEventsWhole
|
||||||
, beatNow
|
, beatNow
|
||||||
, dirtToColour
|
, dirtToColour
|
||||||
, fi
|
, fi
|
||||||
|
|
@ -44,11 +45,12 @@ addEventWhole e (level:ls)
|
||||||
arrangeEventsWhole :: [Event b] -> [[Event b]]
|
arrangeEventsWhole :: [Event b] -> [[Event b]]
|
||||||
arrangeEventsWhole = foldr addEventWhole []
|
arrangeEventsWhole = foldr addEventWhole []
|
||||||
|
|
||||||
levelsWhole :: Pattern a -> [[Event a]]
|
levelsWhole :: Eq a => Pattern a -> [[Event a]]
|
||||||
levelsWhole pat = arrangeEventsWhole $ sortOn' ((\Arc{..} -> stop - start) . part) (queryArc pat (Arc 0 1))
|
levelsWhole pat = arrangeEventsWhole $ sortOn' ((\Arc{..} -> 0 - (stop - start)) . wholeOrPart) (defragParts $ queryArc pat (Arc 0 1))
|
||||||
|
-- levelsWhole pat = arrangeEventsWhole $ defragParts $ queryArc pat (Arc 0 1)
|
||||||
|
|
||||||
fits :: Event b -> [Event b] -> Bool
|
fits :: Event b -> [Event b] -> Bool
|
||||||
fits (Event _ part' _) events = not $ any (\Event{..} -> isJust $ subArc part' part) events
|
fits (Event _ _ part' _) events = not $ any (\Event{..} -> isJust $ subArc part' part) events
|
||||||
|
|
||||||
addEvent :: Event b -> [[Event b]] -> [[Event b]]
|
addEvent :: Event b -> [[Event b]] -> [[Event b]]
|
||||||
addEvent e [] = [[e]]
|
addEvent e [] = [[e]]
|
||||||
|
|
@ -59,8 +61,9 @@ addEvent e (level:ls)
|
||||||
arrangeEvents :: [Event b] -> [[Event b]]
|
arrangeEvents :: [Event b] -> [[Event b]]
|
||||||
arrangeEvents = foldr addEvent []
|
arrangeEvents = foldr addEvent []
|
||||||
|
|
||||||
levels :: Pattern a -> [[Event a]]
|
levels :: Eq a => Pattern a -> [[Event a]]
|
||||||
levels pat = arrangeEvents $ sortOn' ((\Arc{..} -> stop - start) . part) (queryArc pat (Arc 0 1))
|
-- levels pat = arrangeEvents $ sortOn' ((\Arc{..} -> stop - start) . part) (defragParts $ queryArc pat (Arc 0 1))
|
||||||
|
levels pat = arrangeEvents $ reverse $ defragParts $ queryArc pat (Arc 0 1)
|
||||||
|
|
||||||
sortOn' :: Ord a => (b -> a) -> [b] -> [b]
|
sortOn' :: Ord a => (b -> a) -> [b] -> [b]
|
||||||
sortOn' f = map snd . sortOn fst . map (\x -> let y = f x in y `seq` (y, x))
|
sortOn' f = map snd . sortOn fst . map (\x -> let y = f x in y `seq` (y, x))
|
||||||
|
|
@ -79,8 +82,8 @@ stringToColour str = sRGB (r/256) (g/256) (b/256)
|
||||||
|
|
||||||
segmentator :: Pattern ColourD -> Pattern [ColourD]
|
segmentator :: Pattern ColourD -> Pattern [ColourD]
|
||||||
segmentator p@Pattern{..} = Pattern $ \(State arc@Arc{..} _)
|
segmentator p@Pattern{..} = Pattern $ \(State arc@Arc{..} _)
|
||||||
-> filter (\(Event _ (Arc start' stop') _) -> start' < stop && stop' > start)
|
-> filter (\(Event _ _ (Arc start' stop') _) -> start' < stop && stop' > start)
|
||||||
$ groupByTime (segment' (queryArc p arc))
|
$ groupByTime (segment' (defragParts $ queryArc p arc))
|
||||||
|
|
||||||
segment' :: [Event a] -> [Event a]
|
segment' :: [Event a] -> [Event a]
|
||||||
segment' es = foldr split es pts
|
segment' es = foldr split es pts
|
||||||
|
|
@ -88,20 +91,20 @@ segment' es = foldr split es pts
|
||||||
|
|
||||||
split :: Time -> [Event a] -> [Event a]
|
split :: Time -> [Event a] -> [Event a]
|
||||||
split _ [] = []
|
split _ [] = []
|
||||||
split t (ev@(Event whole Arc{..} value):es)
|
split t (ev@(Event c whole Arc{..} value):es)
|
||||||
| t > start && t < stop =
|
| t > start && t < stop =
|
||||||
Event whole (Arc start t) value : Event whole (Arc t stop) value : split t es
|
Event c whole (Arc start t) value : Event c whole (Arc t stop) value : split t es
|
||||||
| otherwise = ev:split t es
|
| otherwise = ev:split t es
|
||||||
|
|
||||||
points :: [Event a] -> [Time]
|
points :: [Event a] -> [Time]
|
||||||
points [] = []
|
points [] = []
|
||||||
points (Event _ Arc{..} _ : es) = start : stop : points es
|
points (Event _ _ Arc{..} _ : es) = start : stop : points es
|
||||||
|
|
||||||
groupByTime :: [Event a] -> [Event [a]]
|
groupByTime :: [Event a] -> [Event [a]]
|
||||||
groupByTime es = map merge $ groupBy ((==) `on` part) $ sortOn (stop . part) es
|
groupByTime es = map merge $ groupBy ((==) `on` part) $ sortOn (stop . part) es
|
||||||
where
|
where
|
||||||
merge :: [EventF a b] -> EventF a [b]
|
merge :: [EventF a b] -> EventF a [b]
|
||||||
merge evs@(Event{whole, part} : _) = Event whole part $ map (\Event{value} -> value) evs
|
merge evs@(Event{context, whole, part} : _) = Event context whole part $ map (\Event{value} -> value) evs
|
||||||
merge _ = error "groupByTime"
|
merge _ = error "groupByTime"
|
||||||
|
|
||||||
beatNow :: Tempo.Tempo -> IO Double
|
beatNow :: Tempo.Tempo -> IO Double
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ drawPatR (x1,x2) p screen beat = mapM_ drawEvents $ event (pos beat) p
|
||||||
(width * fromRational (b - pos beat)) (width * fromRational (e - b)) 1
|
(width * fromRational (b - pos beat)) (width * fromRational (e - b)) 1
|
||||||
|
|
||||||
event :: Rational -> Pat.Pattern ColourD -> [((Rational, Rational), [ColourD])]
|
event :: Rational -> Pat.Pattern ColourD -> [((Rational, Rational), [ColourD])]
|
||||||
event position pat = map (\(Pat.Event _ Arc{..} events) ->
|
event position pat = map (\(Pat.Event _ _ Arc{..} events) ->
|
||||||
((max start position, min stop (position + 1)), events))
|
((max start position, min stop (position + 1)), events))
|
||||||
$ queryArc (segmentator pat) (Arc position (position + 1))
|
$ queryArc (segmentator pat) (Arc position (position + 1))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ matBundleRect = renderMatBundlePDF "./examples/" [foo, pip, pop, bar, buz]
|
||||||
|
|
||||||
-- | Make gradient rectangle pattern
|
-- | Make gradient rectangle pattern
|
||||||
gradientRect :: IO ()
|
gradientRect :: IO ()
|
||||||
gradientRect = renderGradientPDF "./examples/gradientRect" pip
|
gradientRect = renderGradientPDF "./examples/gradientRect" "" pip
|
||||||
|
|
||||||
-- | Make gradient rectangle pattern
|
-- | Make gradient rectangle pattern
|
||||||
matCycleWithBorders :: IO ()
|
matCycleWithBorders :: IO ()
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ v sf fn (x,y) pat =
|
||||||
|
|
||||||
-- | Convert time and color to rendered type.
|
-- | Convert time and color to rendered type.
|
||||||
renderEvent :: Event [ColourD] -> C.Render ()
|
renderEvent :: Event [ColourD] -> C.Render ()
|
||||||
renderEvent (Event _ Arc{..} value) = do
|
renderEvent (Event _ _ Arc{..} value) = do
|
||||||
C.save
|
C.save
|
||||||
drawBlocks value 0
|
drawBlocks value 0
|
||||||
C.restore
|
C.restore
|
||||||
|
|
@ -104,8 +104,8 @@ renderEvent (Event _ Arc{..} value) = do
|
||||||
|
|
||||||
events :: Pattern ColourD -> [Event [ColourD]]
|
events :: Pattern ColourD -> [Event [ColourD]]
|
||||||
events pat = map
|
events pat = map
|
||||||
( \(Event whole Arc{..} value)
|
( \(Event context whole Arc{..} value)
|
||||||
-> Event whole (Arc ((start - tick) / speed') ((stop - tick) / speed')) value
|
-> Event context whole (Arc ((start - tick) / speed') ((stop - tick) / speed')) value
|
||||||
)
|
)
|
||||||
$ queryArc (segmentator pat) (Arc tick (tick + speed'))
|
$ queryArc (segmentator pat) (Arc tick (tick + speed'))
|
||||||
where
|
where
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ renderLevel total (num, level) = do
|
||||||
C.restore
|
C.restore
|
||||||
where
|
where
|
||||||
drawEvent :: Event ColourD -> C.Render ()
|
drawEvent :: Event ColourD -> C.Render ()
|
||||||
drawEvent (Event _ Arc{..} c) = do
|
drawEvent (Event _ _ Arc{..} c) = do
|
||||||
let (RGB r g b) = toSRGB c
|
let (RGB r g b) = toSRGB c
|
||||||
let levelHeight = (1 / fi (total+1))/2
|
let levelHeight = (1 / fi (total+1))/2
|
||||||
let h = levelHeight * fi (num + 1)
|
let h = levelHeight * fi (num + 1)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ totalWidth :: Double
|
||||||
totalWidth = 1700
|
totalWidth = 1700
|
||||||
|
|
||||||
ratio :: Double
|
ratio :: Double
|
||||||
ratio = 3/40
|
ratio = 2/40
|
||||||
|
|
||||||
levelHeight :: Double
|
levelHeight :: Double
|
||||||
levelHeight = totalWidth * ratio
|
levelHeight = totalWidth * ratio
|
||||||
|
|
@ -48,7 +48,7 @@ renderLevel _ (num, level) = do
|
||||||
mapM_ drawEvent $ level
|
mapM_ drawEvent $ level
|
||||||
C.restore
|
C.restore
|
||||||
where
|
where
|
||||||
drawEvent e@(Event _ Arc{..} c) = do
|
drawEvent e@(Event _ _ Arc{..} c) = do
|
||||||
let (Arc sWhole eWhole) = wholeOrPart e
|
let (Arc sWhole eWhole) = wholeOrPart e
|
||||||
let (RGB r g b) = toSRGB c
|
let (RGB r g b) = toSRGB c
|
||||||
let x = (fromRational start) * totalWidth
|
let x = (fromRational start) * totalWidth
|
||||||
|
|
@ -82,14 +82,14 @@ renderLevel _ (num, level) = do
|
||||||
-- C.fill
|
-- C.fill
|
||||||
-- C.stroke
|
-- C.stroke
|
||||||
|
|
||||||
renderGradientSVG :: String -> Pattern ColourD -> IO ()
|
renderGradientSVG :: String -> String -> Pattern ColourD -> IO ()
|
||||||
renderGradientSVG name pat = do
|
renderGradientSVG name label pat = do
|
||||||
v C.withSVGSurface (name ++ ".svg")
|
v C.withSVGSurface (name ++ ".svg")
|
||||||
(totalWidth, levelHeight * (fromIntegral $ length $ levels pat)) $ levels pat
|
(totalWidth, levelHeight * (fromIntegral $ length $ levels pat)) $ levels pat
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
renderGradientPDF :: String -> Pattern ColourD -> IO ()
|
renderGradientPDF :: String -> String -> Pattern ColourD -> IO ()
|
||||||
renderGradientPDF name pat = do
|
renderGradientPDF name label pat = do
|
||||||
v C.withPDFSurface (name ++ ".pdf")
|
v C.withPDFSurface (name ++ ".pdf")
|
||||||
(totalWidth, levelHeight * (fromIntegral $ length $ levels pat)) $ levels pat
|
(totalWidth, levelHeight * (fromIntegral $ length $ levels pat)) $ levels pat
|
||||||
return ()
|
return ()
|
||||||
|
|
|
||||||
|
|
@ -17,25 +17,35 @@ totalWidth :: Double
|
||||||
totalWidth = 1700
|
totalWidth = 1700
|
||||||
|
|
||||||
ratio :: Double
|
ratio :: Double
|
||||||
ratio = 3/40
|
ratio = 2/40
|
||||||
|
|
||||||
levelHeight :: Double
|
levelHeight :: Double
|
||||||
levelHeight = totalWidth * ratio
|
levelHeight = totalWidth * ratio
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
v :: Show a => (FilePath -> Double -> Double -> (C.Surface -> IO ()) -> IO ())
|
v :: Show a => (FilePath -> Double -> Double -> (C.Surface -> IO ()) -> IO ())
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> (Double, Double)
|
-> (Double, Double)
|
||||||
-> [[Event a]]
|
-> [[Event a]]
|
||||||
|
-> String
|
||||||
-> IO ()
|
-> IO ()
|
||||||
v sf fn (x,y) es = sf fn x y $ \surf ->
|
v sf fn (x,y) es label = sf fn x y $ \surf ->
|
||||||
C.renderWith surf $ do
|
C.renderWith surf $ do
|
||||||
|
C.setAntialias C.AntialiasBest
|
||||||
C.save
|
C.save
|
||||||
-- C.scale x (y / (fromIntegral $ length colorEvents))
|
-- C.scale x (y / (fromIntegral $ length colorEvents))
|
||||||
C.setOperator C.OperatorOver
|
C.setOperator C.OperatorOver
|
||||||
|
C.selectFontFace ("Inconsolata" :: String) C.FontSlantNormal C.FontWeightNormal
|
||||||
|
C.setFontSize 0.2
|
||||||
|
(C.TextExtents _ _ _ textH _ _) <- C.textExtents (label :: String)
|
||||||
|
C.moveTo 0 textH
|
||||||
|
C.textPath (label :: String)
|
||||||
|
C.setSourceRGB 0 0 0
|
||||||
|
C.fill
|
||||||
-- C.setSourceRGB 0 0 0
|
-- C.setSourceRGB 0 0 0
|
||||||
-- C.rectangle 0 0 1 1
|
-- C.rectangle 0 0 1 1
|
||||||
--C.fill
|
--C.fill
|
||||||
C.setAntialias C.AntialiasBest
|
|
||||||
mapM_ (renderLevel (length es)) $ enumerate es
|
mapM_ (renderLevel (length es)) $ enumerate es
|
||||||
C.restore
|
C.restore
|
||||||
|
|
||||||
|
|
@ -49,7 +59,7 @@ renderLevel _ (num, level) = do
|
||||||
mapM_ drawEvent $ level
|
mapM_ drawEvent $ level
|
||||||
C.restore
|
C.restore
|
||||||
where
|
where
|
||||||
drawEvent e@(Event _ (Arc sPart ePart) v) = do
|
drawEvent e@(Event _ _ (Arc sPart ePart) v) = do
|
||||||
let (Arc sWhole eWhole) = wholeOrPart e
|
let (Arc sWhole eWhole) = wholeOrPart e
|
||||||
let (r, g, b) = (0,0,0)
|
let (r, g, b) = (0,0,0)
|
||||||
let px = (fromRational sPart) * totalWidth
|
let px = (fromRational sPart) * totalWidth
|
||||||
|
|
@ -64,8 +74,8 @@ renderLevel _ (num, level) = do
|
||||||
|
|
||||||
C.withLinearPattern wx 0 (ww + wx) 0 $ \pat -> do
|
C.withLinearPattern wx 0 (ww + wx) 0 $ \pat -> do
|
||||||
C.save
|
C.save
|
||||||
C.patternAddColorStopRGBA pat 0 0.8 0.8 0.8 1
|
C.patternAddColorStopRGBA pat 0 0.9 0.9 0.9 1
|
||||||
C.patternAddColorStopRGBA pat 1 0 0 0 0.5
|
C.patternAddColorStopRGBA pat 1 0.4 0.4 0.4 0.5
|
||||||
C.patternSetFilter pat C.FilterFast
|
C.patternSetFilter pat C.FilterFast
|
||||||
C.setSource pat
|
C.setSource pat
|
||||||
let leftGap = if px == wx then halfGap else 0
|
let leftGap = if px == wx then halfGap else 0
|
||||||
|
|
@ -111,9 +121,9 @@ renderLevel _ (num, level) = do
|
||||||
C.restore
|
C.restore
|
||||||
C.selectFontFace ("Inconsolata" :: String) C.FontSlantNormal C.FontWeightNormal
|
C.selectFontFace ("Inconsolata" :: String) C.FontSlantNormal C.FontWeightNormal
|
||||||
C.setFontSize 35
|
C.setFontSize 35
|
||||||
(C.TextExtents _ _ textW textH _ _) <- C.textExtents (show v)
|
(C.TextExtents _ _ textW textH _ _) <- C.textExtents (stripQuotes $ show v)
|
||||||
C.moveTo (wx + 12) (y + textH + 16)
|
C.moveTo (wx + 12) (y + 24 + 16)
|
||||||
C.textPath (show v)
|
C.textPath (stripQuotes $ show v)
|
||||||
C.setSourceRGB 0 0 0
|
C.setSourceRGB 0 0 0
|
||||||
C.fill
|
C.fill
|
||||||
-- C.save
|
-- C.save
|
||||||
|
|
@ -123,15 +133,20 @@ renderLevel _ (num, level) = do
|
||||||
-- C.fill
|
-- C.fill
|
||||||
-- C.stroke
|
-- C.stroke
|
||||||
|
|
||||||
renderPartSVG :: Show a => String -> Pattern a -> IO ()
|
stripQuotes s = front $ back s
|
||||||
renderPartSVG name pat = do
|
where front ('"':xs) = xs
|
||||||
|
front xs = xs
|
||||||
|
back = reverse . front . reverse
|
||||||
|
|
||||||
|
renderPartSVG :: (Eq a, Show a) => String -> String -> Pattern a -> IO ()
|
||||||
|
renderPartSVG name label pat = do
|
||||||
v C.withSVGSurface (name ++ ".svg")
|
v C.withSVGSurface (name ++ ".svg")
|
||||||
(totalWidth, levelHeight * (fromIntegral $ length $ levelsWhole pat)) $ levelsWhole pat
|
(totalWidth, levelHeight * (fromIntegral $ length $ levelsWhole pat)) (levelsWhole pat) label
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
renderPartPDF :: Show a => String -> Pattern a -> IO ()
|
renderPartPDF :: (Eq a, Show a) => String -> String -> Pattern a -> IO ()
|
||||||
renderPartPDF name pat = do
|
renderPartPDF name label pat = do
|
||||||
v C.withPDFSurface (name ++ ".pdf")
|
v C.withPDFSurface (name ++ ".pdf")
|
||||||
(totalWidth, levelHeight * (fromIntegral $ length $ levelsWhole pat)) $ levelsWhole pat
|
(totalWidth, levelHeight * (fromIntegral $ length $ levelsWhole pat)) (levelsWhole pat) label
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ library
|
||||||
, SDL-ttf
|
, SDL-ttf
|
||||||
, mtl
|
, mtl
|
||||||
, network
|
, network
|
||||||
, tidal >= 1.0.15 && < 1.5
|
, tidal >= 1.0.15 && < 1.7
|
||||||
, time
|
, time
|
||||||
, unagi-chan
|
, unagi-chan
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue