-- Copyright 2018 Evan Laforge
-- This program is distributed under the terms of the GNU General Public
-- License 3.0, see COPYING or http://www.gnu.org/licenses/gpl-3.0.txt

{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{- | This is a basic library for audio streaming.  It uses the @streaming@
    package to interleave streaming and IO, and represents signals as a stream
    of Vectors of 'Sample's, which is hardcoded to Float.  There are separate
    types for interleaved samples 'Audio' and non-interleaved samples 'NAudio'.

    The sampling rate and channels are recorded as type naturals.  This removes
    the need for runtime error checking, but makes dealing with an unknown
    sampling rate or channels more awkward.
-}
module Util.Audio.Audio (
    -- * types
    Audio(..), AudioIO, AudioId
    , NAudio(..), NAudioIO, NAudioId
    , UnknownAudio(..), UnknownAudioIO
    , Block(..)
    , Sample, Frames(..), secondsToFrames, secondsToFramesCeil, framesToSeconds
    , Count, Channels, Rate, Seconds
    , framesCount, countFrames, blockFrames, vectorFrames
    , blockCount, isEmptyBlock, blockSamples, blockVector
    -- * construct
    , fromBlocks, fromSamples, fromSampleLists
    , toBlocks, toSamples, toBlocksN, toSamplesN
    -- * transform
    , apply
    , castRate
    , take, takeS, mapSamples, gain, multiply
    , takeClose, takeCloseS
    , pan, panConstant
    -- * mix
    , mix
    , mixV
    -- * channels
    , mergeChannels, extractChannel, splitChannels
    , expandChannels, expandV
    , mixChannels, interleaveV, deinterleaveB, deinterleaveV
    -- ** non-interleaved
    , nonInterleaved, interleaved
    , synchronizeToSize
    ,takeN
    , zeroPadN
    -- * generate
    , silence, sine
    , linear
    -- * effects
    , effect
    -- * error
    , Exception(..), exceptionText, throw, throwIO, assert, assertIn
    -- * constants
    , blockSize, silentBlock
    -- * conversions
    , dbToLinear, linearToDb
    -- * util
    , takeFramesGE, splitAt
    , next, isEmpty
    , natVal, someNat
#ifdef TESTING
    , module Util.Audio.Audio
#endif
) where
import Prelude hiding (splitAt, take)
import qualified Control.Exception as Exception
import qualified Control.Monad.Identity as Identity
import qualified Control.Monad.Trans.Resource as Resource
import qualified Data.Maybe as Maybe
import qualified Data.Vector.Storable as V
import qualified Data.Vector.Storable.Mutable as VM
import qualified GHC.TypeLits as TypeLits
import           GHC.TypeLits (KnownNat)
import qualified GHC.Stack as Stack
import qualified Streaming as S
import qualified Streaming.Prelude as S

import           Util.Audio.AudioT (Frames(..))
import qualified Util.CallStack as CallStack
import qualified Util.Control as Control
import qualified Util.Num as Num
import qualified Util.Seq as Seq
import qualified Util.Test.ApproxEq as ApproxEq
import qualified Util.VectorC as VectorC

import qualified Util.Pretty as Pretty

import Global


-- * types

{- | A stream of blocks of interleaved samples.

    There is an invariant that the length of the vector should always be
    a multiple of channels, in other words that a block is an integral number
    of frames.  The blocks may be of variable size, but should default to
    'blockSize', and align to multiples of blockSize, to minimize re-chunking
    when synchronizing streams.
-}
newtype Audio m (rate :: TypeLits.Nat) (chan :: TypeLits.Nat) =
    Audio { forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream :: S.Stream (S.Of Block) m () }
    deriving (NonEmpty (Audio m rate chan) -> Audio m rate chan
Audio m rate chan -> Audio m rate chan -> Audio m rate chan
(Audio m rate chan -> Audio m rate chan -> Audio m rate chan)
-> (NonEmpty (Audio m rate chan) -> Audio m rate chan)
-> (forall b.
    Integral b =>
    b -> Audio m rate chan -> Audio m rate chan)
-> Semigroup (Audio m rate chan)
forall b. Integral b => b -> Audio m rate chan -> Audio m rate chan
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
NonEmpty (Audio m rate chan) -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan -> Audio m rate chan -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat) b.
(Monad m, Integral b) =>
b -> Audio m rate chan -> Audio m rate chan
stimes :: forall b. Integral b => b -> Audio m rate chan -> Audio m rate chan
$cstimes :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat) b.
(Monad m, Integral b) =>
b -> Audio m rate chan -> Audio m rate chan
sconcat :: NonEmpty (Audio m rate chan) -> Audio m rate chan
$csconcat :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
NonEmpty (Audio m rate chan) -> Audio m rate chan
<> :: Audio m rate chan -> Audio m rate chan -> Audio m rate chan
$c<> :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan -> Audio m rate chan -> Audio m rate chan
Semigroup, Semigroup (Audio m rate chan)
Audio m rate chan
Semigroup (Audio m rate chan)
-> Audio m rate chan
-> (Audio m rate chan -> Audio m rate chan -> Audio m rate chan)
-> ([Audio m rate chan] -> Audio m rate chan)
-> Monoid (Audio m rate chan)
[Audio m rate chan] -> Audio m rate chan
Audio m rate chan -> Audio m rate chan -> Audio m rate chan
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Semigroup (Audio m rate chan)
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
[Audio m rate chan] -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan -> Audio m rate chan -> Audio m rate chan
mconcat :: [Audio m rate chan] -> Audio m rate chan
$cmconcat :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
[Audio m rate chan] -> Audio m rate chan
mappend :: Audio m rate chan -> Audio m rate chan -> Audio m rate chan
$cmappend :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan -> Audio m rate chan -> Audio m rate chan
mempty :: Audio m rate chan
$cmempty :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan
Monoid)

type AudioIO rate chan = Audio (Resource.ResourceT IO) rate chan
type AudioId rate chan = Audio Identity.Identity rate chan

{- | Non-interleaved audio stream.  Ok so it's still interleaved, just per
    block instead of per sample.

    Each of the lists will be channels length.  Each Sample vector will be the
    same length until the signal runs out, at which point it may be short, and
    then will be empty.  The stream ends when all signals are empty.

    The same block length guidelines as in 'Audio' also apply.

    Unlike 'Audio', the channel count is dynamic, not static.  This is because
    I use NAudio to stream a variably sized collection of control signals,
    while I use Audio to represent audio signals, which generally have a global
    number of channels determined by how many speakers you have.  But it does
    mean that you have to be careful that the length of each blocks list always
    matches '_nchannels'.  TODO it should be possible to use an existentially
    quantified type natural and length indexed list to ensure this, but not
    sure if it's worth it.
-}
data NAudio m (rate :: TypeLits.Nat) = NAudio
    { forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels :: !Channels
    , forall (m :: * -> *) (rate :: Nat).
NAudio m rate -> Stream (Of [Block]) m ()
_nstream :: S.Stream (S.Of [Block]) m ()
    }

type NAudioIO rate = NAudio (Resource.ResourceT IO) rate
type NAudioId rate = NAudio Identity.Identity rate

-- | There is a special representation for a constant block.  0 blocks are
-- common when aligning sounds, and constant ones are common for control
-- signals.
data Block = Block !(V.Vector Sample) | Constant !Count !Sample
    deriving (Block -> Block -> Bool
(Block -> Block -> Bool) -> (Block -> Block -> Bool) -> Eq Block
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Block -> Block -> Bool
$c/= :: Block -> Block -> Bool
== :: Block -> Block -> Bool
$c== :: Block -> Block -> Bool
Eq, Int -> Block -> ShowS
[Block] -> ShowS
Block -> [Char]
(Int -> Block -> ShowS)
-> (Block -> [Char]) -> ([Block] -> ShowS) -> Show Block
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [Block] -> ShowS
$cshowList :: [Block] -> ShowS
show :: Block -> [Char]
$cshow :: Block -> [Char]
showsPrec :: Int -> Block -> ShowS
$cshowsPrec :: Int -> Block -> ShowS
Show)

instance Pretty Block where
    format :: Block -> Doc
format (Block Vector Float
v) = Vector Float -> Doc
forall a. Pretty a => a -> Doc
Pretty.format Vector Float
v
    format (Constant Int
count Float
val) = Text -> Doc
Pretty.text (Text -> Doc) -> Text -> Doc
forall a b. (a -> b) -> a -> b
$ Text
"const:" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Int, Float) -> Text
forall a. Pretty a => a -> Text
pretty (Int
count, Float
val)

-- | This is an Audio with dynamic rate and channels.
data UnknownAudio m = forall rate chan. (KnownNat rate, KnownNat chan) =>
    UnknownAudio (Audio m rate chan)
type UnknownAudioIO = UnknownAudio (Resource.ResourceT IO)

-- | I hardcode the sample format to Float for now, since I have no need to
-- work with any other format.
type Sample = Float

-- | Sample count.  This is Frames * channels.
type Count = Int
type Channels = Int
type Rate = Int

type Seconds = Double

secondsToFrames :: Rate -> Seconds -> Frames
secondsToFrames :: Int -> Seconds -> Frames
secondsToFrames Int
rate Seconds
seconds = Int -> Frames
Frames (Int -> Frames) -> Int -> Frames
forall a b. (a -> b) -> a -> b
$ Seconds -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Seconds -> Int) -> Seconds -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Seconds
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
rate Seconds -> Seconds -> Seconds
forall a. Num a => a -> a -> a
* Seconds
seconds

secondsToFramesCeil :: Rate -> Seconds -> Frames
secondsToFramesCeil :: Int -> Seconds -> Frames
secondsToFramesCeil Int
rate Seconds
seconds =
    Int -> Frames
Frames (Int -> Frames) -> Int -> Frames
forall a b. (a -> b) -> a -> b
$ Seconds -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Seconds -> Int) -> Seconds -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Seconds
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
rate Seconds -> Seconds -> Seconds
forall a. Num a => a -> a -> a
* Seconds
seconds

framesToSeconds :: Rate -> Frames -> Seconds
framesToSeconds :: Int -> Frames -> Seconds
framesToSeconds Int
rate (Frames Int
frames) = Int -> Seconds
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
frames Seconds -> Seconds -> Seconds
forall a. Fractional a => a -> a -> a
/ Int -> Seconds
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
rate

framesCount :: KnownNat chan => Proxy chan -> Frames -> Count
framesCount :: forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan
chan (Frames Int
frames) = Int
frames Int -> Int -> Int
forall a. Num a => a -> a -> a
* Proxy chan -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal Proxy chan
chan

framesCount_ :: Channels -> Frames -> Count
framesCount_ :: Int -> Frames -> Int
framesCount_ Int
chan (Frames Int
frames) = Int
frames Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
chan

countFrames :: KnownNat chan => Proxy chan -> Count -> Frames
countFrames :: forall (chan :: Nat). KnownNat chan => Proxy chan -> Int -> Frames
countFrames Proxy chan
chan = Int -> Int -> Frames
countFrames_ (Proxy chan -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal Proxy chan
chan)

countFrames_ :: Channels -> Count -> Frames
countFrames_ :: Int -> Int -> Frames
countFrames_ Int
chan Int
count = Int -> Frames
Frames (Int -> Frames) -> Int -> Frames
forall a b. (a -> b) -> a -> b
$ Int
count Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
chan

blockFrames :: KnownNat chan => Proxy chan -> Block -> Frames
blockFrames :: forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan
chan = Proxy chan -> Int -> Frames
forall (chan :: Nat). KnownNat chan => Proxy chan -> Int -> Frames
countFrames Proxy chan
chan (Int -> Frames) -> (Block -> Int) -> Block -> Frames
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Block -> Int
blockCount

blockFrames_ :: Channels -> Block -> Frames
blockFrames_ :: Int -> Block -> Frames
blockFrames_ Int
chan = Int -> Int -> Frames
countFrames_ Int
chan (Int -> Frames) -> (Block -> Int) -> Block -> Frames
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Block -> Int
blockCount

vectorFrames :: KnownNat chan => Proxy chan -> V.Vector Sample -> Frames
vectorFrames :: forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Vector Float -> Frames
vectorFrames Proxy chan
chan = Proxy chan -> Int -> Frames
forall (chan :: Nat). KnownNat chan => Proxy chan -> Int -> Frames
countFrames Proxy chan
chan (Int -> Frames) -> (Vector Float -> Int) -> Vector Float -> Frames
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Float -> Int
forall a. Storable a => Vector a -> Int
V.length

blockCount :: Block -> Count
blockCount :: Block -> Int
blockCount (Block Vector Float
v) = Vector Float -> Int
forall a. Storable a => Vector a -> Int
V.length Vector Float
v
blockCount (Constant Int
c Float
_) = Int
c

isEmptyBlock :: Block -> Bool
isEmptyBlock :: Block -> Bool
isEmptyBlock = (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0) (Int -> Bool) -> (Block -> Int) -> Block -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Block -> Int
blockCount

blockSamples :: Block -> [V.Vector Sample]
blockSamples :: Block -> [Vector Float]
blockSamples (Block Vector Float
v) = [Vector Float
v]
blockSamples (Constant Int
count Float
_) | Int
count Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = []
blockSamples (Constant Int
count Float
0)
    | Int
count Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Vector Float -> Int
forall a. Storable a => Vector a -> Int
V.length Vector Float
silentBlock =
        Vector Float
silentBlock Vector Float -> [Vector Float] -> [Vector Float]
forall a. a -> [a] -> [a]
: Block -> [Vector Float]
blockSamples (Int -> Float -> Block
Constant (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Vector Float -> Int
forall a. Storable a => Vector a -> Int
V.length Vector Float
silentBlock) Float
0)
    | Bool
otherwise = [Int -> Vector Float -> Vector Float
forall a. Storable a => Int -> Vector a -> Vector a
V.take Int
count Vector Float
silentBlock]
blockSamples (Constant Int
count Float
val) = [Int -> Float -> Vector Float
forall a. Storable a => Int -> a -> Vector a
V.replicate Int
count Float
val]

blockVector :: Block -> V.Vector Sample
blockVector :: Block -> Vector Float
blockVector = [Vector Float] -> Vector Float
forall a. Monoid a => [a] -> a
mconcat ([Vector Float] -> Vector Float)
-> (Block -> [Vector Float]) -> Block -> Vector Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Block -> [Vector Float]
blockSamples

blockSplit :: Count -> Block -> (Block, Block)
blockSplit :: Int -> Block -> (Block, Block)
blockSplit Int
n (Block Vector Float
v) = (Vector Float -> Block
Block Vector Float
pre, Vector Float -> Block
Block Vector Float
post)
    where (Vector Float
pre, Vector Float
post) = Int -> Vector Float -> (Vector Float, Vector Float)
forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
V.splitAt Int
n Vector Float
v
blockSplit Int
n (Constant Int
count Float
val) =
    (Int -> Float -> Block
Constant (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
count Int
n) Float
val, Int -> Float -> Block
Constant (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)) Float
val)

instance Semigroup Block where
    Constant Int
c1 Float
v1 <> :: Block -> Block -> Block
<> Constant Int
c2 Float
v2 | Float
v1 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
v2 = Int -> Float -> Block
Constant (Int
c1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
c2) Float
v1
    Block
b1 <> Block
b2 = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ [Vector Float] -> Vector Float
forall a. Monoid a => [a] -> a
mconcat ([Vector Float] -> Vector Float) -> [Vector Float] -> Vector Float
forall a b. (a -> b) -> a -> b
$ Block -> [Vector Float]
blockSamples Block
b1 [Vector Float] -> [Vector Float] -> [Vector Float]
forall a. [a] -> [a] -> [a]
++ Block -> [Vector Float]
blockSamples Block
b2

instance Monoid Block where
    mempty :: Block
mempty = Int -> Float -> Block
Constant Int
0 Float
0
    -- This reduces allocation if there are multiple vectors, though that's
    -- pretty unlikely.
    mconcat :: [Block] -> Block
mconcat (Constant Int
c1 Float
v1 : [Block]
bs)
        | [Vector Float] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Vector Float]
vs Bool -> Bool -> Bool
&& ((Int, Float) -> Bool) -> [(Int, Float)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
==Float
v1) (Float -> Bool) -> ((Int, Float) -> Float) -> (Int, Float) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Float) -> Float
forall a b. (a, b) -> b
snd) [(Int, Float)]
cs =
            Int -> Float -> Block
Constant (Int
c1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
Num.sum (((Int, Float) -> Int) -> [(Int, Float)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Float) -> Int
forall a b. (a, b) -> a
fst [(Int, Float)]
cs)) Float
v1
        where
        cs :: [(Int, Float)]
cs = [(Int
c, Float
v) | Constant Int
c Float
v <- [Block]
bs]
        vs :: [Vector Float]
vs = [Vector Float
v | Block Vector Float
v <- [Block]
bs]
    mconcat [Block]
bs = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ [Vector Float] -> Vector Float
forall a. Monoid a => [a] -> a
mconcat ([Vector Float] -> Vector Float) -> [Vector Float] -> Vector Float
forall a b. (a -> b) -> a -> b
$ (Block -> [Vector Float]) -> [Block] -> [Vector Float]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Block -> [Vector Float]
blockSamples [Block]
bs

-- * construct

-- | Construct audio manually for testing.  The length of each vector should be
-- a multiple of the channels, or this will crash.
fromSamples :: forall m rate chan. (Monad m, KnownNat chan)
    => [V.Vector Sample] -> Audio m rate chan
fromSamples :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
[Vector Float] -> Audio m rate chan
fromSamples = [Block] -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
[Block] -> Audio m rate chan
fromBlocks ([Block] -> Audio m rate chan)
-> ([Vector Float] -> [Block])
-> [Vector Float]
-> Audio m rate chan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector Float -> Block) -> [Vector Float] -> [Block]
forall a b. (a -> b) -> [a] -> [b]
map Vector Float -> Block
Block

fromBlocks :: forall m rate chan. (Monad m, KnownNat chan)
    => [Block] -> Audio m rate chan
fromBlocks :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
[Block] -> Audio m rate chan
fromBlocks = Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> ([Block] -> Stream (Of Block) m ())
-> [Block]
-> Audio m rate chan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Block] -> Stream (Of Block) m ()
forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Foldable f) =>
f a -> Stream (Of a) m ()
S.each ([Block] -> Stream (Of Block) m ())
-> ([Block] -> [Block]) -> [Block] -> Stream (Of Block) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Block -> Block) -> [Block] -> [Block]
forall a b. (a -> b) -> [a] -> [b]
map Block -> Block
check
    where
    check :: Block -> Block
check Block
block
        | Block -> Int
blockCount Block
block Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
chan Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Block
block
        | Bool
otherwise = [Char] -> Block
forall a. HasCallStack => [Char] -> a
error ([Char] -> Block) -> [Char] -> Block
forall a b. (a -> b) -> a -> b
$ [Char]
"block count " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show (Block -> Int
blockCount Block
block)
            [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
" not a multiple of channels " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
chan
    chan :: Int
chan = Proxy chan -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @chan)

fromSampleLists :: forall m rate chan. (Monad m, KnownNat chan)
    => [[Sample]] -> Audio m rate chan
fromSampleLists :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
[[Float]] -> Audio m rate chan
fromSampleLists = [Vector Float] -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
[Vector Float] -> Audio m rate chan
fromSamples ([Vector Float] -> Audio m rate chan)
-> ([[Float]] -> [Vector Float]) -> [[Float]] -> Audio m rate chan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Float] -> Vector Float) -> [[Float]] -> [Vector Float]
forall a b. (a -> b) -> [a] -> [b]
map [Float] -> Vector Float
forall a. Storable a => [a] -> Vector a
V.fromList

toBlocks :: Monad m => Audio m rate chan -> m [Block]
toBlocks :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan -> m [Block]
toBlocks = Stream (Of Block) m () -> m [Block]
forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m [a]
S.toList_ (Stream (Of Block) m () -> m [Block])
-> (Audio m rate chan -> Stream (Of Block) m ())
-> Audio m rate chan
-> m [Block]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Audio m rate chan -> Stream (Of Block) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream

toSamples :: Monad m => Audio m rate chan -> m [V.Vector Sample]
toSamples :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan -> m [Vector Float]
toSamples = ([Block] -> [Vector Float]) -> m [Block] -> m [Vector Float]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Block -> [Vector Float]) -> [Block] -> [Vector Float]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Block -> [Vector Float]
blockSamples) (m [Block] -> m [Vector Float])
-> (Audio m rate chan -> m [Block])
-> Audio m rate chan
-> m [Vector Float]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Audio m rate chan -> m [Block]
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan -> m [Block]
toBlocks

toBlocksN :: Monad m => NAudio m rate -> m [[Block]]
toBlocksN :: forall (m :: * -> *) (rate :: Nat).
Monad m =>
NAudio m rate -> m [[Block]]
toBlocksN = Stream (Of [Block]) m () -> m [[Block]]
forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m [a]
S.toList_ (Stream (Of [Block]) m () -> m [[Block]])
-> (NAudio m rate -> Stream (Of [Block]) m ())
-> NAudio m rate
-> m [[Block]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NAudio m rate -> Stream (Of [Block]) m ()
forall (m :: * -> *) (rate :: Nat).
NAudio m rate -> Stream (Of [Block]) m ()
_nstream

toSamplesN :: Monad m => NAudio m rate -> m [[V.Vector Sample]]
toSamplesN :: forall (m :: * -> *) (rate :: Nat).
Monad m =>
NAudio m rate -> m [[Vector Float]]
toSamplesN = ([[Block]] -> [[Vector Float]])
-> m [[Block]] -> m [[Vector Float]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([Block] -> [Vector Float]) -> [[Block]] -> [[Vector Float]]
forall a b. (a -> b) -> [a] -> [b]
map ((Block -> Vector Float) -> [Block] -> [Vector Float]
forall a b. (a -> b) -> [a] -> [b]
map Block -> Vector Float
blockVector)) (m [[Block]] -> m [[Vector Float]])
-> (NAudio m rate -> m [[Block]])
-> NAudio m rate
-> m [[Vector Float]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NAudio m rate -> m [[Block]]
forall (m :: * -> *) (rate :: Nat).
Monad m =>
NAudio m rate -> m [[Block]]
toBlocksN

-- * transform

apply :: (S.Stream (S.Of Block) m () -> S.Stream (S.Of Block) m ())
    -> Audio m rate chan -> Audio m rate chan
apply :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Stream (Of Block) m () -> Stream (Of Block) m ())
-> Audio m rate chan -> Audio m rate chan
apply Stream (Of Block) m () -> Stream (Of Block) m ()
f (Audio Stream (Of Block) m ()
stream) = Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Stream (Of Block) m ()
f Stream (Of Block) m ()
stream)

castRate :: Audio m rate1 chan -> Audio m rate2 chan
castRate :: forall (m :: * -> *) (rate1 :: Nat) (chan :: Nat) (rate2 :: Nat).
Audio m rate1 chan -> Audio m rate2 chan
castRate (Audio Stream (Of Block) m ()
stream) = Stream (Of Block) m () -> Audio m rate2 chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio Stream (Of Block) m ()
stream

take :: forall m rate chan. (Monad m, KnownNat chan)
    => Frames -> Audio m rate chan -> Audio m rate chan
take :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Frames -> Audio m rate chan -> Audio m rate chan
take = m () -> Frames -> Audio m rate chan -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
m () -> Frames -> Audio m rate chan -> Audio m rate chan
takeClose (() -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

takeS :: forall m rate chan. (Monad m, KnownNat rate, KnownNat chan)
    => Seconds -> Audio m rate chan -> Audio m rate chan
takeS :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat rate, KnownNat chan) =>
Seconds -> Audio m rate chan -> Audio m rate chan
takeS = m () -> Seconds -> Audio m rate chan -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat rate, KnownNat chan) =>
m () -> Seconds -> Audio m rate chan -> Audio m rate chan
takeCloseS (() -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

-- | This is like 'take', but it takes a close action to run when the audio
-- stream is terminated.  This is because streaming can't otherwise close
-- the input file in a timely way, because the take can't tell upstream that
-- it will never demand another chunk.  This appears to be a problem with all
-- pull-based streaming libraries, including pipes and conduit.
takeCloseS :: forall m rate chan. (Monad m, KnownNat rate, KnownNat chan)
    => m () -> Seconds -> Audio m rate chan -> Audio m rate chan
takeCloseS :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat rate, KnownNat chan) =>
m () -> Seconds -> Audio m rate chan -> Audio m rate chan
takeCloseS m ()
close Seconds
seconds Audio m rate chan
audio
    | Seconds
seconds Seconds -> Seconds -> Bool
forall a. Ord a => a -> a -> Bool
<= Seconds
0 = Audio m rate chan
forall a. Monoid a => a
mempty
    | Bool
otherwise = m () -> Frames -> Audio m rate chan -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
m () -> Frames -> Audio m rate chan -> Audio m rate chan
takeClose m ()
close
        (Int -> Seconds -> Frames
secondsToFrames (Proxy rate -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (Proxy rate
forall {k} (t :: k). Proxy t
Proxy :: Proxy rate)) Seconds
seconds) Audio m rate chan
audio

takeClose :: forall m rate chan. (Monad m, KnownNat chan)
    => m () -> Frames -> Audio m rate chan -> Audio m rate chan
takeClose :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
m () -> Frames -> Audio m rate chan -> Audio m rate chan
takeClose m ()
close Frames
frames (Audio Stream (Of Block) m ()
audio)
    | Frames
frames Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
<= Frames
0 = Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> Stream (Of Block) m () -> Audio m rate chan
forall a b. (a -> b) -> a -> b
$ m () -> Stream (Of Block) m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m ()
close
    | Bool
otherwise = Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> Stream (Of Block) m () -> Audio m rate chan
forall a b. (a -> b) -> a -> b
$ (Frames, Stream (Of Block) m ())
-> (((Frames, Stream (Of Block) m ()) -> Stream (Of Block) m ())
    -> (Frames, Stream (Of Block) m ()) -> Stream (Of Block) m ())
-> Stream (Of Block) m ()
forall state a. state -> ((state -> a) -> state -> a) -> a
Control.loop1 (Frames
0, Stream (Of Block) m ()
audio) ((((Frames, Stream (Of Block) m ()) -> Stream (Of Block) m ())
  -> (Frames, Stream (Of Block) m ()) -> Stream (Of Block) m ())
 -> Stream (Of Block) m ())
-> (((Frames, Stream (Of Block) m ()) -> Stream (Of Block) m ())
    -> (Frames, Stream (Of Block) m ()) -> Stream (Of Block) m ())
-> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$
        \(Frames, Stream (Of Block) m ()) -> Stream (Of Block) m ()
loop (Frames
now, Stream (Of Block) m ()
audio) -> m (Maybe (Block, Stream (Of Block) m ()))
-> Stream (Of Block) m (Maybe (Block, Stream (Of Block) m ()))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Stream (Of Block) m () -> m (Maybe (Block, Stream (Of Block) m ()))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Maybe (a, Stream (Of a) m r))
S.uncons Stream (Of Block) m ()
audio) Stream (Of Block) m (Maybe (Block, Stream (Of Block) m ()))
-> (Maybe (Block, Stream (Of Block) m ())
    -> Stream (Of Block) m ())
-> Stream (Of Block) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
            Maybe (Block, Stream (Of Block) m ())
Nothing -> m () -> Stream (Of Block) m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m ()
close
            Just (Block
block, Stream (Of Block) m ()
audio)
                | Frames
end Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
<= Frames
frames -> Block -> Stream (Of Block) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield Block
block Stream (Of Block) m ()
-> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Frames, Stream (Of Block) m ()) -> Stream (Of Block) m ()
loop (Frames
end, Stream (Of Block) m ()
audio)
                | Frames
now Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
>= Frames
frames -> m () -> Stream (Of Block) m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m ()
close
                | Bool
otherwise -> do
                    m () -> Stream (Of Block) m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m ()
close
                    Block -> Stream (Of Block) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield (Block -> Stream (Of Block) m ())
-> Block -> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ (Block, Block) -> Block
forall a b. (a, b) -> a
fst ((Block, Block) -> Block) -> (Block, Block) -> Block
forall a b. (a -> b) -> a -> b
$ Int -> Block -> (Block, Block)
blockSplit Int
left Block
block
                where
                end :: Frames
end = Frames
now Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
+ Proxy chan -> Block -> Frames
forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan
chan Block
block
                left :: Int
left = Proxy chan -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan
chan (Frames -> Frames -> Frames
forall a. Ord a => a -> a -> a
min Frames
frames Frames
end Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
- Frames
now)
    where chan :: Proxy chan
chan = Proxy chan
forall {k} (t :: k). Proxy t
Proxy :: Proxy chan

mapSamples :: Monad m => (Float -> Float) -> Audio m rate chan
    -> Audio m rate chan
mapSamples :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
(Float -> Float) -> Audio m rate chan -> Audio m rate chan
mapSamples Float -> Float
f = (Stream (Of Block) m () -> Stream (Of Block) m ())
-> Audio m rate chan -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Stream (Of Block) m () -> Stream (Of Block) m ())
-> Audio m rate chan -> Audio m rate chan
apply ((Block -> Block)
-> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map Block -> Block
block)
    where
    block :: Block -> Block
block (Block Vector Float
v) = Vector Float -> Block
Block ((Float -> Float) -> Vector Float -> Vector Float
forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map Float -> Float
f Vector Float
v)
    block (Constant Int
count Float
val) = Int -> Float -> Block
Constant Int
count (Float -> Float
f Float
val)

-- | Set linear gain.  Use 'dbToLinear' to scale by dB.
gain :: Monad m => Float -> Audio m rate chan -> Audio m rate chan
gain :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Float -> Audio m rate chan -> Audio m rate chan
gain Float
n Audio m rate chan
audio
    | Float
n Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
1 = Audio m rate chan
audio
    | Bool
otherwise = (Float -> Float) -> Audio m rate chan -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
(Float -> Float) -> Audio m rate chan -> Audio m rate chan
mapSamples (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
n) Audio m rate chan
audio

-- | Multiply two signals, and end with the shorter one.
multiply :: (Monad m, KnownNat chan) => Audio m rate chan -> Audio m rate chan
    -> Audio m rate chan
multiply :: forall (m :: * -> *) (chan :: Nat) (rate :: Nat).
(Monad m, KnownNat chan) =>
Audio m rate chan -> Audio m rate chan -> Audio m rate chan
multiply Audio m rate chan
audio1 Audio m rate chan
audio2 =
    Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> Stream (Of Block) m () -> Audio m rate chan
forall a b. (a -> b) -> a -> b
$ (Stream (Of (Maybe Block, Maybe Block)) m ()
 -> m (Either
         () (Block, Stream (Of (Maybe Block, Maybe Block)) m ())))
-> Stream (Of (Maybe Block, Maybe Block)) m ()
-> Stream (Of Block) m ()
forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr ((Either
   ()
   ((Maybe Block, Maybe Block),
    Stream (Of (Maybe Block, Maybe Block)) m ())
 -> Either () (Block, Stream (Of (Maybe Block, Maybe Block)) m ()))
-> m (Either
        ()
        ((Maybe Block, Maybe Block),
         Stream (Of (Maybe Block, Maybe Block)) m ()))
-> m (Either
        () (Block, Stream (Of (Maybe Block, Maybe Block)) m ()))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either
  ()
  ((Maybe Block, Maybe Block),
   Stream (Of (Maybe Block, Maybe Block)) m ())
-> Either () (Block, Stream (Of (Maybe Block, Maybe Block)) m ())
forall {b}.
Either () ((Maybe Block, Maybe Block), b) -> Either () (Block, b)
merge (m (Either
      ()
      ((Maybe Block, Maybe Block),
       Stream (Of (Maybe Block, Maybe Block)) m ()))
 -> m (Either
         () (Block, Stream (Of (Maybe Block, Maybe Block)) m ())))
-> (Stream (Of (Maybe Block, Maybe Block)) m ()
    -> m (Either
            ()
            ((Maybe Block, Maybe Block),
             Stream (Of (Maybe Block, Maybe Block)) m ())))
-> Stream (Of (Maybe Block, Maybe Block)) m ()
-> m (Either
        () (Block, Stream (Of (Maybe Block, Maybe Block)) m ()))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stream (Of (Maybe Block, Maybe Block)) m ()
-> m (Either
        ()
        ((Maybe Block, Maybe Block),
         Stream (Of (Maybe Block, Maybe Block)) m ()))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r))
S.next) (Stream (Of (Maybe Block, Maybe Block)) m ()
 -> Stream (Of Block) m ())
-> Stream (Of (Maybe Block, Maybe Block)) m ()
-> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ Audio m rate chan
-> Audio m rate chan -> Stream (Of (Maybe Block, Maybe Block)) m ()
forall (m :: * -> *) (rate :: Nat) (chan1 :: Nat) (chan2 :: Nat).
(Monad m, KnownNat chan1, KnownNat chan2) =>
Audio m rate chan1
-> Audio m rate chan2
-> Stream (Of (Maybe Block, Maybe Block)) m ()
synchronize Audio m rate chan
audio1 Audio m rate chan
audio2
    where
    merge :: Either () ((Maybe Block, Maybe Block), b) -> Either () (Block, b)
merge = \case
        Left () -> () -> Either () (Block, b)
forall a b. a -> Either a b
Left ()
        Right ((Maybe Block
Nothing, Maybe Block
_), b
_) -> () -> Either () (Block, b)
forall a b. a -> Either a b
Left ()
        Right ((Maybe Block
_, Maybe Block
Nothing), b
_) -> () -> Either () (Block, b)
forall a b. a -> Either a b
Left ()
        -- Since they have the same channels, there's no need to deinterleave.
        Right ((Just Block
b1, Just Block
b2), b
audio) -> (Block, b) -> Either () (Block, b)
forall a b. b -> Either a b
Right (Block -> Block -> Block
blockMultiply Block
b1 Block
b2, b
audio)

blockMultiply :: Block -> Block -> Block
blockMultiply :: Block -> Block -> Block
blockMultiply (Constant Int
c1 Float
v1) (Constant Int
c2 Float
v2) = Int -> Float -> Block
Constant (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
c1 Int
c2) (Float
v1Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
v2)
blockMultiply b1 :: Block
b1@(Block {}) b2 :: Block
b2@(Constant {}) = Block -> Block -> Block
blockMultiply Block
b2 Block
b1
blockMultiply (Constant Int
c1 Float
v1) (Block Vector Float
b2)
    | Float
v1 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0 = Int -> Float -> Block
Constant (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
c1 (Vector Float -> Int
forall a. Storable a => Vector a -> Int
V.length Vector Float
b2)) Float
0
    | Float
v1 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
1 = Vector Float -> Block
Block Vector Float
b2
    | Bool
otherwise = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ (Float -> Float) -> Vector Float -> Vector Float
forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
v1) (Vector Float -> Vector Float) -> Vector Float -> Vector Float
forall a b. (a -> b) -> a -> b
$ Int -> Vector Float -> Vector Float
forall a. Storable a => Int -> Vector a -> Vector a
V.take Int
c1 Vector Float
b2
blockMultiply (Block Vector Float
b1) (Block Vector Float
b2) = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ (Float -> Float -> Float)
-> Vector Float -> Vector Float -> Vector Float
forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith Float -> Float -> Float
forall a. Num a => a -> a -> a
(*) Vector Float
b1 Vector Float
b2

-- blockZipWith :: (Sample -> Sample -> Sample) -> Block -> Block -> Block
-- blockZipWith f (Constant c1 v1) (Constant c2 v2) =
--     Constant (min c1 c2) (f v1 v2)
-- blockZipWith f b1 b2 = Block $
--     V.zipWith f (mconcat (blockSamples b1)) (mconcat (blockSamples b2))

-- | Pan a stereo signal with a mono one.  The pan signal goes from -1 to 1.
--
-- TODO This is linear panning, try constant power or -4.5dB:
-- http://www.cs.cmu.edu/~music/icm-online/readings/panlaws/
pan :: Monad m => Audio m rate 1 -> Audio m rate 2 -> Audio m rate 2
pan :: forall (m :: * -> *) (rate :: Nat).
Monad m =>
Audio m rate 1 -> Audio m rate 2 -> Audio m rate 2
pan Audio m rate 1
pos Audio m rate 2
audio = Stream (Of Block) m () -> Audio m rate 2
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate 2)
-> Stream (Of Block) m () -> Audio m rate 2
forall a b. (a -> b) -> a -> b
$ (Stream (Of (Maybe Block, Maybe Block)) m ()
 -> m (Either
         () (Block, Stream (Of (Maybe Block, Maybe Block)) m ())))
-> Stream (Of (Maybe Block, Maybe Block)) m ()
-> Stream (Of Block) m ()
forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr ((Either
   ()
   ((Maybe Block, Maybe Block),
    Stream (Of (Maybe Block, Maybe Block)) m ())
 -> Either () (Block, Stream (Of (Maybe Block, Maybe Block)) m ()))
-> m (Either
        ()
        ((Maybe Block, Maybe Block),
         Stream (Of (Maybe Block, Maybe Block)) m ()))
-> m (Either
        () (Block, Stream (Of (Maybe Block, Maybe Block)) m ()))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either
  ()
  ((Maybe Block, Maybe Block),
   Stream (Of (Maybe Block, Maybe Block)) m ())
-> Either () (Block, Stream (Of (Maybe Block, Maybe Block)) m ())
forall {b}.
Either () ((Maybe Block, Maybe Block), b) -> Either () (Block, b)
merge (m (Either
      ()
      ((Maybe Block, Maybe Block),
       Stream (Of (Maybe Block, Maybe Block)) m ()))
 -> m (Either
         () (Block, Stream (Of (Maybe Block, Maybe Block)) m ())))
-> (Stream (Of (Maybe Block, Maybe Block)) m ()
    -> m (Either
            ()
            ((Maybe Block, Maybe Block),
             Stream (Of (Maybe Block, Maybe Block)) m ())))
-> Stream (Of (Maybe Block, Maybe Block)) m ()
-> m (Either
        () (Block, Stream (Of (Maybe Block, Maybe Block)) m ()))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stream (Of (Maybe Block, Maybe Block)) m ()
-> m (Either
        ()
        ((Maybe Block, Maybe Block),
         Stream (Of (Maybe Block, Maybe Block)) m ()))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r))
S.next) (Stream (Of (Maybe Block, Maybe Block)) m ()
 -> Stream (Of Block) m ())
-> Stream (Of (Maybe Block, Maybe Block)) m ()
-> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ Audio m rate 1
-> Audio m rate 2 -> Stream (Of (Maybe Block, Maybe Block)) m ()
forall (m :: * -> *) (rate :: Nat) (chan1 :: Nat) (chan2 :: Nat).
(Monad m, KnownNat chan1, KnownNat chan2) =>
Audio m rate chan1
-> Audio m rate chan2
-> Stream (Of (Maybe Block, Maybe Block)) m ()
synchronize Audio m rate 1
pos Audio m rate 2
audio
    where
    merge :: Either () ((Maybe Block, Maybe Block), b) -> Either () (Block, b)
merge = \case
        Left () -> () -> Either () (Block, b)
forall a b. a -> Either a b
Left ()
        Right ((Maybe Block
Nothing, Maybe Block
_), b
_) -> () -> Either () (Block, b)
forall a b. a -> Either a b
Left ()
        Right ((Maybe Block
_, Maybe Block
Nothing), b
_) -> () -> Either () (Block, b)
forall a b. a -> Either a b
Left ()
        Right ((Just Block
_, Just (Constant Int
c Float
0)), b
audio) ->
            (Block, b) -> Either () (Block, b)
forall a b. b -> Either a b
Right (Int -> Float -> Block
Constant Int
c Float
0, b
audio)
        Right ((Just (Constant Int
_ Float
0), Just Block
stereo), b
audio) ->
            (Block, b) -> Either () (Block, b)
forall a b. b -> Either a b
Right (Block
stereo, b
audio)
        Right ((Just Block
pos_, Just Block
stereo), b
audio) -> (Block, b) -> Either () (Block, b)
forall a b. b -> Either a b
Right
            ( Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ [Vector Float] -> Vector Float
forall a. Storable a => [Vector a] -> Vector a
interleaveV
                [ (Float -> Float -> Float)
-> Vector Float -> Vector Float -> Vector Float
forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith Float -> Float -> Float
forall a. Num a => a -> a -> a
(*) ((Float -> Float) -> Vector Float -> Vector Float
forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map ((Float
2-) (Float -> Float) -> (Float -> Float) -> Float -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Float -> Float -> Float
forall a. Num a => a -> a -> a
+Float
1)) Vector Float
pos) Vector Float
left
                , (Float -> Float -> Float)
-> Vector Float -> Vector Float -> Vector Float
forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith Float -> Float -> Float
forall a. Num a => a -> a -> a
(*) ((Float -> Float) -> Vector Float -> Vector Float
forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (Float -> Float -> Float
forall a. Num a => a -> a -> a
+Float
1) Vector Float
pos) Vector Float
right
                ]
            , b
audio
            )
            where
            pos :: Vector Float
pos = Block -> Vector Float
blockVector Block
pos_
            [Vector Float
left, Vector Float
right] = Int -> Vector Float -> [Vector Float]
forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
2 (Vector Float -> [Vector Float]) -> Vector Float -> [Vector Float]
forall a b. (a -> b) -> a -> b
$ Block -> Vector Float
blockVector Block
stereo

-- | Like 'pan', but more efficient.  TODO also linear pan, as in 'pan'.
panConstant :: Monad m => Sample -> Audio m rate 2 -> Audio m rate 2
panConstant :: forall (m :: * -> *) (rate :: Nat).
Monad m =>
Float -> Audio m rate 2 -> Audio m rate 2
panConstant Float
pos
    | Seconds -> Float -> Float -> Bool
forall a. ApproxEq a => Seconds -> a -> a -> Bool
ApproxEq.eq Seconds
0.01 Float
pos Float
0 = Audio m rate 2 -> Audio m rate 2
forall a. a -> a
id
    | Bool
otherwise = Stream (Of Block) m () -> Audio m rate 2
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate 2)
-> (Audio m rate 2 -> Stream (Of Block) m ())
-> Audio m rate 2
-> Audio m rate 2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Block -> Block)
-> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map Block -> Block
pan (Stream (Of Block) m () -> Stream (Of Block) m ())
-> (Audio m rate 2 -> Stream (Of Block) m ())
-> Audio m rate 2
-> Stream (Of Block) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Audio m rate 2 -> Stream (Of Block) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream
    where
    pan :: Block -> Block
pan (Constant Int
count Float
val) | Float
val Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0 = Int -> Float -> Block
Constant Int
count Float
0
    pan Block
stereo = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ [Vector Float] -> Vector Float
forall a. Storable a => [Vector a] -> Vector a
interleaveV
        [ (Float -> Float) -> Vector Float -> Vector Float
forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
posFloat -> Float -> Float
forall a. Num a => a -> a -> a
+Float
1))) Vector Float
left
        , (Float -> Float) -> Vector Float -> Vector Float
forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
posFloat -> Float -> Float
forall a. Num a => a -> a -> a
+Float
1)) Vector Float
right
        ]
        where [Vector Float
left, Vector Float
right] = Int -> Vector Float -> [Vector Float]
forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
2 (Vector Float -> [Vector Float]) -> Vector Float -> [Vector Float]
forall a b. (a -> b) -> a -> b
$ Block -> Vector Float
blockVector Block
stereo

-- * mix

-- | Mix together the audio streams at the given start times.
--
-- TODO the input could also be a stream, in case it somehow comes from IO.
mix :: Monad m => [Audio m rate chan] -> Audio m rate chan
mix :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
[Audio m rate chan] -> Audio m rate chan
mix = Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> ([Audio m rate chan] -> Stream (Of Block) m ())
-> [Audio m rate chan]
-> Audio m rate chan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Block] -> Block)
-> Stream (Of [Block]) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map [Block] -> Block
merge (Stream (Of [Block]) m () -> Stream (Of Block) m ())
-> ([Audio m rate chan] -> Stream (Of [Block]) m ())
-> [Audio m rate chan]
-> Stream (Of Block) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Audio m rate chan] -> Stream (Of [Block]) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
[Audio m rate chan] -> Stream (Of [Block]) m ()
synchronizeList
    where
    merge :: [Block] -> Block
merge [] = Vector Float -> Block
Block Vector Float
forall a. Storable a => Vector a
V.empty
    merge blocks :: [Block]
blocks@(Block
block:[Block]
_)
        | [Vector Float] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Vector Float]
vectors = Int -> Float -> Block
Constant (Block -> Int
blockCount Block
block) Float
constant
        | Bool
otherwise = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$
            (if Float
constant Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0 then Vector Float -> Vector Float
forall a. a -> a
id else (Float -> Float) -> Vector Float -> Vector Float
forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (Float -> Float -> Float
forall a. Num a => a -> a -> a
+Float
constant)) (Vector Float -> Vector Float) -> Vector Float -> Vector Float
forall a b. (a -> b) -> a -> b
$ Int -> [Vector Float] -> Vector Float
mixV Int
0 [Vector Float]
vectors
        where
        constant :: Float
constant = [Float] -> Float
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
Num.sum [Float
val | Constant Int
_ Float
val <- [Block]
blocks]
        vectors :: [Vector Float]
vectors = [Vector Float
v | Block Vector Float
v <- [Block]
blocks]

-- | Add vectors of samples.  The output will be the max of the longest vector
-- and the provided minimum length.
mixV :: Count -> [V.Vector Sample] -> V.Vector Sample
mixV :: Int -> [Vector Float] -> Vector Float
mixV Int
len [] = Int -> Float -> Vector Float
forall a. Storable a => Int -> a -> Vector a
V.replicate Int
len Float
0
mixV Int
len [Vector Float
v]
    | Vector Float -> Int
forall a. Storable a => Vector a -> Int
V.length Vector Float
v Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
len = Vector Float
v
    | Bool
otherwise = Vector Float
v Vector Float -> Vector Float -> Vector Float
forall a. Semigroup a => a -> a -> a
<> Int -> Float -> Vector Float
forall a. Storable a => Int -> a -> Vector a
V.replicate (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Vector Float -> Int
forall a. Storable a => Vector a -> Int
V.length Vector Float
v) Float
0
mixV Int
len [Vector Float]
vectors = Int -> [Vector Float] -> Vector Float
VectorC.mixFloats Int
len [Vector Float]
vectors


-- * channels

mergeChannels :: forall m rate chan1 chan2.
    (Monad m, KnownNat chan1, KnownNat chan2)
    => Audio m rate chan1 -> Audio m rate chan2
    -> Audio m rate (chan1 TypeLits.+ chan2)
mergeChannels :: forall (m :: * -> *) (rate :: Nat) (chan1 :: Nat) (chan2 :: Nat).
(Monad m, KnownNat chan1, KnownNat chan2) =>
Audio m rate chan1
-> Audio m rate chan2 -> Audio m rate (chan1 + chan2)
mergeChannels Audio m rate chan1
audio1 Audio m rate chan2
audio2 =
    Stream (Of Block) m () -> Audio m rate (chan1 + chan2)
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate (chan1 + chan2))
-> Stream (Of Block) m () -> Audio m rate (chan1 + chan2)
forall a b. (a -> b) -> a -> b
$ ((Maybe Block, Maybe Block) -> Block)
-> Stream (Of (Maybe Block, Maybe Block)) m ()
-> Stream (Of Block) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map ((Block, Block) -> Block
merge ((Block, Block) -> Block)
-> ((Maybe Block, Maybe Block) -> (Block, Block))
-> (Maybe Block, Maybe Block)
-> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Block, Maybe Block) -> (Block, Block)
to0) (Stream (Of (Maybe Block, Maybe Block)) m ()
 -> Stream (Of Block) m ())
-> Stream (Of (Maybe Block, Maybe Block)) m ()
-> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ Audio m rate chan1
-> Audio m rate chan2
-> Stream (Of (Maybe Block, Maybe Block)) m ()
forall (m :: * -> *) (rate :: Nat) (chan1 :: Nat) (chan2 :: Nat).
(Monad m, KnownNat chan1, KnownNat chan2) =>
Audio m rate chan1
-> Audio m rate chan2
-> Stream (Of (Maybe Block, Maybe Block)) m ()
synchronize Audio m rate chan1
audio1 Audio m rate chan2
audio2
    where
    to0 :: (Maybe Block, Maybe Block) -> (Block, Block)
to0 (Maybe Block
a1, Maybe Block
a2) =
        ( Block -> Maybe Block -> Block
forall a. a -> Maybe a -> a
fromMaybe (Int -> Float -> Block
Constant Int
count1 Float
0) Maybe Block
a1
        , Block -> Maybe Block -> Block
forall a. a -> Maybe a -> a
fromMaybe (Int -> Float -> Block
Constant Int
count2 Float
0) Maybe Block
a2
        )
        where
        count1 :: Int
count1 = Proxy chan1 -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan1
chan1 (Frames -> Int) -> Frames -> Int
forall a b. (a -> b) -> a -> b
$ Frames -> (Block -> Frames) -> Maybe Block -> Frames
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Frames
0 (Proxy chan2 -> Block -> Frames
forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan2
chan2) Maybe Block
a2
        count2 :: Int
count2 = Proxy chan2 -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan2
chan2 (Frames -> Int) -> Frames -> Int
forall a b. (a -> b) -> a -> b
$ Frames -> (Block -> Frames) -> Maybe Block -> Frames
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Frames
0 (Proxy chan1 -> Block -> Frames
forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan1
chan1) Maybe Block
a1
    -- These should now have the same number of frames.
    merge :: (Block, Block) -> Block
merge = \case
        -- Due to synchronize, c1 == c2
        (Constant Int
c1 Float
v1, Constant Int
c2 Float
v2) | Float
v1 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
v2 -> Int -> Float -> Block
Constant (Int
c1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
c2) Float
v1
        (Block
b1, Block
b2) -> Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ [Vector Float] -> Vector Float
forall a. Storable a => [Vector a] -> Vector a
interleaveV ([Vector Float] -> Vector Float) -> [Vector Float] -> Vector Float
forall a b. (a -> b) -> a -> b
$
            Int -> Vector Float -> [Vector Float]
forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV (Proxy chan1 -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal Proxy chan1
chan1) (Block -> Vector Float
blockVector Block
b1)
            [Vector Float] -> [Vector Float] -> [Vector Float]
forall a. [a] -> [a] -> [a]
++ Int -> Vector Float -> [Vector Float]
forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV (Proxy chan2 -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal Proxy chan2
chan2) (Block -> Vector Float
blockVector Block
b2)
    chan1 :: Proxy chan1
chan1 = forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @chan1
    chan2 :: Proxy chan2
chan2 = forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @chan2

-- | Extract a single channel.  It will crash unless 0 <= idx < chan.
--
-- See 'splitChannels' to get them all.
extractChannel :: forall m rate chan. (Monad m, KnownNat chan)
    => Channels -> Audio m rate chan -> Audio m rate 1
extractChannel :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Int -> Audio m rate chan -> Audio m rate 1
extractChannel Int
idx = Stream (Of Block) m () -> Audio m rate 1
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate 1)
-> (Audio m rate chan -> Stream (Of Block) m ())
-> Audio m rate chan
-> Audio m rate 1
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Block -> Block)
-> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map Block -> Block
extract (Stream (Of Block) m () -> Stream (Of Block) m ())
-> (Audio m rate chan -> Stream (Of Block) m ())
-> Audio m rate chan
-> Stream (Of Block) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Audio m rate chan -> Stream (Of Block) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream
    where
    extract :: Block -> Block
extract (Constant Int
count Float
val) = Int -> Float -> Block
Constant (Int
count Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
chan) Float
val
    extract (Block Vector Float
v) = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ Int -> Vector Float -> [Vector Float]
forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
chan Vector Float
v [Vector Float] -> Int -> Vector Float
forall a. [a] -> Int -> a
!! Int
idx
    chan :: Int
chan = Proxy chan -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @chan)

-- | De-interleave the audio.  This is the inverse of 'splitChannels', but it
-- converts to NAudio, since [Audio] would amount to an unzip, which streams
-- don't support in a straightforward way.
splitChannels :: forall m rate chan. (Monad m, KnownNat chan)
    => Audio m rate chan -> NAudio m rate
splitChannels :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Audio m rate chan -> NAudio m rate
splitChannels = Int -> Stream (Of [Block]) m () -> NAudio m rate
forall (m :: * -> *) (rate :: Nat).
Int -> Stream (Of [Block]) m () -> NAudio m rate
NAudio Int
chan (Stream (Of [Block]) m () -> NAudio m rate)
-> (Audio m rate chan -> Stream (Of [Block]) m ())
-> Audio m rate chan
-> NAudio m rate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Block -> [Block])
-> Stream (Of Block) m () -> Stream (Of [Block]) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map (Int -> Block -> [Block]
deinterleaveB Int
chan) (Stream (Of Block) m () -> Stream (Of [Block]) m ())
-> (Audio m rate chan -> Stream (Of Block) m ())
-> Audio m rate chan
-> Stream (Of [Block]) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Audio m rate chan -> Stream (Of Block) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream
    where chan :: Int
chan = Proxy chan -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @chan)

-- | Take a single channel signal to multiple channels by copying samples.
--
-- This could be generalized to expand n to m where m is divisible by n, but
-- that's more complicated and I don't need it.
expandChannels :: forall m rate chan. (Monad m, KnownNat chan)
    => Audio m rate 1 -> Audio m rate chan
expandChannels :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Audio m rate 1 -> Audio m rate chan
expandChannels (Audio Stream (Of Block) m ()
audio) = Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> Stream (Of Block) m () -> Audio m rate chan
forall a b. (a -> b) -> a -> b
$ (Block -> Block)
-> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map (Int -> Block -> Block
expandB Int
chan) Stream (Of Block) m ()
audio
    where chan :: Int
chan = Proxy chan -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (Proxy chan
forall {k} (t :: k). Proxy t
Proxy :: Proxy chan)

expandB :: Channels -> Block -> Block
expandB :: Int -> Block -> Block
expandB Int
chan (Constant Int
count Float
val) = Int -> Float -> Block
Constant (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
chan) Float
val
expandB Int
chan (Block Vector Float
v) = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ Int -> Vector Float -> Vector Float
expandV Int
chan Vector Float
v

expandV :: Channels -> V.Vector Sample -> V.Vector Sample
expandV :: Int -> Vector Float -> Vector Float
expandV Int
chan Vector Float
block =
    Int -> (Int -> Float) -> Vector Float
forall a. Storable a => Int -> (Int -> a) -> Vector a
V.generate (Vector Float -> Int
forall a. Storable a => Vector a -> Int
V.length Vector Float
block Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
chan) ((Int -> Float) -> Vector Float) -> (Int -> Float) -> Vector Float
forall a b. (a -> b) -> a -> b
$ \Int
i -> Vector Float
block Vector Float -> Int -> Float
forall a. Storable a => Vector a -> Int -> a
V.! (Int
i Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
chan)

-- | Do the reverse of 'expandChannels', mixing all channels to a mono signal.
mixChannels :: forall m rate chan. (Monad m, KnownNat chan)
    => Audio m rate chan -> Audio m rate 1
mixChannels :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Audio m rate chan -> Audio m rate 1
mixChannels (Audio Stream (Of Block) m ()
audio) = Stream (Of Block) m () -> Audio m rate 1
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate 1)
-> Stream (Of Block) m () -> Audio m rate 1
forall a b. (a -> b) -> a -> b
$ (Block -> Block)
-> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map Block -> Block
mix Stream (Of Block) m ()
audio
    where
    mix :: Block -> Block
mix (Constant Int
count Float
val) = Int -> Float -> Block
Constant (Int
count Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
chan) Float
val
    mix (Block Vector Float
v) = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ Int -> [Vector Float] -> Vector Float
mixV Int
0 ([Vector Float] -> Vector Float) -> [Vector Float] -> Vector Float
forall a b. (a -> b) -> a -> b
$ Int -> Vector Float -> [Vector Float]
forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
chan Vector Float
v
    chan :: Int
chan = Proxy chan -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @chan)

deinterleaveB :: Channels -> Block -> [Block]
deinterleaveB :: Int -> Block -> [Block]
deinterleaveB Int
chan (Constant Int
count Float
val) =
    Int -> Block -> [Block]
forall a. Int -> a -> [a]
replicate Int
chan (Block -> [Block]) -> Block -> [Block]
forall a b. (a -> b) -> a -> b
$ Int -> Float -> Block
Constant (Int
count Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
chan) Float
val
deinterleaveB Int
chan (Block Vector Float
v) = (Vector Float -> Block) -> [Vector Float] -> [Block]
forall a b. (a -> b) -> [a] -> [b]
map Vector Float -> Block
Block ([Vector Float] -> [Block]) -> [Vector Float] -> [Block]
forall a b. (a -> b) -> a -> b
$ Int -> Vector Float -> [Vector Float]
forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
chan Vector Float
v

deinterleaveV :: V.Storable a => Channels -> V.Vector a -> [V.Vector a]
deinterleaveV :: forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
channels Vector a
v
    | Int
channels Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = [Vector a
v]
    | Bool
otherwise = (Int -> Vector a) -> [Int] -> [Vector a]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Vector a
gen [Int
0 .. Int
channels Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
    where
    gen :: Int -> Vector a
gen Int
chan = Int -> (Int -> a) -> Vector a
forall a. Storable a => Int -> (Int -> a) -> Vector a
V.generate Int
frames (\Int
i -> Vector a
v Vector a -> Int -> a
forall a. Storable a => Vector a -> Int -> a
V.! (Int
channels Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
chan))
    frames :: Int
frames = Vector a -> Int
forall a. Storable a => Vector a -> Int
V.length Vector a
v Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
channels

interleaveB :: [Block] -> Block
interleaveB :: [Block] -> Block
interleaveB (b :: Block
b@(Constant Int
count Float
val) : [Block]
bs) | (Block -> Bool) -> [Block] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Block -> Block -> Bool
forall a. Eq a => a -> a -> Bool
==Block
b) [Block]
bs =
    Int -> Float -> Block
Constant (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
* ([Block] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Block]
bs Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)) Float
val
interleaveB [Block]
bs = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ [Vector Float] -> Vector Float
forall a. Storable a => [Vector a] -> Vector a
interleaveV ([Vector Float] -> Vector Float) -> [Vector Float] -> Vector Float
forall a b. (a -> b) -> a -> b
$ (Block -> Vector Float) -> [Block] -> [Vector Float]
forall a b. (a -> b) -> [a] -> [b]
map Block -> Vector Float
blockVector [Block]
bs

interleaveV :: V.Storable a => [V.Vector a] -> V.Vector a
interleaveV :: forall a. Storable a => [Vector a] -> Vector a
interleaveV [Vector a]
vs = (forall s. ST s (MVector s a)) -> Vector a
forall a. Storable a => (forall s. ST s (MVector s a)) -> Vector a
V.create ((forall s. ST s (MVector s a)) -> Vector a)
-> (forall s. ST s (MVector s a)) -> Vector a
forall a b. (a -> b) -> a -> b
$ do
    MVector s a
out <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> m (MVector (PrimState m) a)
VM.new (Int -> ST s (MVector (PrimState (ST s)) a))
-> Int -> ST s (MVector (PrimState (ST s)) a)
forall a b. (a -> b) -> a -> b
$ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
Num.sum ((Vector a -> Int) -> [Vector a] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Vector a -> Int
forall a. Storable a => Vector a -> Int
V.length [Vector a]
vs)
    [(Int, Vector a)] -> ((Int, Vector a) -> ST s ()) -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ([Int] -> [Vector a] -> [(Int, Vector a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] [Vector a]
vs) (((Int, Vector a) -> ST s ()) -> ST s ())
-> ((Int, Vector a) -> ST s ()) -> ST s ()
forall a b. (a -> b) -> a -> b
$ \(Int
vi, Vector a
v) ->
        [Int] -> (Int -> ST s ()) -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Int -> Int -> Int -> [Int]
forall a. (Num a, Ord a) => a -> a -> a -> [a]
Seq.range' Int
0 (Vector a -> Int
forall a. Storable a => Vector a -> Int
V.length Vector a
v) Int
1) ((Int -> ST s ()) -> ST s ()) -> (Int -> ST s ()) -> ST s ()
forall a b. (a -> b) -> a -> b
$ \Int
i ->
            MVector (PrimState (ST s)) a -> Int -> a -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
VM.write MVector s a
MVector (PrimState (ST s)) a
out (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
stride Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
vi) (Vector a -> Int -> a
forall a. Storable a => Vector a -> Int -> a
V.unsafeIndex Vector a
v Int
i)
    MVector s a -> ST s (MVector s a)
forall (m :: * -> *) a. Monad m => a -> m a
return MVector s a
out
    where stride :: Int
stride = [Vector a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Vector a]
vs

-- | Synchronize block size for two streams.  If one stream runs out ahead of
-- the other, it will emit Nothings.
synchronize :: forall m rate chan1 chan2.
    (Monad m, KnownNat chan1, KnownNat chan2)
    => Audio m rate chan1 -> Audio m rate chan2
    -> S.Stream (S.Of (Maybe Block, Maybe Block)) m ()
synchronize :: forall (m :: * -> *) (rate :: Nat) (chan1 :: Nat) (chan2 :: Nat).
(Monad m, KnownNat chan1, KnownNat chan2) =>
Audio m rate chan1
-> Audio m rate chan2
-> Stream (Of (Maybe Block, Maybe Block)) m ()
synchronize Audio m rate chan1
audio1 Audio m rate chan2
audio2 = ((Stream (Of Block) m (), Stream (Of Block) m ())
 -> m (Either
         ()
         ((Maybe Block, Maybe Block),
          (Stream (Of Block) m (), Stream (Of Block) m ()))))
-> (Stream (Of Block) m (), Stream (Of Block) m ())
-> Stream (Of (Maybe Block, Maybe Block)) m ()
forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr (Stream (Of Block) m (), Stream (Of Block) m ())
-> m (Either
        ()
        ((Maybe Block, Maybe Block),
         (Stream (Of Block) m (), Stream (Of Block) m ())))
forall {m :: * -> *} {r} {r}.
Monad m =>
(Stream (Of Block) m r, Stream (Of Block) m r)
-> m (Either
        ()
        ((Maybe Block, Maybe Block),
         (Stream (Of Block) m r, Stream (Of Block) m r)))
unfold (Audio m rate chan1 -> Stream (Of Block) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream Audio m rate chan1
audio1, Audio m rate chan2 -> Stream (Of Block) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream Audio m rate chan2
audio2)
    where
    unfold :: (Stream (Of Block) m r, Stream (Of Block) m r)
-> m (Either
        ()
        ((Maybe Block, Maybe Block),
         (Stream (Of Block) m r, Stream (Of Block) m r)))
unfold (Stream (Of Block) m r
a1, Stream (Of Block) m r
a2) = Stream (Of Block) m r
-> Stream (Of Block) m r
-> (Maybe (Block, Stream (Of Block) m r),
    Maybe (Block, Stream (Of Block) m r))
-> Either
     ()
     ((Maybe Block, Maybe Block),
      (Stream (Of Block) m r, Stream (Of Block) m r))
forall {m :: * -> *} {m :: * -> *} {r} {r}.
(Monad m, Monad m) =>
Stream (Of Block) m r
-> Stream (Of Block) m r
-> (Maybe (Block, Stream (Of Block) m r),
    Maybe (Block, Stream (Of Block) m r))
-> Either
     ()
     ((Maybe Block, Maybe Block),
      (Stream (Of Block) m r, Stream (Of Block) m r))
recons Stream (Of Block) m r
a1 Stream (Of Block) m r
a2 ((Maybe (Block, Stream (Of Block) m r),
  Maybe (Block, Stream (Of Block) m r))
 -> Either
      ()
      ((Maybe Block, Maybe Block),
       (Stream (Of Block) m r, Stream (Of Block) m r)))
-> m (Maybe (Block, Stream (Of Block) m r),
      Maybe (Block, Stream (Of Block) m r))
-> m (Either
        ()
        ((Maybe Block, Maybe Block),
         (Stream (Of Block) m r, Stream (Of Block) m r)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((,) (Maybe (Block, Stream (Of Block) m r)
 -> Maybe (Block, Stream (Of Block) m r)
 -> (Maybe (Block, Stream (Of Block) m r),
     Maybe (Block, Stream (Of Block) m r)))
-> m (Maybe (Block, Stream (Of Block) m r))
-> m (Maybe (Block, Stream (Of Block) m r)
      -> (Maybe (Block, Stream (Of Block) m r),
          Maybe (Block, Stream (Of Block) m r)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Stream (Of Block) m r -> m (Maybe (Block, Stream (Of Block) m r))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Maybe (a, Stream (Of a) m r))
S.uncons Stream (Of Block) m r
a1 m (Maybe (Block, Stream (Of Block) m r)
   -> (Maybe (Block, Stream (Of Block) m r),
       Maybe (Block, Stream (Of Block) m r)))
-> m (Maybe (Block, Stream (Of Block) m r))
-> m (Maybe (Block, Stream (Of Block) m r),
      Maybe (Block, Stream (Of Block) m r))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Stream (Of Block) m r -> m (Maybe (Block, Stream (Of Block) m r))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Maybe (a, Stream (Of a) m r))
S.uncons Stream (Of Block) m r
a2)
    recons :: Stream (Of Block) m r
-> Stream (Of Block) m r
-> (Maybe (Block, Stream (Of Block) m r),
    Maybe (Block, Stream (Of Block) m r))
-> Either
     ()
     ((Maybe Block, Maybe Block),
      (Stream (Of Block) m r, Stream (Of Block) m r))
recons Stream (Of Block) m r
a1 Stream (Of Block) m r
a2 = \case
        (Maybe (Block, Stream (Of Block) m r)
Nothing, Maybe (Block, Stream (Of Block) m r)
Nothing) -> ()
-> Either
     ()
     ((Maybe Block, Maybe Block),
      (Stream (Of Block) m r, Stream (Of Block) m r))
forall a b. a -> Either a b
Left ()
        (Just (Block
b1, Stream (Of Block) m r
as1), Maybe (Block, Stream (Of Block) m r)
Nothing) -> ((Maybe Block, Maybe Block),
 (Stream (Of Block) m r, Stream (Of Block) m r))
-> Either
     ()
     ((Maybe Block, Maybe Block),
      (Stream (Of Block) m r, Stream (Of Block) m r))
forall a b. b -> Either a b
Right ((Block -> Maybe Block
forall a. a -> Maybe a
Just Block
b1, Maybe Block
forall a. Maybe a
Nothing), (Stream (Of Block) m r
as1, Stream (Of Block) m r
a2))
        (Maybe (Block, Stream (Of Block) m r)
Nothing, Just (Block
b2, Stream (Of Block) m r
as2)) -> ((Maybe Block, Maybe Block),
 (Stream (Of Block) m r, Stream (Of Block) m r))
-> Either
     ()
     ((Maybe Block, Maybe Block),
      (Stream (Of Block) m r, Stream (Of Block) m r))
forall a b. b -> Either a b
Right ((Maybe Block
forall a. Maybe a
Nothing, Block -> Maybe Block
forall a. a -> Maybe a
Just Block
b2), (Stream (Of Block) m r
a1, Stream (Of Block) m r
as2))
        (Just (Block
b1, Stream (Of Block) m r
as1), Just (Block
b2, Stream (Of Block) m r
as2)) -> ((Maybe Block, Maybe Block),
 (Stream (Of Block) m r, Stream (Of Block) m r))
-> Either
     ()
     ((Maybe Block, Maybe Block),
      (Stream (Of Block) m r, Stream (Of Block) m r))
forall a b. b -> Either a b
Right (((Maybe Block, Maybe Block),
  (Stream (Of Block) m r, Stream (Of Block) m r))
 -> Either
      ()
      ((Maybe Block, Maybe Block),
       (Stream (Of Block) m r, Stream (Of Block) m r)))
-> ((Maybe Block, Maybe Block),
    (Stream (Of Block) m r, Stream (Of Block) m r))
-> Either
     ()
     ((Maybe Block, Maybe Block),
      (Stream (Of Block) m r, Stream (Of Block) m r))
forall a b. (a -> b) -> a -> b
$
            case Frames -> Frames -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Frames
frames1 Frames
frames2 of
                Ordering
LT -> ((Block -> Maybe Block
forall a. a -> Maybe a
Just Block
b1, Block -> Maybe Block
forall a. a -> Maybe a
Just Block
pre2), (Stream (Of Block) m r
as1, Block -> Stream (Of Block) m r -> Stream (Of Block) m r
forall (m :: * -> *) a r.
Monad m =>
a -> Stream (Of a) m r -> Stream (Of a) m r
S.cons Block
post2 Stream (Of Block) m r
as2))
                Ordering
GT -> ((Block -> Maybe Block
forall a. a -> Maybe a
Just Block
pre1, Block -> Maybe Block
forall a. a -> Maybe a
Just Block
b2), (Block -> Stream (Of Block) m r -> Stream (Of Block) m r
forall (m :: * -> *) a r.
Monad m =>
a -> Stream (Of a) m r -> Stream (Of a) m r
S.cons Block
post1 Stream (Of Block) m r
as1, Stream (Of Block) m r
as2))
                Ordering
EQ -> ((Block -> Maybe Block
forall a. a -> Maybe a
Just Block
b1, Block -> Maybe Block
forall a. a -> Maybe a
Just Block
b2), (Stream (Of Block) m r
as1, Stream (Of Block) m r
as2))
            where
            frames1 :: Frames
frames1 = Proxy chan1 -> Block -> Frames
forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan1
chan1 Block
b1
            frames2 :: Frames
frames2 = Proxy chan2 -> Block -> Frames
forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan2
chan2 Block
b2
            (Block
pre1, Block
post1) = Int -> Block -> (Block, Block)
blockSplit (Proxy chan1 -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan1
chan1 Frames
shortest) Block
b1
            (Block
pre2, Block
post2) = Int -> Block -> (Block, Block)
blockSplit (Proxy chan2 -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan2
chan2 Frames
shortest) Block
b2
            shortest :: Frames
shortest = Frames -> Frames -> Frames
forall a. Ord a => a -> a -> a
min Frames
frames1 Frames
frames2
    chan1 :: Proxy chan1
chan1 = Proxy chan1
forall {k} (t :: k). Proxy t
Proxy :: Proxy chan1
    chan2 :: Proxy chan2
chan2 = Proxy chan2
forall {k} (t :: k). Proxy t
Proxy :: Proxy chan2

-- | Synchronize block size for all streams: pull from each one, then split
-- each to the shortest one.
synchronizeList :: Monad m => [Audio m rate chan]
    -> S.Stream (S.Of [Block]) m ()
synchronizeList :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
[Audio m rate chan] -> Stream (Of [Block]) m ()
synchronizeList = ([Stream (Of Block) m ()]
 -> m (Either () ([Block], [Stream (Of Block) m ()])))
-> [Stream (Of Block) m ()] -> Stream (Of [Block]) m ()
forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr [Stream (Of Block) m ()]
-> m (Either () ([Block], [Stream (Of Block) m ()]))
forall {m :: * -> *} {r}.
Monad m =>
[Stream (Of Block) m r]
-> m (Either () ([Block], [Stream (Of Block) m r]))
unfold ([Stream (Of Block) m ()] -> Stream (Of [Block]) m ())
-> ([Audio m rate chan] -> [Stream (Of Block) m ()])
-> [Audio m rate chan]
-> Stream (Of [Block]) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Audio m rate chan -> Stream (Of Block) m ())
-> [Audio m rate chan] -> [Stream (Of Block) m ()]
forall a b. (a -> b) -> [a] -> [b]
map Audio m rate chan -> Stream (Of Block) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream
    where
    unfold :: [Stream (Of Block) m r]
-> m (Either () ([Block], [Stream (Of Block) m r]))
unfold [Stream (Of Block) m r]
audios = do
        [(Block, Stream (Of Block) m r)]
pairs <- [Maybe (Block, Stream (Of Block) m r)]
-> [(Block, Stream (Of Block) m r)]
forall a. [Maybe a] -> [a]
Maybe.catMaybes ([Maybe (Block, Stream (Of Block) m r)]
 -> [(Block, Stream (Of Block) m r)])
-> m [Maybe (Block, Stream (Of Block) m r)]
-> m [(Block, Stream (Of Block) m r)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Stream (Of Block) m r -> m (Maybe (Block, Stream (Of Block) m r)))
-> [Stream (Of Block) m r]
-> m [Maybe (Block, Stream (Of Block) m r)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Stream (Of Block) m r -> m (Maybe (Block, Stream (Of Block) m r))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Maybe (a, Stream (Of a) m r))
S.uncons [Stream (Of Block) m r]
audios
        Either () ([Block], [Stream (Of Block) m r])
-> m (Either () ([Block], [Stream (Of Block) m r]))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either () ([Block], [Stream (Of Block) m r])
 -> m (Either () ([Block], [Stream (Of Block) m r])))
-> Either () ([Block], [Stream (Of Block) m r])
-> m (Either () ([Block], [Stream (Of Block) m r]))
forall a b. (a -> b) -> a -> b
$ case [Int] -> Maybe Int
forall a. Ord a => [a] -> Maybe a
Seq.minimum ([Int] -> Maybe Int) -> [Int] -> Maybe Int
forall a b. (a -> b) -> a -> b
$ ((Block, Stream (Of Block) m r) -> Int)
-> [(Block, Stream (Of Block) m r)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Block -> Int
blockCount (Block -> Int)
-> ((Block, Stream (Of Block) m r) -> Block)
-> (Block, Stream (Of Block) m r)
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Block, Stream (Of Block) m r) -> Block
forall a b. (a, b) -> a
fst) [(Block, Stream (Of Block) m r)]
pairs of
            Maybe Int
Nothing -> () -> Either () ([Block], [Stream (Of Block) m r])
forall a b. a -> Either a b
Left ()
            Just Int
shortest -> ([Block], [Stream (Of Block) m r])
-> Either () ([Block], [Stream (Of Block) m r])
forall a b. b -> Either a b
Right (([Block], [Stream (Of Block) m r])
 -> Either () ([Block], [Stream (Of Block) m r]))
-> ([Block], [Stream (Of Block) m r])
-> Either () ([Block], [Stream (Of Block) m r])
forall a b. (a -> b) -> a -> b
$ [(Block, Stream (Of Block) m r)]
-> ([Block], [Stream (Of Block) m r])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(Block, Stream (Of Block) m r)]
 -> ([Block], [Stream (Of Block) m r]))
-> [(Block, Stream (Of Block) m r)]
-> ([Block], [Stream (Of Block) m r])
forall a b. (a -> b) -> a -> b
$ ((Block, Stream (Of Block) m r) -> (Block, Stream (Of Block) m r))
-> [(Block, Stream (Of Block) m r)]
-> [(Block, Stream (Of Block) m r)]
forall a b. (a -> b) -> [a] -> [b]
map (Int
-> (Block, Stream (Of Block) m r) -> (Block, Stream (Of Block) m r)
forall {m :: * -> *} {r}.
Monad m =>
Int
-> (Block, Stream (Of Block) m r) -> (Block, Stream (Of Block) m r)
recons Int
shortest) [(Block, Stream (Of Block) m r)]
pairs
    recons :: Int
-> (Block, Stream (Of Block) m r) -> (Block, Stream (Of Block) m r)
recons Int
size (Block
block, Stream (Of Block) m r
tail)
        | Block -> Int
blockCount Block
block Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
size = (Block
block, Stream (Of Block) m r
tail)
        | Bool
otherwise = case Block
block of
            Block Vector Float
v -> (Vector Float -> Block
Block Vector Float
pre, Block -> Stream (Of Block) m r -> Stream (Of Block) m r
forall (m :: * -> *) a r.
Monad m =>
a -> Stream (Of a) m r -> Stream (Of a) m r
S.cons (Vector Float -> Block
Block Vector Float
post) Stream (Of Block) m r
tail)
                where (Vector Float
pre, Vector Float
post) = Int -> Vector Float -> (Vector Float, Vector Float)
forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
V.splitAt Int
size Vector Float
v
            Constant Int
count Float
val ->
                (Int -> Float -> Block
Constant Int
size Float
val, Block -> Stream (Of Block) m r -> Stream (Of Block) m r
forall (m :: * -> *) a r.
Monad m =>
a -> Stream (Of a) m r -> Stream (Of a) m r
S.cons (Int -> Float -> Block
Constant (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
size) Float
val) Stream (Of Block) m r
tail)

-- ** non-interleaved

-- | Merge 'Audio's into a single 'NAudio' stream, synchronized with the given
-- block size.
nonInterleaved :: Monad m => Frames -> Frames -> [Audio m rate 1]
    -> NAudio m rate
nonInterleaved :: forall (m :: * -> *) (rate :: Nat).
Monad m =>
Frames -> Frames -> [Audio m rate 1] -> NAudio m rate
nonInterleaved Frames
now Frames
size [Audio m rate 1]
audios = Int -> Stream (Of [Block]) m () -> NAudio m rate
forall (m :: * -> *) (rate :: Nat).
Int -> Stream (Of [Block]) m () -> NAudio m rate
NAudio ([Audio m rate 1] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Audio m rate 1]
audios) (Stream (Of [Block]) m () -> NAudio m rate)
-> Stream (Of [Block]) m () -> NAudio m rate
forall a b. (a -> b) -> a -> b
$
    ([Stream (Of Block) m ()]
 -> m (Either () ([Block], [Stream (Of Block) m ()])))
-> [Stream (Of Block) m ()] -> Stream (Of [Block]) m ()
forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr [Stream (Of Block) m ()]
-> m (Either () ([Block], [Stream (Of Block) m ()]))
forall {m :: * -> *} {b} {r}.
(Monad m, Monoid b) =>
[Stream (Of b) m r] -> m (Either () ([b], [Stream (Of b) m r]))
unfold ((Audio m rate 1 -> Stream (Of Block) m ())
-> [Audio m rate 1] -> [Stream (Of Block) m ()]
forall a b. (a -> b) -> [a] -> [b]
map (Audio m rate 1 -> Stream (Of Block) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream (Audio m rate 1 -> Stream (Of Block) m ())
-> (Audio m rate 1 -> Audio m rate 1)
-> Audio m rate 1
-> Stream (Of Block) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frames -> Frames -> Audio m rate 1 -> Audio m rate 1
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Frames -> Frames -> Audio m rate chan -> Audio m rate chan
synchronizeToSize Frames
now Frames
size) [Audio m rate 1]
audios)
    where
    unfold :: [Stream (Of b) m r] -> m (Either () ([b], [Stream (Of b) m r]))
unfold [Stream (Of b) m r]
streams = do
        [Maybe (b, Stream (Of b) m r)]
pairs <- (Stream (Of b) m r -> m (Maybe (b, Stream (Of b) m r)))
-> [Stream (Of b) m r] -> m [Maybe (b, Stream (Of b) m r)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Stream (Of b) m r -> m (Maybe (b, Stream (Of b) m r))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Maybe (a, Stream (Of a) m r))
S.uncons [Stream (Of b) m r]
streams
        let heads :: [Maybe b]
heads = (Maybe (b, Stream (Of b) m r) -> Maybe b)
-> [Maybe (b, Stream (Of b) m r)] -> [Maybe b]
forall a b. (a -> b) -> [a] -> [b]
map (((b, Stream (Of b) m r) -> b)
-> Maybe (b, Stream (Of b) m r) -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (b, Stream (Of b) m r) -> b
forall a b. (a, b) -> a
fst) [Maybe (b, Stream (Of b) m r)]
pairs
            tails :: [Stream (Of b) m r]
tails = [Stream (Of b) m r
tail | Just (b
_, Stream (Of b) m r
tail) <- [Maybe (b, Stream (Of b) m r)]
pairs]
        Either () ([b], [Stream (Of b) m r])
-> m (Either () ([b], [Stream (Of b) m r]))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either () ([b], [Stream (Of b) m r])
 -> m (Either () ([b], [Stream (Of b) m r])))
-> Either () ([b], [Stream (Of b) m r])
-> m (Either () ([b], [Stream (Of b) m r]))
forall a b. (a -> b) -> a -> b
$ if [Stream (Of b) m r] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Stream (Of b) m r]
tails then () -> Either () ([b], [Stream (Of b) m r])
forall a b. a -> Either a b
Left ()
            else ([b], [Stream (Of b) m r]) -> Either () ([b], [Stream (Of b) m r])
forall a b. b -> Either a b
Right ((Maybe b -> b) -> [Maybe b] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map (b -> Maybe b -> b
forall a. a -> Maybe a -> a
fromMaybe b
forall a. Monoid a => a
mempty) [Maybe b]
heads, [Stream (Of b) m r]
tails)

-- | Convert a non-interleaved NAudio with an unknown number of channels
-- to an interleaved one with a known number.  This is the inverse of
-- 'nonInterleaved'.
--
-- This is limited to only work when the channels are equal, or the NAudio has
-- 1 channel, in which case it acts like 'expandChannels'.  Similar to
-- 'expandChannels', I could generalize it, but I don't need that now.
interleaved :: forall m rate chan. (Monad m, KnownNat chan)
    => NAudio m rate -> Either Text (Audio m rate chan)
interleaved :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
NAudio m rate -> Either Text (Audio m rate chan)
interleaved NAudio m rate
naudio
    | NAudio m rate -> Int
forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 =
        Audio m rate chan -> Either Text (Audio m rate chan)
forall a b. b -> Either a b
Right (Audio m rate chan -> Either Text (Audio m rate chan))
-> Audio m rate chan -> Either Text (Audio m rate chan)
forall a b. (a -> b) -> a -> b
$ Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> Stream (Of Block) m () -> Audio m rate chan
forall a b. (a -> b) -> a -> b
$ ([Block] -> Block)
-> Stream (Of [Block]) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map (Int -> Block -> Block
expandB Int
chan (Block -> Block) -> ([Block] -> Block) -> [Block] -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Block] -> Block
forall a. [a] -> a
head) (Stream (Of [Block]) m () -> Stream (Of Block) m ())
-> Stream (Of [Block]) m () -> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ NAudio m rate -> Stream (Of [Block]) m ()
forall (m :: * -> *) (rate :: Nat).
NAudio m rate -> Stream (Of [Block]) m ()
_nstream NAudio m rate
naudio
    | NAudio m rate -> Int
forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
chan =
        Audio m rate chan -> Either Text (Audio m rate chan)
forall a b. b -> Either a b
Right (Audio m rate chan -> Either Text (Audio m rate chan))
-> Audio m rate chan -> Either Text (Audio m rate chan)
forall a b. (a -> b) -> a -> b
$ Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> Stream (Of Block) m () -> Audio m rate chan
forall a b. (a -> b) -> a -> b
$ ([Block] -> Block)
-> Stream (Of [Block]) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map [Block] -> Block
interleaveB (Stream (Of [Block]) m () -> Stream (Of Block) m ())
-> Stream (Of [Block]) m () -> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ NAudio m rate -> Stream (Of [Block]) m ()
forall (m :: * -> *) (rate :: Nat).
NAudio m rate -> Stream (Of [Block]) m ()
_nstream NAudio m rate
naudio
    | Bool
otherwise = Text -> Either Text (Audio m rate chan)
forall a b. a -> Either a b
Left (Text -> Either Text (Audio m rate chan))
-> Text -> Either Text (Audio m rate chan)
forall a b. (a -> b) -> a -> b
$ Text
"can't convert " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showt (NAudio m rate -> Int
forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio)
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" channels to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showt Int
chan
    where
    chan :: Int
chan = Proxy chan -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @chan)

synchronizeToSize :: forall m rate chan. (Monad m, KnownNat chan)
    => Frames -> Frames -> Audio m rate chan -> Audio m rate chan
synchronizeToSize :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Frames -> Frames -> Audio m rate chan -> Audio m rate chan
synchronizeToSize Frames
now Frames
size = Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> (Audio m rate chan -> Stream (Of Block) m ())
-> Audio m rate chan
-> Audio m rate chan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Bool, Audio m rate chan)
 -> m (Either () (Block, (Bool, Audio m rate chan))))
-> (Bool, Audio m rate chan) -> Stream (Of Block) m ()
forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr (Bool, Audio m rate chan)
-> m (Either () (Block, (Bool, Audio m rate chan)))
forall {m :: * -> *} {chan :: Nat} {rate :: Nat}.
(Monad m, KnownNat chan) =>
(Bool, Audio m rate chan)
-> m (Either () (Block, (Bool, Audio m rate chan)))
unfold ((Bool, Audio m rate chan) -> Stream (Of Block) m ())
-> (Audio m rate chan -> (Bool, Audio m rate chan))
-> Audio m rate chan
-> Stream (Of Block) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool
True,)
    where
    unfold :: (Bool, Audio m rate chan)
-> m (Either () (Block, (Bool, Audio m rate chan)))
unfold (Bool
initial, Audio m rate chan
audio) = do
        ([Block]
blocks, Audio m rate chan
audio) <- Frames -> Audio m rate chan -> m ([Block], Audio m rate chan)
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Frames -> Audio m rate chan -> m ([Block], Audio m rate chan)
splitAt (if Bool
initial then Frames
align else Frames
size) Audio m rate chan
audio
        Either () (Block, (Bool, Audio m rate chan))
-> m (Either () (Block, (Bool, Audio m rate chan)))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either () (Block, (Bool, Audio m rate chan))
 -> m (Either () (Block, (Bool, Audio m rate chan))))
-> Either () (Block, (Bool, Audio m rate chan))
-> m (Either () (Block, (Bool, Audio m rate chan)))
forall a b. (a -> b) -> a -> b
$ if [Block] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Block]
blocks
            then () -> Either () (Block, (Bool, Audio m rate chan))
forall a b. a -> Either a b
Left ()
            else (Block, (Bool, Audio m rate chan))
-> Either () (Block, (Bool, Audio m rate chan))
forall a b. b -> Either a b
Right ([Block] -> Block
forall a. Monoid a => [a] -> a
mconcat [Block]
blocks, (Bool
False, Audio m rate chan
audio))
    align :: Frames
align = if Frames
now Frames -> Frames -> Frames
forall a. Integral a => a -> a -> a
`mod` Frames
size Frames -> Frames -> Bool
forall a. Eq a => a -> a -> Bool
== Frames
0 then Frames
size else Frames
size Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
- Frames
now Frames -> Frames -> Frames
forall a. Integral a => a -> a -> a
`mod` Frames
size

takeN :: Monad m => Frames -> NAudio m rate -> NAudio m rate
takeN :: forall (m :: * -> *) (rate :: Nat).
Monad m =>
Frames -> NAudio m rate -> NAudio m rate
takeN Frames
frames NAudio m rate
naudio
    | Frames
frames Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
<= Frames
0 = NAudio m rate
naudio
    | Bool
otherwise = Int -> Stream (Of [Block]) m () -> NAudio m rate
forall (m :: * -> *) (rate :: Nat).
Int -> Stream (Of [Block]) m () -> NAudio m rate
NAudio (NAudio m rate -> Int
forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio) (Stream (Of [Block]) m () -> NAudio m rate)
-> Stream (Of [Block]) m () -> NAudio m rate
forall a b. (a -> b) -> a -> b
$
        (Frames, Stream (Of [Block]) m ())
-> (((Frames, Stream (Of [Block]) m ())
     -> Stream (Of [Block]) m ())
    -> (Frames, Stream (Of [Block]) m ()) -> Stream (Of [Block]) m ())
-> Stream (Of [Block]) m ()
forall state a. state -> ((state -> a) -> state -> a) -> a
Control.loop1 (Frames
0, NAudio m rate -> Stream (Of [Block]) m ()
forall (m :: * -> *) (rate :: Nat).
NAudio m rate -> Stream (Of [Block]) m ()
_nstream NAudio m rate
naudio) ((((Frames, Stream (Of [Block]) m ()) -> Stream (Of [Block]) m ())
  -> (Frames, Stream (Of [Block]) m ()) -> Stream (Of [Block]) m ())
 -> Stream (Of [Block]) m ())
-> (((Frames, Stream (Of [Block]) m ())
     -> Stream (Of [Block]) m ())
    -> (Frames, Stream (Of [Block]) m ()) -> Stream (Of [Block]) m ())
-> Stream (Of [Block]) m ()
forall a b. (a -> b) -> a -> b
$ \(Frames, Stream (Of [Block]) m ()) -> Stream (Of [Block]) m ()
loop (Frames
now, Stream (Of [Block]) m ()
audio) ->
            m (Maybe ([Block], Stream (Of [Block]) m ()))
-> Stream
     (Of [Block]) m (Maybe ([Block], Stream (Of [Block]) m ()))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Stream (Of [Block]) m ()
-> m (Maybe ([Block], Stream (Of [Block]) m ()))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Maybe (a, Stream (Of a) m r))
S.uncons Stream (Of [Block]) m ()
audio) Stream (Of [Block]) m (Maybe ([Block], Stream (Of [Block]) m ()))
-> (Maybe ([Block], Stream (Of [Block]) m ())
    -> Stream (Of [Block]) m ())
-> Stream (Of [Block]) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                Maybe ([Block], Stream (Of [Block]) m ())
Nothing -> () -> Stream (Of [Block]) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                Just ([], Stream (Of [Block]) m ()
audio) -> (Frames, Stream (Of [Block]) m ()) -> Stream (Of [Block]) m ()
loop (Frames
now, Stream (Of [Block]) m ()
audio)
                Just (blocks :: [Block]
blocks@(Block
block:[Block]
_), Stream (Of [Block]) m ()
audio)
                    | Frames
end Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
<= Frames
frames -> [Block] -> Stream (Of [Block]) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield [Block]
blocks Stream (Of [Block]) m ()
-> Stream (Of [Block]) m () -> Stream (Of [Block]) m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Frames, Stream (Of [Block]) m ()) -> Stream (Of [Block]) m ()
loop (Frames
end, Stream (Of [Block]) m ()
audio)
                    | Frames
now Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
>= Frames
frames -> () -> Stream (Of [Block]) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                    | Bool
otherwise -> [Block] -> Stream (Of [Block]) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield ([Block] -> Stream (Of [Block]) m ())
-> [Block] -> Stream (Of [Block]) m ()
forall a b. (a -> b) -> a -> b
$ (Block -> Block) -> [Block] -> [Block]
forall a b. (a -> b) -> [a] -> [b]
map ((Block, Block) -> Block
forall a b. (a, b) -> a
fst ((Block, Block) -> Block)
-> (Block -> (Block, Block)) -> Block -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Block -> (Block, Block)
blockSplit Int
left) [Block]
blocks
                    where
                    end :: Frames
end = Frames
now Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
+ Int -> Block -> Frames
blockFrames_ Int
chan Block
block
                    left :: Int
left = Int -> Frames -> Int
framesCount_ Int
chan (Frames -> Frames -> Frames
forall a. Ord a => a -> a -> a
min Frames
frames Frames
end Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
- Frames
now)
        where chan :: Int
chan = NAudio m rate -> Int
forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio

-- | Extend blocks shorter than the given size with zeros, and pad the end with
-- zeros forever.  Composed with 'nonInterleaved', which may leave a short
-- final block, the output should be infinite and have uniform block size.
zeroPadN :: Monad m => Frames -> NAudio m rate -> NAudio m rate
zeroPadN :: forall (m :: * -> *) (rate :: Nat).
Monad m =>
Frames -> NAudio m rate -> NAudio m rate
zeroPadN Frames
size_ NAudio m rate
naudio = NAudio m rate
naudio { _nstream :: Stream (Of [Block]) m ()
_nstream = (Stream (Of [Block]) m ()
 -> m (Either () ([Block], Stream (Of [Block]) m ())))
-> Stream (Of [Block]) m () -> Stream (Of [Block]) m ()
forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr Stream (Of [Block]) m ()
-> m (Either () ([Block], Stream (Of [Block]) m ()))
forall {m :: * -> *} {r} {a}.
Monad m =>
Stream (Of [Block]) m r
-> m (Either a ([Block], Stream (Of [Block]) m r))
unfold (NAudio m rate -> Stream (Of [Block]) m ()
forall (m :: * -> *) (rate :: Nat).
NAudio m rate -> Stream (Of [Block]) m ()
_nstream NAudio m rate
naudio) }
    where
    unfold :: Stream (Of [Block]) m r
-> m (Either a ([Block], Stream (Of [Block]) m r))
unfold Stream (Of [Block]) m r
audio = Stream (Of [Block]) m r
-> m (Maybe ([Block], Stream (Of [Block]) m r))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Maybe (a, Stream (Of a) m r))
S.uncons Stream (Of [Block]) m r
audio m (Maybe ([Block], Stream (Of [Block]) m r))
-> (Maybe ([Block], Stream (Of [Block]) m r)
    -> m (Either a ([Block], Stream (Of [Block]) m r)))
-> m (Either a ([Block], Stream (Of [Block]) m r))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either a ([Block], Stream (Of [Block]) m r)
-> m (Either a ([Block], Stream (Of [Block]) m r))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either a ([Block], Stream (Of [Block]) m r)
 -> m (Either a ([Block], Stream (Of [Block]) m r)))
-> (Maybe ([Block], Stream (Of [Block]) m r)
    -> Either a ([Block], Stream (Of [Block]) m r))
-> Maybe ([Block], Stream (Of [Block]) m r)
-> m (Either a ([Block], Stream (Of [Block]) m r))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
        Maybe ([Block], Stream (Of [Block]) m r)
Nothing ->
            ([Block], Stream (Of [Block]) m r)
-> Either a ([Block], Stream (Of [Block]) m r)
forall a b. b -> Either a b
Right (Int -> Block -> [Block]
forall a. Int -> a -> [a]
replicate (NAudio m rate -> Int
forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio) (Int -> Float -> Block
Constant Int
size Float
0), Stream (Of [Block]) m r
audio)
        Just ([Block]
blocks, Stream (Of [Block]) m r
audio) -> ([Block], Stream (Of [Block]) m r)
-> Either a ([Block], Stream (Of [Block]) m r)
forall a b. b -> Either a b
Right ((Block -> Block) -> [Block] -> [Block]
forall a b. (a -> b) -> [a] -> [b]
map Block -> Block
pad [Block]
blocks, Stream (Of [Block]) m r
audio)
    pad :: Block -> Block
pad (Constant Int
count Float
val) | Float
val Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
0 = Int -> Float -> Block
Constant (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
size Int
count) Float
0
    pad Block
block
        | Block -> Int
blockCount Block
block Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
size = Block
block
        | Bool
otherwise = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ Vector Float
v Vector Float -> Vector Float -> Vector Float
forall a. Semigroup a => a -> a -> a
<> Int -> Float -> Vector Float
forall a. Storable a => Int -> a -> Vector a
V.replicate (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Vector Float -> Int
forall a. Storable a => Vector a -> Int
V.length Vector Float
v) Float
0
        where v :: Vector Float
v = Block -> Vector Float
blockVector Block
block
    size :: Int
size = Proxy 1 -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount (forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @1) Frames
size_

-- * generate

-- | Silence.  Forever.
silence :: (Monad m, KnownNat chan) => Audio m rate chan
silence :: forall (m :: * -> *) (chan :: Nat) (rate :: Nat).
(Monad m, KnownNat chan) =>
Audio m rate chan
silence = Float -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Float -> Audio m rate chan
constant Float
0

-- | An infinite constant stream, which reuses the same buffer.
constant :: forall m rate chan. (Monad m, KnownNat chan)
    => Sample -> Audio m rate chan
constant :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Float -> Audio m rate chan
constant Float
val = Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> Stream (Of Block) m () -> Audio m rate chan
forall a b. (a -> b) -> a -> b
$ Block -> Stream (Of Block) m ()
forall (m :: * -> *) a r. Monad m => a -> Stream (Of a) m r
S.repeat (Block -> Stream (Of Block) m ())
-> Block -> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ Int -> Float -> Block
Constant Int
size Float
val
    where size :: Int
size = Proxy chan -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount (forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @chan) Frames
blockSize

-- | Generate a test tone at the given frequency, forever.  This is not
-- efficient, but it's just for testing.
sine :: forall m rate. (Monad m, KnownNat rate) => Float -> Audio m rate 1
sine :: forall (m :: * -> *) (rate :: Nat).
(Monad m, KnownNat rate) =>
Float -> Audio m rate 1
sine Float
frequency =
    Stream (Of Block) m () -> Audio m rate 1
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate 1)
-> Stream (Of Block) m () -> Audio m rate 1
forall a b. (a -> b) -> a -> b
$ Frames
-> ((Frames -> Stream (Of Block) m ())
    -> Frames -> Stream (Of Block) m ())
-> Stream (Of Block) m ()
forall state a. state -> ((state -> a) -> state -> a) -> a
Control.loop1 Frames
0 (((Frames -> Stream (Of Block) m ())
  -> Frames -> Stream (Of Block) m ())
 -> Stream (Of Block) m ())
-> ((Frames -> Stream (Of Block) m ())
    -> Frames -> Stream (Of Block) m ())
-> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ \Frames -> Stream (Of Block) m ()
loop Frames
frame ->
        Block -> Stream (Of Block) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield (Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ Frames -> Vector Float
gen Frames
frame) Stream (Of Block) m ()
-> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Frames -> Stream (Of Block) m ()
loop (Frames
frame Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
+ Frames
blockSize)
    where
    gen :: Frames -> Vector Float
gen Frames
start =
        Int -> (Int -> Float) -> Vector Float
forall a. Storable a => Int -> (Int -> a) -> Vector a
V.generate (Frames -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Frames
end Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
- Frames
start)) (Frames -> Float
forall {a}. Integral a => a -> Float
val (Frames -> Float) -> (Int -> Frames) -> Int -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
+Frames
start) (Frames -> Frames) -> (Int -> Frames) -> Int -> Frames
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Frames
Frames)
        where end :: Frames
end = Frames
start Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
+ Frames
blockSize
    val :: a -> Float
val a
frame = Float -> Float
forall a. Floating a => a -> a
sin (Float -> Float) -> Float -> Float
forall a b. (a -> b) -> a -> b
$ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
forall a. Floating a => a
pi Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
frequency Float -> Float -> Float
forall a. Num a => a -> a -> a
* (a -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
frame Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
rate)
    rate :: Float
rate = Integer -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Float) -> Integer -> Float
forall a b. (a -> b) -> a -> b
$ Proxy rate -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
TypeLits.natVal (Proxy rate
forall {k} (t :: k). Proxy t
Proxy :: Proxy rate)

-- | Generate a piecewise linear signal from breakpoints.  The signal will
-- continue forever with the last value.
--
-- TODO take blockSize and start args so a subsequent synchronization doesn't
-- have to reallocate.
linear :: forall m rate. (Monad m, KnownNat rate)
    => Bool -> [(Seconds, Double)] -> Audio m rate 1
linear :: forall (m :: * -> *) (rate :: Nat).
(Monad m, KnownNat rate) =>
Bool -> [(Seconds, Seconds)] -> Audio m rate 1
linear Bool
forever [(Seconds, Seconds)]
breakpoints = Stream (Of Block) m () -> Audio m rate 1
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate 1)
-> Stream (Of Block) m () -> Audio m rate 1
forall a b. (a -> b) -> a -> b
$ (Frames, Seconds, Seconds, [(Seconds, Seconds)])
-> Stream (Of Block) m ()
forall {m :: * -> *}.
Monad m =>
(Frames, Seconds, Seconds, [(Seconds, Seconds)])
-> Stream (Of Block) m ()
loop (Frames
0, Seconds
0, Seconds
0, [(Seconds, Seconds)] -> [(Seconds, Seconds)]
forall {a} {b}. (Ord a, Num a, Num b, Eq b) => [(a, b)] -> [(a, b)]
from0 [(Seconds, Seconds)]
breakpoints)
    where
    loop :: (Frames, Seconds, Seconds, [(Seconds, Seconds)])
-> Stream (Of Block) m ()
loop (Frames
start, Seconds
prevX, Seconds
prevY, [(Seconds, Seconds)]
breakpoints) = case [(Seconds, Seconds)]
breakpoints of
        (Seconds
x, Seconds
y) : [(Seconds, Seconds)]
xys
            | Seconds -> Frames
toFrame Seconds
x Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
<= Frames
start -> (Frames, Seconds, Seconds, [(Seconds, Seconds)])
-> Stream (Of Block) m ()
loop (Frames
start, Seconds
x, Seconds
y, [(Seconds, Seconds)]
xys)
            | Bool
otherwise -> do
                Block -> Stream (Of Block) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield (Block -> Stream (Of Block) m ())
-> Block -> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ Seconds -> Seconds -> Seconds -> Seconds -> Frames -> Int -> Block
segment Seconds
prevX Seconds
prevY Seconds
x Seconds
y Frames
start (Frames -> Int
toCount Frames
generate)
                (Frames, Seconds, Seconds, [(Seconds, Seconds)])
-> Stream (Of Block) m ()
loop (Frames
start Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
+ Frames
generate, Seconds
prevX, Seconds
prevY, [(Seconds, Seconds)]
breakpoints)
            where generate :: Frames
generate = Frames -> Frames -> Frames
forall a. Ord a => a -> a -> a
min Frames
blockSize (Seconds -> Frames
toFrame Seconds
x Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
- Frames
start)
        []  | Bool
forever -> Audio m Any 1 -> Stream (Of Block) m ()
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream (Audio m Any 1 -> Stream (Of Block) m ())
-> Audio m Any 1 -> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Float -> Audio m rate chan
constant @_ @_ @1 (Seconds -> Float
Num.d2f Seconds
prevY)
            | Bool
otherwise -> Block -> Stream (Of Block) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield (Block -> Stream (Of Block) m ())
-> Block -> Stream (Of Block) m ()
forall a b. (a -> b) -> a -> b
$ Int -> Float -> Block
Constant Int
1 (Seconds -> Float
Num.d2f Seconds
prevY)
    -- Go through some hassle to create constant segments efficiently, since
    -- they should be pretty common.
    segment :: Seconds -> Seconds -> Seconds -> Seconds -> Frames -> Int -> Block
segment Seconds
x1 Seconds
y1 Seconds
x2 Seconds
y2 Frames
start Int
count
        | Seconds
y1 Seconds -> Seconds -> Bool
forall a. Eq a => a -> a -> Bool
== Seconds
y2 = Int -> Float -> Block
Constant Int
count (Seconds -> Float
Num.d2f Seconds
y1)
        | Bool
otherwise = Vector Float -> Block
Block (Vector Float -> Block) -> Vector Float -> Block
forall a b. (a -> b) -> a -> b
$ Int -> (Int -> Float) -> Vector Float
forall a. Storable a => Int -> (Int -> a) -> Vector a
V.generate Int
count
            (Seconds -> Seconds -> Seconds -> Seconds -> Seconds -> Float
interpolate Seconds
x1 Seconds
y1 Seconds
x2 Seconds
y2 (Seconds -> Float) -> (Int -> Seconds) -> Int -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frames -> Seconds
toSec (Frames -> Seconds) -> (Int -> Frames) -> Int -> Seconds
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
+Frames
start) (Frames -> Frames) -> (Int -> Frames) -> Int -> Frames
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Frames
Frames)
    interpolate :: Seconds -> Seconds -> Seconds -> Seconds -> Seconds -> Float
interpolate Seconds
x1 Seconds
y1 Seconds
x2 Seconds
y2 Seconds
x = Seconds -> Float
Num.d2f (Seconds -> Float) -> Seconds -> Float
forall a b. (a -> b) -> a -> b
$
        (Seconds
y2 Seconds -> Seconds -> Seconds
forall a. Num a => a -> a -> a
- Seconds
y1) Seconds -> Seconds -> Seconds
forall a. Fractional a => a -> a -> a
/ (Seconds
x2 Seconds -> Seconds -> Seconds
forall a. Num a => a -> a -> a
- Seconds
x1) Seconds -> Seconds -> Seconds
forall a. Num a => a -> a -> a
* (Seconds
x Seconds -> Seconds -> Seconds
forall a. Num a => a -> a -> a
- Seconds
x1) Seconds -> Seconds -> Seconds
forall a. Num a => a -> a -> a
+ Seconds
y1
    toFrame :: Seconds -> Frames
toFrame = Int -> Seconds -> Frames
secondsToFrames Int
rate
    toSec :: Frames -> Seconds
toSec = Int -> Frames -> Seconds
framesToSeconds Int
rate
    toCount :: Frames -> Int
toCount = Proxy 1 -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount (forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @1)
    rate :: Int
rate = Proxy rate -> Int
forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (Proxy rate
forall {k} (t :: k). Proxy t
Proxy :: Proxy rate)
    -- The signal is implicitly constant 0 before the first sample.
    from0 :: [(a, b)] -> [(a, b)]
from0 bps :: [(a, b)]
bps@((a
x, b
y) : [(a, b)]
_) | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0 Bool -> Bool -> Bool
&& b
y b -> b -> Bool
forall a. Eq a => a -> a -> Bool
/= b
0 = (a
x, b
0) (a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
: [(a, b)]
bps
    from0 [(a, b)]
bps = [(a, b)]
bps

-- * effects

-- | Prepend an effect to the stream, useful to log when a stream is started.
effect :: MonadIO m => IO () -> Audio m rate chan -> Audio m rate chan
effect :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
MonadIO m =>
IO () -> Audio m rate chan -> Audio m rate chan
effect IO ()
m (Audio Stream (Of Block) m ()
s) = Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (IO () -> Stream (Of Block) m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ()
m Stream (Of Block) m ()
-> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Stream (Of Block) m ()
s)

-- * error

newtype Exception = Exception Text
    deriving (Int -> Exception -> ShowS
[Exception] -> ShowS
Exception -> [Char]
(Int -> Exception -> ShowS)
-> (Exception -> [Char])
-> ([Exception] -> ShowS)
-> Show Exception
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [Exception] -> ShowS
$cshowList :: [Exception] -> ShowS
show :: Exception -> [Char]
$cshow :: Exception -> [Char]
showsPrec :: Int -> Exception -> ShowS
$cshowsPrec :: Int -> Exception -> ShowS
Show)

exceptionText :: Exception -> Text
exceptionText :: Exception -> Text
exceptionText (Exception Text
msg) = Text
msg

instance Exception.Exception Exception where
    displayException :: Exception -> [Char]
displayException (Exception Text
msg) = Text -> [Char]
untxt Text
msg

throw :: Stack.HasCallStack => Text -> AudioIO rate chan
throw :: forall (rate :: Nat) (chan :: Nat).
HasCallStack =>
Text -> AudioIO rate chan
throw = Stream (Of Block) (ResourceT IO) ()
-> Audio (ResourceT IO) rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) (ResourceT IO) ()
 -> Audio (ResourceT IO) rate chan)
-> (Text -> Stream (Of Block) (ResourceT IO) ())
-> Text
-> Audio (ResourceT IO) rate chan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Stream (Of Block) (ResourceT IO) ()
forall (m :: * -> *) a. (HasCallStack, MonadIO m) => Text -> m a
throwIO

throwIO :: (Stack.HasCallStack, MonadIO m) => Text -> m a
throwIO :: forall (m :: * -> *) a. (HasCallStack, MonadIO m) => Text -> m a
throwIO = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> (Text -> IO a) -> Text -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exception -> IO a
forall e a. Exception e => e -> IO a
Exception.throwIO (Exception -> IO a) -> (Text -> Exception) -> Text -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Exception
Exception
    (Text -> Exception) -> (Text -> Text) -> Text -> Exception
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Text
HasCallStack => Text
CallStack.getStack Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
": ") <>)

assert :: (Stack.HasCallStack, MonadIO m) => Bool -> Text -> m ()
assert :: forall (m :: * -> *).
(HasCallStack, MonadIO m) =>
Bool -> Text -> m ()
assert Bool
True Text
_ = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
assert Bool
False Text
msg = Text -> m ()
forall (m :: * -> *) a. (HasCallStack, MonadIO m) => Text -> m a
throwIO (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"assertion: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
msg

-- | Insert an assertion into the audio stream.
assertIn :: (Stack.HasCallStack, MonadIO m) => Bool -> Text
    -> Audio m rate chan -> Audio m rate chan
assertIn :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(HasCallStack, MonadIO m) =>
Bool -> Text -> Audio m rate chan -> Audio m rate chan
assertIn Bool
check Text
msg = (Stream (Of Block) m () -> Stream (Of Block) m ())
-> Audio m rate chan -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Stream (Of Block) m () -> Stream (Of Block) m ())
-> Audio m rate chan -> Audio m rate chan
apply (Bool -> Text -> Stream (Of Block) m ()
forall (m :: * -> *).
(HasCallStack, MonadIO m) =>
Bool -> Text -> m ()
assert Bool
check Text
msg *>)

-- * constants

blockSize :: Frames
blockSize :: Frames
blockSize = Frames
5000

silentBlock :: V.Vector Sample
silentBlock :: Vector Float
silentBlock = Int -> Float -> Vector Float
forall a. Storable a => Int -> a -> Vector a
V.replicate (Proxy 1 -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount (forall {t :: Nat}. Proxy t
forall {k} (t :: k). Proxy t
Proxy @1) Frames
blockSize) Float
0

-- * conversions

linearToDb, dbToLinear :: Float -> Float
linearToDb :: Float -> Float
linearToDb Float
x = Float -> Float -> Float
forall a. Floating a => a -> a -> a
logBase Float
10 Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
20
dbToLinear :: Float -> Float
dbToLinear Float
x = Float
10Float -> Float -> Float
forall a. Floating a => a -> a -> a
**(Float
x Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
20)
    -- Here's another way.  Is it faster?  Does it matter?
    -- dbToLinear db = 2**(db * 0.16609640474)

-- * audio util

-- | Take >= the given number of frames.  It may take more if the size doesn't
-- line up on a block boundary.
--
-- TODO rename to splitAtGE
takeFramesGE :: forall m rate chan. (Monad m, KnownNat chan)
    => Frames -> Audio m rate chan -> m ([Block], Audio m rate chan)
takeFramesGE :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Frames -> Audio m rate chan -> m ([Block], Audio m rate chan)
takeFramesGE Frames
frames (Audio Stream (Of Block) m ()
audio) = do
    [Block]
blocks S.:> Stream (Of Block) m ()
rest <- Stream (Of Block) m (Stream (Of Block) m ())
-> m (Of [Block] (Stream (Of Block) m ()))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Of [a] r)
S.toList (Stream (Of Block) m (Stream (Of Block) m ())
 -> m (Of [Block] (Stream (Of Block) m ())))
-> Stream (Of Block) m (Stream (Of Block) m ())
-> m (Of [Block] (Stream (Of Block) m ()))
forall a b. (a -> b) -> a -> b
$
        (Frames -> Block -> Frames)
-> Frames
-> (Frames -> Bool)
-> Stream (Of Block) m ()
-> Stream (Of Block) m (Stream (Of Block) m ())
forall (m :: * -> *) accum a r.
Monad m =>
(accum -> a -> accum)
-> accum
-> (accum -> Bool)
-> Stream (Of a) m r
-> Stream (Of a) m (Stream (Of a) m r)
breakAfter (\Frames
n -> (Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
+Frames
n) (Frames -> Frames) -> (Block -> Frames) -> Block -> Frames
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy chan -> Block -> Frames
forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan
chan) Frames
0 (Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
>=Frames
frames) Stream (Of Block) m ()
audio
    ([Block], Audio m rate chan) -> m ([Block], Audio m rate chan)
forall (m :: * -> *) a. Monad m => a -> m a
return ([Block]
blocks, Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio Stream (Of Block) m ()
rest)
    where
    chan :: Proxy chan
chan = Proxy chan
forall {k} (t :: k). Proxy t
Proxy :: Proxy chan

-- | Take exactly the given number of frames.
splitAt :: forall m rate chan. (Monad m, KnownNat chan)
    => Frames -> Audio m rate chan -> m ([Block], Audio m rate chan)
splitAt :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Frames -> Audio m rate chan -> m ([Block], Audio m rate chan)
splitAt Frames
frames (Audio Stream (Of Block) m ()
audio)
    | Frames
frames Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
<= Frames
0 = ([Block], Audio m rate chan) -> m ([Block], Audio m rate chan)
forall (m :: * -> *) a. Monad m => a -> m a
return ([], Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio Stream (Of Block) m ()
audio)
    | Bool
otherwise = Stream (Of Block) m ()
-> m (Either () (Block, Stream (Of Block) m ()))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r))
S.next Stream (Of Block) m ()
audio m (Either () (Block, Stream (Of Block) m ()))
-> (Either () (Block, Stream (Of Block) m ())
    -> m ([Block], Audio m rate chan))
-> m ([Block], Audio m rate chan)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left () -> ([Block], Audio m rate chan) -> m ([Block], Audio m rate chan)
forall (m :: * -> *) a. Monad m => a -> m a
return ([], Audio m rate chan
forall a. Monoid a => a
mempty)
        Right (Block
block, Stream (Of Block) m ()
audio)
            | Frames
produced Frames -> Frames -> Bool
forall a. Ord a => a -> a -> Bool
< Frames
frames ->
                ([Block] -> [Block])
-> ([Block], Audio m rate chan) -> ([Block], Audio m rate chan)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Block
block:) (([Block], Audio m rate chan) -> ([Block], Audio m rate chan))
-> m ([Block], Audio m rate chan) -> m ([Block], Audio m rate chan)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Frames -> Audio m rate chan -> m ([Block], Audio m rate chan)
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Frames -> Audio m rate chan -> m ([Block], Audio m rate chan)
splitAt (Frames
frames Frames -> Frames -> Frames
forall a. Num a => a -> a -> a
- Frames
produced) (Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio Stream (Of Block) m ()
audio)
            | Frames
produced Frames -> Frames -> Bool
forall a. Eq a => a -> a -> Bool
== Frames
frames -> ([Block], Audio m rate chan) -> m ([Block], Audio m rate chan)
forall (m :: * -> *) a. Monad m => a -> m a
return ([Block
block], Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio Stream (Of Block) m ()
audio)
            | Bool
otherwise -> ([Block], Audio m rate chan) -> m ([Block], Audio m rate chan)
forall (m :: * -> *) a. Monad m => a -> m a
return ([Block
pre], Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> Stream (Of Block) m () -> Audio m rate chan
forall a b. (a -> b) -> a -> b
$ Block -> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a r.
Monad m =>
a -> Stream (Of a) m r -> Stream (Of a) m r
S.cons Block
post Stream (Of Block) m ()
audio)
            where
            produced :: Frames
produced = Proxy chan -> Block -> Frames
forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan
chan Block
block
            (Block
pre, Block
post) = Int -> Block -> (Block, Block)
blockSplit (Proxy chan -> Frames -> Int
forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan
chan Frames
frames) Block
block
    where
    chan :: Proxy chan
chan = Proxy chan
forall {k} (t :: k). Proxy t
Proxy :: Proxy chan

next :: Monad m => Audio m rate chan -> m (Maybe (Block, Audio m rate chan))
next :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan -> m (Maybe (Block, Audio m rate chan))
next (Audio Stream (Of Block) m ()
audio) = Stream (Of Block) m ()
-> m (Either () (Block, Stream (Of Block) m ()))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r))
S.next Stream (Of Block) m ()
audio m (Either () (Block, Stream (Of Block) m ()))
-> (Either () (Block, Stream (Of Block) m ())
    -> m (Maybe (Block, Audio m rate chan)))
-> m (Maybe (Block, Audio m rate chan))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Left () -> Maybe (Block, Audio m rate chan)
-> m (Maybe (Block, Audio m rate chan))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Block, Audio m rate chan)
forall a. Maybe a
Nothing
    Right (Block
block, Stream (Of Block) m ()
audio) -> Maybe (Block, Audio m rate chan)
-> m (Maybe (Block, Audio m rate chan))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Block, Audio m rate chan)
 -> m (Maybe (Block, Audio m rate chan)))
-> Maybe (Block, Audio m rate chan)
-> m (Maybe (Block, Audio m rate chan))
forall a b. (a -> b) -> a -> b
$ (Block, Audio m rate chan) -> Maybe (Block, Audio m rate chan)
forall a. a -> Maybe a
Just (Block
block, Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio Stream (Of Block) m ()
audio)

-- | Nothing if the Audio stream is completed.  Otherwise, it returns
-- the same stream but with the first chunk evaluated, to avoid duplicating
-- effects.
isEmpty :: Monad m => Audio m rate chan -> m (Maybe (Audio m rate chan))
isEmpty :: forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
Audio m rate chan -> m (Maybe (Audio m rate chan))
isEmpty (Audio Stream (Of Block) m ()
audio) = Stream (Of Block) m ()
-> m (Either () (Block, Stream (Of Block) m ()))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r))
S.next Stream (Of Block) m ()
audio m (Either () (Block, Stream (Of Block) m ()))
-> (Either () (Block, Stream (Of Block) m ())
    -> m (Maybe (Audio m rate chan)))
-> m (Maybe (Audio m rate chan))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Left () -> Maybe (Audio m rate chan) -> m (Maybe (Audio m rate chan))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Audio m rate chan)
forall a. Maybe a
Nothing
    Right (Block
block, Stream (Of Block) m ()
audio) -> Maybe (Audio m rate chan) -> m (Maybe (Audio m rate chan))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Audio m rate chan) -> m (Maybe (Audio m rate chan)))
-> Maybe (Audio m rate chan) -> m (Maybe (Audio m rate chan))
forall a b. (a -> b) -> a -> b
$ Audio m rate chan -> Maybe (Audio m rate chan)
forall a. a -> Maybe a
Just (Audio m rate chan -> Maybe (Audio m rate chan))
-> Audio m rate chan -> Maybe (Audio m rate chan)
forall a b. (a -> b) -> a -> b
$ Stream (Of Block) m () -> Audio m rate chan
forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (Stream (Of Block) m () -> Audio m rate chan)
-> Stream (Of Block) m () -> Audio m rate chan
forall a b. (a -> b) -> a -> b
$ Block -> Stream (Of Block) m () -> Stream (Of Block) m ()
forall (m :: * -> *) a r.
Monad m =>
a -> Stream (Of a) m r -> Stream (Of a) m r
S.cons Block
block Stream (Of Block) m ()
audio

-- * util

natVal :: KnownNat n => Proxy n -> Int
natVal :: forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Int) -> (Proxy n -> Integer) -> Proxy n -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
TypeLits.natVal

someNat :: Int -> TypeLits.SomeNat
someNat :: Int -> SomeNat
someNat Int
int = case Integer -> Maybe SomeNat
TypeLits.someNatVal (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
int) of
    Maybe SomeNat
Nothing -> [Char] -> SomeNat
forall a. HasCallStack => [Char] -> a
error ([Char] -> SomeNat) -> [Char] -> SomeNat
forall a b. (a -> b) -> a -> b
$ [Char]
"not a natural: " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
int
    Just SomeNat
n -> SomeNat
n

-- | This is like 'S.breakWhen', except it breaks after the place where the
-- predicate becomes true, not before it.
breakAfter :: Monad m => (accum -> a -> accum) -> accum -> (accum -> Bool)
    -> S.Stream (S.Of a) m r -> S.Stream (S.Of a) m (S.Stream (S.Of a) m r)
breakAfter :: forall (m :: * -> *) accum a r.
Monad m =>
(accum -> a -> accum)
-> accum
-> (accum -> Bool)
-> Stream (Of a) m r
-> Stream (Of a) m (Stream (Of a) m r)
breakAfter accum -> a -> accum
combine accum
accum accum -> Bool
check = accum -> Stream (Of a) m r -> Stream (Of a) m (Stream (Of a) m r)
forall {m :: * -> *} {a}.
Monad m =>
accum -> Stream (Of a) m a -> Stream (Of a) m (Stream (Of a) m a)
loop accum
accum
    where
    loop :: accum -> Stream (Of a) m a -> Stream (Of a) m (Stream (Of a) m a)
loop accum
accum Stream (Of a) m a
as = m (Either a (a, Stream (Of a) m a))
-> Stream (Of a) m (Either a (a, Stream (Of a) m a))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Stream (Of a) m a -> m (Either a (a, Stream (Of a) m a))
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r))
S.next Stream (Of a) m a
as) Stream (Of a) m (Either a (a, Stream (Of a) m a))
-> (Either a (a, Stream (Of a) m a)
    -> Stream (Of a) m (Stream (Of a) m a))
-> Stream (Of a) m (Stream (Of a) m a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left a
r -> Stream (Of a) m a -> Stream (Of a) m (Stream (Of a) m a)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Stream (Of a) m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r)
        Right (a
a, Stream (Of a) m a
as)
            | accum -> Bool
check accum
next -> a -> Stream (Of a) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield a
a Stream (Of a) m ()
-> Stream (Of a) m (Stream (Of a) m a)
-> Stream (Of a) m (Stream (Of a) m a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Stream (Of a) m a -> Stream (Of a) m (Stream (Of a) m a)
forall (m :: * -> *) a. Monad m => a -> m a
return Stream (Of a) m a
as
            | Bool
otherwise -> a -> Stream (Of a) m ()
forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield a
a Stream (Of a) m ()
-> Stream (Of a) m (Stream (Of a) m a)
-> Stream (Of a) m (Stream (Of a) m a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> accum -> Stream (Of a) m a -> Stream (Of a) m (Stream (Of a) m a)
loop accum
next Stream (Of a) m a
as
            where next :: accum
next = accum -> a -> accum
combine accum
accum a
a