module Perform.Midi.MSignal (
module Perform.Midi.MSignal, module Util.TimeVector
) where
import Prelude hiding (head, last)
import qualified Util.Num as Num
import qualified Util.TimeVector as TimeVector
import Util.TimeVector
(Sample(..), constant, drop_before, drop_at_after, within, map_y,
map_err)
import qualified Midi.Midi as Midi
import Global
import Types
type Signal = TimeVector.Unboxed
type Y = TimeVector.UnboxedY
type X = RealTime
head, last :: Signal -> Maybe (X, Y)
head :: Signal -> Maybe (X, Y)
head = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall y. Sample y -> (X, y)
TimeVector.to_pair forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. Vector v a => v a -> Maybe a
TimeVector.head
last :: Signal -> Maybe (X, Y)
last = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall y. Sample y -> (X, y)
TimeVector.to_pair forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a. Vector v a => v a -> Maybe a
TimeVector.last
at :: X -> Signal -> Y
at :: X -> Signal -> Y
at X
x = forall a. a -> Maybe a -> a
fromMaybe Y
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) y.
Vector v (Sample y) =>
X -> v (Sample y) -> Maybe y
TimeVector.at X
x
from_pairs :: [(X, Y)] -> Signal
from_pairs :: [(X, Y)] -> Signal
from_pairs = forall (v :: * -> *) y.
Vector v (Sample y) =>
[(X, y)] -> v (Sample y)
TimeVector.from_pairs
to_pairs :: Signal -> [(X, Y)]
to_pairs :: Signal -> [(X, Y)]
to_pairs = forall (v :: * -> *) y.
Vector v (Sample y) =>
v (Sample y) -> [(X, y)]
TimeVector.to_pairs
scalar_add :: Y -> Signal -> Signal
scalar_add :: Y -> Signal -> Signal
scalar_add Y
y = forall (v :: * -> *) y.
Vector v (Sample y) =>
(y -> y) -> v (Sample y) -> v (Sample y)
TimeVector.map_y (forall a. Num a => a -> a -> a
+Y
y)
clip_bounds :: Y -> Y -> Signal -> (Signal, [(X, X)])
clip_bounds :: Y -> Y -> Signal -> (Signal, [(X, X)])
clip_bounds Y
low Y
high Signal
sig = (Signal
clipped, forall a. [a] -> [a]
reverse [(X, X)]
out_of_range)
where
clipped :: Signal
clipped = if forall (t :: * -> *) a. Foldable t => t a -> Bool
Prelude.null [(X, X)]
out_of_range then Signal
sig
else forall (v :: * -> *) y.
Vector v (Sample y) =>
(y -> y) -> v (Sample y) -> v (Sample y)
TimeVector.map_y (forall a. Ord a => a -> a -> a -> a
Num.clamp Y
low Y
high) Signal
sig
([(X, X)]
ranges, Maybe X
in_clip) = forall (v :: * -> *) b a.
Vector v b =>
(a -> b -> a) -> a -> v b -> a
TimeVector.foldl' ([(X, X)], Maybe X) -> Sample Y -> ([(X, X)], Maybe X)
go ([], forall a. Maybe a
Nothing) Signal
sig
out_of_range :: [(X, X)]
out_of_range = case (Maybe X
in_clip, forall (v :: * -> *) a. Vector v a => v a -> Maybe a
TimeVector.last Signal
sig) of
(Just X
start, Just (TimeVector.Sample X
end Y
_)) -> (X
start, X
end) forall a. a -> [a] -> [a]
: [(X, X)]
ranges
(Maybe X, Maybe (Sample Y))
_ -> [(X, X)]
ranges
go :: ([(X, X)], Maybe X) -> Sample Y -> ([(X, X)], Maybe X)
go state :: ([(X, X)], Maybe X)
state@([(X, X)]
accum, Maybe X
Nothing) (TimeVector.Sample X
x Y
y)
| Y
y forall a. Ord a => a -> a -> Bool
< Y
low Bool -> Bool -> Bool
|| Y
y forall a. Ord a => a -> a -> Bool
> Y
high = ([(X, X)]
accum, forall a. a -> Maybe a
Just X
x)
| Bool
otherwise = ([(X, X)], Maybe X)
state
go state :: ([(X, X)], Maybe X)
state@([(X, X)]
accum, Just X
start) (TimeVector.Sample X
x Y
y)
| Y
y forall a. Ord a => a -> a -> Bool
< Y
low Bool -> Bool -> Bool
|| Y
y forall a. Ord a => a -> a -> Bool
> Y
high = ([(X, X)], Maybe X)
state
| Bool
otherwise = ((X
start, X
x) forall a. a -> [a] -> [a]
: [(X, X)]
accum, forall a. Maybe a
Nothing)
pitches_share :: Bool -> X -> X
-> Midi.Key -> Signal -> Midi.Key -> Signal -> Bool
pitches_share :: Bool -> X -> X -> Key -> Signal -> Key -> Signal -> Bool
pitches_share Bool
in_decay X
start X
end Key
initial1 Signal
sig1 Key
initial2 Signal
sig2
| Bool -> Bool
not Bool
in_decay Bool -> Bool -> Bool
&& Key
initial1 forall a. Eq a => a -> a -> Bool
== Key
initial2 = Bool
False
| Bool
otherwise = Y -> Y -> Bool
pitch_eq (Signal
sig1 forall {a} {v :: * -> *}.
(Num a, Vector v (Sample a)) =>
v (Sample a) -> X -> a
! X
start) (Signal
sig2 forall {a} {v :: * -> *}.
(Num a, Vector v (Sample a)) =>
v (Sample a) -> X -> a
! X
start)
Bool -> Bool -> Bool
&& Y -> Y -> Bool
pitch_eq (Signal
sig1 forall {a} {v :: * -> *}.
(Num a, Vector v (Sample a)) =>
v (Sample a) -> X -> a
! X
end) (Signal
sig2 forall {a} {v :: * -> *}.
(Num a, Vector v (Sample a)) =>
v (Sample a) -> X -> a
! X
end)
Bool -> Bool -> Bool
&& (Y -> Y -> Bool) -> X -> Signal -> Signal -> Bool
signals_share Y -> Y -> Bool
pitch_eq X
start Signal
in1 Signal
in2
where
in1 :: Signal
in1 = forall (v :: * -> *) y.
Vector v (Sample y) =>
X -> X -> v (Sample y) -> v (Sample y)
TimeVector.within X
start X
end Signal
sig1
in2 :: Signal
in2 = forall (v :: * -> *) y.
Vector v (Sample y) =>
X -> X -> v (Sample y) -> v (Sample y)
TimeVector.within X
start X
end Signal
sig2
pitch_eq :: Y -> Y -> Bool
pitch_eq = Key -> Key -> Y -> Y -> Bool
nns_share Key
initial1 Key
initial2
! :: v (Sample a) -> X -> a
(!) v (Sample a)
sig X
x = forall a. a -> Maybe a -> a
fromMaybe a
0 forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) y.
Vector v (Sample y) =>
X -> v (Sample y) -> Maybe y
TimeVector.at X
x v (Sample a)
sig
{-# INLINE signals_share #-}
signals_share :: (Y -> Y -> Bool) -> X -> TimeVector.Unboxed
-> TimeVector.Unboxed -> Bool
signals_share :: (Y -> Y -> Bool) -> X -> Signal -> Signal -> Bool
signals_share Y -> Y -> Bool
eq X
start Signal
vec1 Signal
vec2 = Y -> Y -> Int -> Int -> Bool
go Y
0 Y
0 Int
0 Int
0
where
go :: Y -> Y -> Int -> Int -> Bool
go Y
prev_ay Y
prev_by Int
i1 Int
i2 =
case forall (v1 :: * -> *) y1 (v2 :: * -> *) y2.
(Vector v1 (Sample y1), Vector v2 (Sample y2)) =>
y1
-> y2
-> Int
-> Int
-> Int
-> Int
-> v1 (Sample y1)
-> v2 (Sample y2)
-> Maybe (X, y1, y2, Int, Int)
TimeVector.resample1 Y
prev_ay Y
prev_by Int
len1 Int
len2 Int
i1 Int
i2 Signal
vec1 Signal
vec2 of
Maybe (X, Y, Y, Int, Int)
Nothing -> Bool
True
Just (X
x, Y
ay, Y
by, Int
i1, Int
i2) ->
(X
x forall a. Ord a => a -> a -> Bool
<= X
start Bool -> Bool -> Bool
|| Y -> Y -> Bool
eq Y
ay Y
by) Bool -> Bool -> Bool
&& Y -> Y -> Int -> Int -> Bool
go Y
ay Y
by Int
i1 Int
i2
len1 :: Int
len1 = forall (v :: * -> *) a. Vector v a => v a -> Int
TimeVector.length Signal
vec1
len2 :: Int
len2 = forall (v :: * -> *) a. Vector v a => v a -> Int
TimeVector.length Signal
vec2
nns_share :: Midi.Key -> Midi.Key -> Y -> Y -> Bool
nns_share :: Key -> Key -> Y -> Y -> Bool
nns_share Key
initial1 Key
initial2 Y
nn1 Y
nn2 =
forall a b. (RealFrac a, Integral b) => a -> b
floor ((Y
nn1 forall a. Num a => a -> a -> a
- forall a. Num a => Key -> a
Midi.from_key Key
initial1) forall a. Num a => a -> a -> a
* Y
1000)
forall a. Eq a => a -> a -> Bool
== forall a b. (RealFrac a, Integral b) => a -> b
floor ((Y
nn2 forall a. Num a => a -> a -> a
- forall a. Num a => Key -> a
Midi.from_key Key
initial2) forall a. Num a => a -> a -> a
* Y
1000)