-- 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.Lists as Lists
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
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, 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
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]
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) = forall a. Pretty a => a -> Doc
Pretty.format Vector Float
v
    format (Constant Int
count Float
val) = Text -> Doc
Pretty.text forall a b. (a -> b) -> a -> b
$ Text
"const:" forall a. Semigroup a => a -> a -> a
<> 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 forall a b. (a -> b) -> a -> b
$ forall a b. (RealFrac a, Integral b) => a -> b
round forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
rate 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 forall a b. (a -> b) -> a -> b
$ forall a b. (RealFrac a, Integral b) => a -> b
ceiling forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
rate forall a. Num a => a -> a -> a
* Seconds
seconds

framesToSeconds :: Rate -> Frames -> Seconds
framesToSeconds :: Int -> Frames -> Seconds
framesToSeconds Int
rate (Frames Int
frames) = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
frames forall a. Fractional a => a -> a -> a
/ 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 forall a. Num a => a -> a -> a
* 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 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_ (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 forall a b. (a -> b) -> a -> b
$ Int
count 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 = forall (chan :: Nat). KnownNat chan => Proxy chan -> Int -> Frames
countFrames Proxy chan
chan 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 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 = forall (chan :: Nat). KnownNat chan => Proxy chan -> Int -> Frames
countFrames Proxy chan
chan forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Storable a => Vector a -> Int
V.length

blockCount :: Block -> Count
blockCount :: Block -> Int
blockCount (Block Vector Float
v) = 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 = (forall a. Eq a => a -> a -> Bool
==Int
0) 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 forall a. Ord a => a -> a -> Bool
<= Int
0 = []
blockSamples (Constant Int
count Float
0)
    | Int
count forall a. Ord a => a -> a -> Bool
> forall a. Storable a => Vector a -> Int
V.length Vector Float
silentBlock =
        Vector Float
silentBlock forall a. a -> [a] -> [a]
: Block -> [Vector Float]
blockSamples (Int -> Float -> Block
Constant (Int
count forall a. Num a => a -> a -> a
- forall a. Storable a => Vector a -> Int
V.length Vector Float
silentBlock) Float
0)
    | Bool
otherwise = [forall a. Storable a => Int -> Vector a -> Vector a
V.take Int
count Vector Float
silentBlock]
blockSamples (Constant Int
count Float
val) = [forall a. Storable a => Int -> a -> Vector a
V.replicate Int
count Float
val]

blockVector :: Block -> V.Vector Sample
blockVector :: Block -> Vector Float
blockVector = forall a. Monoid a => [a] -> a
mconcat 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) = 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 (forall a. Ord a => a -> a -> a
min Int
count Int
n) Float
val, Int -> Float -> Block
Constant (forall a. Ord a => a -> a -> a
max Int
0 (Int
count 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 forall a. Eq a => a -> a -> Bool
== Float
v2 = Int -> Float -> Block
Constant (Int
c1forall a. Num a => a -> a -> a
+Int
c2) Float
v1
    Block
b1 <> Block
b2 = Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ Block -> [Vector Float]
blockSamples Block
b1 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)
        | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Vector Float]
vs Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((forall a. Eq a => a -> a -> Bool
==Float
v1) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) [(Int, Float)]
cs =
            Int -> Float -> Block
Constant (Int
c1 forall a. Num a => a -> a -> a
+ forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
Num.sum (forall a b. (a -> b) -> [a] -> [b]
map 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 forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ 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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
[Block] -> Audio m rate chan
fromBlocks forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) (f :: * -> *) a.
(Monad m, Foldable f) =>
f a -> Stream (Of a) m ()
S.each forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Block -> Block
check
    where
    check :: Block -> Block
check Block
block
        | Block -> Int
blockCount Block
block forall a. Integral a => a -> a -> a
`mod` Int
chan forall a. Eq a => a -> a -> Bool
== Int
0 = Block
block
        | Bool
otherwise = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"block count " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show (Block -> Int
blockCount Block
block)
            forall a. Semigroup a => a -> a -> a
<> [Char]
" not a multiple of channels " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show Int
chan
    chan :: Int
chan = forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
[Vector Float] -> Audio m rate chan
fromSamples forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map 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 = forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m [a]
S.toList_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Block -> [Vector Float]
blockSamples) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m [a]
S.toList_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map Block -> Vector Float
blockVector)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) = 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) = 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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
m () -> Frames -> Audio m rate chan -> Audio m rate chan
takeClose (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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat rate, KnownNat chan) =>
m () -> Seconds -> Audio m rate chan -> Audio m rate chan
takeCloseS (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 forall a. Ord a => a -> a -> Bool
<= Seconds
0 = forall a. Monoid a => a
mempty
    | Bool
otherwise = 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 (forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (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 forall a. Ord a => a -> a -> Bool
<= Frames
0 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m ()
close
    | Bool
otherwise = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ forall state a. state -> ((state -> a) -> state -> a) -> a
Control.loop1 (Frames
0, Stream (Of Block) m ()
audio) forall a b. (a -> b) -> a -> b
$
        \(Frames, Stream (Of Block) m ()) -> Stream (Of Block) m ()
loop (Frames
now, Stream (Of Block) m ()
audio) -> forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (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) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
            Maybe (Block, Stream (Of Block) m ())
Nothing -> 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 forall a. Ord a => a -> a -> Bool
<= Frames
frames -> forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield Block
block 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 forall a. Ord a => a -> a -> Bool
>= Frames
frames -> forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m ()
close
                | Bool
otherwise -> do
                    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m ()
close
                    forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ Int -> Block -> (Block, Block)
blockSplit Int
left Block
block
                where
                end :: Frames
end = Frames
now forall a. Num a => a -> a -> a
+ forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan
chan Block
block
                left :: Int
left = forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan
chan (forall a. Ord a => a -> a -> a
min Frames
frames Frames
end forall a. Num a => a -> a -> a
- Frames
now)
    where chan :: Proxy chan
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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Stream (Of Block) m () -> Stream (Of Block) m ())
-> Audio m rate chan -> Audio m rate chan
apply (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 (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 forall a. Eq a => a -> a -> Bool
== Float
1 = Audio m rate chan
audio
    | Bool
otherwise = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Monad m =>
(Float -> Float) -> Audio m rate chan -> Audio m rate chan
mapSamples (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 =
    forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {b}.
Either () ((Maybe Block, Maybe Block), b) -> Either () (Block, b)
merge forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r))
S.next) forall a b. (a -> b) -> a -> b
$ 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 () -> forall a b. a -> Either a b
Left ()
        Right ((Maybe Block
Nothing, Maybe Block
_), b
_) -> forall a b. a -> Either a b
Left ()
        Right ((Maybe Block
_, Maybe Block
Nothing), 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) -> 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 (forall a. Ord a => a -> a -> a
min Int
c1 Int
c2) (Float
v1forall 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 forall a. Eq a => a -> a -> Bool
== Float
0 = Int -> Float -> Block
Constant (forall a. Ord a => a -> a -> a
min Int
c1 (forall a. Storable a => Vector a -> Int
V.length Vector Float
b2)) Float
0
    | Float
v1 forall a. Eq a => a -> a -> Bool
== Float
1 = Vector Float -> Block
Block Vector Float
b2
    | Bool
otherwise = Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (forall a. Num a => a -> a -> a
*Float
v1) forall a b. (a -> b) -> a -> b
$ 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 forall a b. (a -> b) -> a -> b
$ forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith 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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {b}.
Either () ((Maybe Block, Maybe Block), b) -> Either () (Block, b)
merge forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r))
S.next) forall a b. (a -> b) -> a -> b
$ 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 () -> forall a b. a -> Either a b
Left ()
        Right ((Maybe Block
Nothing, Maybe Block
_), b
_) -> forall a b. a -> Either a b
Left ()
        Right ((Maybe Block
_, Maybe Block
Nothing), b
_) -> forall a b. a -> Either a b
Left ()
        Right ((Just Block
_, Just (Constant Int
c Float
0)), b
audio) ->
            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) ->
            forall a b. b -> Either a b
Right (Block
stereo, b
audio)
        Right ((Just Block
pos_, Just Block
stereo), b
audio) -> forall a b. b -> Either a b
Right
            ( Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
interleaveV
                [ forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith forall a. Num a => a -> a -> a
(*) (forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map ((Float
2-) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
+Float
1)) Vector Float
pos) Vector Float
left
                , forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith forall a. Num a => a -> a -> a
(*) (forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (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] = forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
2 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
    | forall a. ApproxEq a => Seconds -> a -> a -> Bool
ApproxEq.eq Seconds
0.01 Float
pos Float
0 = forall a. a -> a
id
    | Bool
otherwise = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map Block -> Block
pan forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 forall a. Eq a => a -> a -> Bool
== Float
0 = Int -> Float -> Block
Constant Int
count Float
0
    pan Block
stereo = Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
interleaveV
        [ forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (forall a. Num a => a -> a -> a
* (Float
2 forall a. Num a => a -> a -> a
- (Float
posforall a. Num a => a -> a -> a
+Float
1))) Vector Float
left
        , forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (forall a. Num a => a -> a -> a
* (Float
posforall a. Num a => a -> a -> a
+Float
1)) Vector Float
right
        ]
        where [Vector Float
left, Vector Float
right] = forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
2 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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map [Block] -> Block
merge forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 forall a. Storable a => Vector a
V.empty
    merge blocks :: [Block]
blocks@(Block
block:[Block]
_)
        | 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 forall a b. (a -> b) -> a -> b
$
            (if Float
constant forall a. Eq a => a -> a -> Bool
== Float
0 then forall a. a -> a
id else forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map (forall a. Num a => a -> a -> a
+Float
constant)) forall a b. (a -> b) -> a -> b
$ Int -> [Vector Float] -> Vector Float
mixV Int
0 [Vector Float]
vectors
        where
        constant :: Float
constant = 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 [] = forall a. Storable a => Int -> a -> Vector a
V.replicate Int
len Float
0
mixV Int
len [Vector Float
v]
    | forall a. Storable a => Vector a -> Int
V.length Vector Float
v forall a. Ord a => a -> a -> Bool
>= Int
len = Vector Float
v
    | Bool
otherwise = Vector Float
v forall a. Semigroup a => a -> a -> a
<> forall a. Storable a => Int -> a -> Vector a
V.replicate (Int
len forall a. Num a => a -> a -> a
- 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 =
    forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Block, Maybe Block) -> (Block, Block)
to0) forall a b. (a -> b) -> a -> b
$ 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) =
        ( forall a. a -> Maybe a -> a
fromMaybe (Int -> Float -> Block
Constant Int
count1 Float
0) Maybe Block
a1
        , forall a. a -> Maybe a -> a
fromMaybe (Int -> Float -> Block
Constant Int
count2 Float
0) Maybe Block
a2
        )
        where
        count1 :: Int
count1 = forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan1
chan1 forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe Frames
0 (forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan2
chan2) Maybe Block
a2
        count2 :: Int
count2 = forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan2
chan2 forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe Frames
0 (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 forall a. Eq a => a -> a -> Bool
== Float
v2 -> Int -> Float -> Block
Constant (Int
c1forall a. Num a => a -> a -> a
+Int
c2) Float
v1
        (Block
b1, Block
b2) -> Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
interleaveV forall a b. (a -> b) -> a -> b
$
            forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV (forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal Proxy chan1
chan1) (Block -> Vector Float
blockVector Block
b1)
            forall a. [a] -> [a] -> [a]
++ forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV (forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal Proxy chan2
chan2) (Block -> Vector Float
blockVector Block
b2)
    chan1 :: Proxy chan1
chan1 = forall {k} (t :: k). Proxy t
Proxy @chan1
    chan2 :: Proxy chan2
chan2 = 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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map Block -> Block
extract forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 forall a. Integral a => a -> a -> a
`div` Int
chan) Float
val
    extract (Block Vector Float
v) = Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
chan Vector Float
v forall a. [a] -> Int -> a
!! Int
idx
    chan :: Int
chan = forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (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 = forall (m :: * -> *) (rate :: Nat).
Int -> Stream (Of [Block]) m () -> NAudio m rate
NAudio Int
chan forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream
    where chan :: Int
chan = forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (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) = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ 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 = forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (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 forall a. Num a => a -> a -> a
* Int
chan) Float
val
expandB Int
chan (Block Vector Float
v) = Vector Float -> Block
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 =
    forall a. Storable a => Int -> (Int -> a) -> Vector a
V.generate (forall a. Storable a => Vector a -> Int
V.length Vector Float
block forall a. Num a => a -> a -> a
* Int
chan) forall a b. (a -> b) -> a -> b
$ \Int
i -> Vector Float
block forall a. Storable a => Vector a -> Int -> a
V.! (Int
i 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) = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ 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 forall a. Integral a => a -> a -> a
`div` Int
chan) Float
val
    mix (Block Vector Float
v) = Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ Int -> [Vector Float] -> Vector Float
mixV Int
0 forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleaveV Int
chan Vector Float
v
    chan :: Int
chan = forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (forall {k} (t :: k). Proxy t
Proxy @chan)

deinterleaveB :: Channels -> Block -> [Block]
deinterleaveB :: Int -> Block -> [Block]
deinterleaveB Int
chan (Constant Int
count Float
val) =
    forall a. Int -> a -> [a]
replicate Int
chan forall a b. (a -> b) -> a -> b
$ Int -> Float -> Block
Constant (Int
count forall a. Integral a => a -> a -> a
`div` Int
chan) Float
val
deinterleaveB Int
chan (Block Vector Float
v) = forall a b. (a -> b) -> [a] -> [b]
map Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ 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 forall a. Eq a => a -> a -> Bool
== Int
1 = [Vector a
v]
    | Bool
otherwise = forall a b. (a -> b) -> [a] -> [b]
map Int -> Vector a
gen [Int
0 .. Int
channels forall a. Num a => a -> a -> a
- Int
1]
    where
    gen :: Int -> Vector a
gen Int
chan = forall a. Storable a => Int -> (Int -> a) -> Vector a
V.generate Int
frames (\Int
i -> Vector a
v forall a. Storable a => Vector a -> Int -> a
V.! (Int
channels forall a. Num a => a -> a -> a
* Int
i forall a. Num a => a -> a -> a
+ Int
chan))
    frames :: Int
frames = forall a. Storable a => Vector a -> Int
V.length Vector a
v 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) | forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Eq a => a -> a -> Bool
==Block
b) [Block]
bs =
    Int -> Float -> Block
Constant (Int
count forall a. Num a => a -> a -> a
* (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Block]
bs forall a. Num a => a -> a -> a
+ Int
1)) Float
val
interleaveB [Block]
bs = Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
interleaveV forall a b. (a -> b) -> a -> b
$ 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 a. Storable a => (forall s. ST s (MVector s a)) -> Vector a
V.create forall a b. (a -> b) -> a -> b
$ do
    MVector s a
out <- forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> m (MVector (PrimState m) a)
VM.new forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
Num.sum (forall a b. (a -> b) -> [a] -> [b]
map forall a. Storable a => Vector a -> Int
V.length [Vector a]
vs)
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] [Vector a]
vs) forall a b. (a -> b) -> a -> b
$ \(Int
vi, Vector a
v) ->
        forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall a. (Num a, Ord a) => a -> a -> a -> [a]
Lists.range' Int
0 (forall a. Storable a => Vector a -> Int
V.length Vector a
v) Int
1) forall a b. (a -> b) -> a -> b
$ \Int
i ->
            forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
MVector (PrimState m) a -> Int -> a -> m ()
VM.write MVector s a
out (Int
iforall a. Num a => a -> a -> a
*Int
stride forall a. Num a => a -> a -> a
+ Int
vi) (forall a. Storable a => Vector a -> Int -> a
V.unsafeIndex Vector a
v Int
i)
    forall (m :: * -> *) a. Monad m => a -> m a
return MVector s a
out
    where stride :: Int
stride = 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 = forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr 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 (forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream Audio m rate chan1
audio1, 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) = 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 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> 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 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> 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) -> 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) -> forall a b. b -> Either a b
Right ((forall a. a -> Maybe a
Just Block
b1, 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)) -> forall a b. b -> Either a b
Right ((forall a. Maybe a
Nothing, 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)) -> forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$
            case forall a. Ord a => a -> a -> Ordering
compare Frames
frames1 Frames
frames2 of
                Ordering
LT -> ((forall a. a -> Maybe a
Just Block
b1, forall a. a -> Maybe a
Just Block
pre2), (Stream (Of Block) m r
as1, 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 -> ((forall a. a -> Maybe a
Just Block
pre1, forall a. a -> Maybe a
Just Block
b2), (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 -> ((forall a. a -> Maybe a
Just Block
b1, forall a. a -> Maybe a
Just Block
b2), (Stream (Of Block) m r
as1, Stream (Of Block) m r
as2))
            where
            frames1 :: Frames
frames1 = forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan1
chan1 Block
b1
            frames2 :: Frames
frames2 = forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan2
chan2 Block
b2
            (Block
pre1, Block
post1) = Int -> Block -> (Block, Block)
blockSplit (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 (forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan2
chan2 Frames
shortest) Block
b2
            shortest :: Frames
shortest = forall a. Ord a => a -> a -> a
min Frames
frames1 Frames
frames2
    chan1 :: Proxy chan1
chan1 = forall {k} (t :: k). Proxy t
Proxy :: Proxy chan1
    chan2 :: Proxy chan2
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 = forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr forall {m :: * -> *} {r}.
Monad m =>
[Stream (Of Block) m r]
-> m (Either () ([Block], [Stream (Of Block) m r]))
unfold forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map 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 <- forall a. [Maybe a] -> [a]
Maybe.catMaybes forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM 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
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case forall a. Ord a => [a] -> Maybe a
Lists.minimum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (Block -> Int
blockCount forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(Block, Stream (Of Block) m r)]
pairs of
            Maybe Int
Nothing -> forall a b. a -> Either a b
Left ()
            Just Int
shortest -> forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a b. [(a, b)] -> ([a], [b])
unzip forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (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 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, 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) = 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, 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 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 = forall (m :: * -> *) (rate :: Nat).
Int -> Stream (Of [Block]) m () -> NAudio m rate
NAudio (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Audio m rate 1]
audios) forall a b. (a -> b) -> a -> b
$
    forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr forall {m :: * -> *} {b} {r}.
(Monad m, Monoid b) =>
[Stream (Of b) m r] -> m (Either () ([b], [Stream (Of b) m r]))
unfold (forall a b. (a -> b) -> [a] -> [b]
map (forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM 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 = forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap 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]
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Stream (Of b) m r]
tails then forall a b. a -> Either a b
Left ()
            else forall a b. b -> Either a b
Right (forall a b. (a -> b) -> [a] -> [b]
map (forall a. a -> Maybe a -> a
fromMaybe 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
    | forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio forall a. Eq a => a -> a -> Bool
== Int
1 =
        forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> a
head) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (rate :: Nat).
NAudio m rate -> Stream (Of [Block]) m ()
_nstream NAudio m rate
naudio
    | forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio forall a. Eq a => a -> a -> Bool
== Int
chan =
        forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
S.map [Block] -> Block
interleaveB forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (rate :: Nat).
NAudio m rate -> Stream (Of [Block]) m ()
_nstream NAudio m rate
naudio
    | Bool
otherwise = forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ Text
"can't convert " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt (forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio)
        forall a. Semigroup a => a -> a -> a
<> Text
" channels to " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt Int
chan
    where
    chan :: Int
chan = forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr forall {m :: * -> *} {chan :: Nat} {rate :: Nat}.
(Monad m, KnownNat chan) =>
(Bool, Audio m rate chan)
-> m (Either () (Block, (Bool, Audio m rate chan)))
unfold 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) <- 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
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Block]
blocks
            then forall a b. a -> Either a b
Left ()
            else forall a b. b -> Either a b
Right (forall a. Monoid a => [a] -> a
mconcat [Block]
blocks, (Bool
False, Audio m rate chan
audio))
    align :: Frames
align = if Frames
now forall a. Integral a => a -> a -> a
`mod` Frames
size forall a. Eq a => a -> a -> Bool
== Frames
0 then Frames
size else Frames
size forall a. Num a => a -> a -> a
- Frames
now 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 forall a. Ord a => a -> a -> Bool
<= Frames
0 = NAudio m rate
naudio
    | Bool
otherwise = forall (m :: * -> *) (rate :: Nat).
Int -> Stream (Of [Block]) m () -> NAudio m rate
NAudio (forall (m :: * -> *) (rate :: Nat). NAudio m rate -> Int
_nchannels NAudio m rate
naudio) forall a b. (a -> b) -> a -> b
$
        forall state a. state -> ((state -> a) -> state -> a) -> a
Control.loop1 (Frames
0, forall (m :: * -> *) (rate :: Nat).
NAudio m rate -> Stream (Of [Block]) m ()
_nstream NAudio m rate
naudio) forall a b. (a -> b) -> a -> b
$ \(Frames, Stream (Of [Block]) m ()) -> Stream (Of [Block]) m ()
loop (Frames
now, Stream (Of [Block]) m ()
audio) ->
            forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (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) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                Maybe ([Block], Stream (Of [Block]) m ())
Nothing -> 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 forall a. Ord a => a -> a -> Bool
<= Frames
frames -> forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield [Block]
blocks 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 forall a. Ord a => a -> a -> Bool
>= Frames
frames -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
                    | Bool
otherwise -> forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a, b) -> a
fst 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 forall a. Num a => a -> a -> a
+ Int -> Block -> Frames
blockFrames_ Int
chan Block
block
                    left :: Int
left = Int -> Frames -> Int
framesCount_ Int
chan (forall a. Ord a => a -> a -> a
min Frames
frames Frames
end forall a. Num a => a -> a -> a
- Frames
now)
        where chan :: Int
chan = 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 = forall (m :: * -> *) s r a.
Monad m =>
(s -> m (Either r (a, s))) -> s -> Stream (Of a) m r
S.unfoldr forall {m :: * -> *} {r} {a}.
Monad m =>
Stream (Of [Block]) m r
-> m (Either a ([Block], Stream (Of [Block]) m r))
unfold (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 = 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 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
        Maybe ([Block], Stream (Of [Block]) m r)
Nothing ->
            forall a b. b -> Either a b
Right (forall a. Int -> a -> [a]
replicate (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) -> forall a b. b -> Either a b
Right (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 forall a. Eq a => a -> a -> Bool
== Float
0 = Int -> Float -> Block
Constant (forall a. Ord a => a -> a -> a
max Int
size Int
count) Float
0
    pad Block
block
        | Block -> Int
blockCount Block
block forall a. Ord a => a -> a -> Bool
>= Int
size = Block
block
        | Bool
otherwise = Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ Vector Float
v forall a. Semigroup a => a -> a -> a
<> forall a. Storable a => Int -> a -> Vector a
V.replicate (Int
size forall a. Num a => a -> a -> a
- 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 = forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount (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 = 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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a r. Monad m => a -> Stream (Of a) m r
S.repeat forall a b. (a -> b) -> a -> b
$ Int -> Float -> Block
Constant Int
size Float
val
    where size :: Int
size = forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount (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 =
    forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ forall state a. state -> ((state -> a) -> state -> a) -> a
Control.loop1 Frames
0 forall a b. (a -> b) -> a -> b
$ \Frames -> Stream (Of Block) m ()
loop Frames
frame ->
        forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield (Vector Float -> Block
Block forall a b. (a -> b) -> a -> b
$ Frames -> Vector Float
gen Frames
frame) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Frames -> Stream (Of Block) m ()
loop (Frames
frame forall a. Num a => a -> a -> a
+ Frames
blockSize)
    where
    gen :: Frames -> Vector Float
gen Frames
start =
        forall a. Storable a => Int -> (Int -> a) -> Vector a
V.generate (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Frames
end forall a. Num a => a -> a -> a
- Frames
start)) (forall {a}. Integral a => a -> Float
val forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
+Frames
start) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Frames
Frames)
        where end :: Frames
end = Frames
start forall a. Num a => a -> a -> a
+ Frames
blockSize
    val :: a -> Float
val a
frame = forall a. Floating a => a -> a
sin forall a b. (a -> b) -> a -> b
$ Float
2 forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Float
frequency forall a. Num a => a -> a -> a
* (forall a b. (Integral a, Num b) => a -> b
fromIntegral a
frame forall a. Fractional a => a -> a -> a
/ Float
rate)
    rate :: Float
rate = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
TypeLits.natVal (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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ forall {m :: * -> *}.
Monad m =>
(Frames, Seconds, Seconds, [(Seconds, Seconds)])
-> Stream (Of Block) m ()
loop (Frames
0, Seconds
0, Seconds
0, 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 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
                forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield 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 forall a. Num a => a -> a -> a
+ Frames
generate, Seconds
prevX, Seconds
prevY, [(Seconds, Seconds)]
breakpoints)
            where generate :: Frames
generate = forall a. Ord a => a -> a -> a
min Frames
blockSize (Seconds -> Frames
toFrame Seconds
x forall a. Num a => a -> a -> a
- Frames
start)
        []  | Bool
forever -> forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Audio m rate chan -> Stream (Of Block) m ()
_stream 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 -> forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield 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 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 forall a b. (a -> b) -> a -> b
$ 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frames -> Seconds
toSec forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
+Frames
start) 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 forall a b. (a -> b) -> a -> b
$
        (Seconds
y2 forall a. Num a => a -> a -> a
- Seconds
y1) forall a. Fractional a => a -> a -> a
/ (Seconds
x2 forall a. Num a => a -> a -> a
- Seconds
x1) forall a. Num a => a -> a -> a
* (Seconds
x forall a. Num a => a -> a -> a
- Seconds
x1) 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 = forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount (forall {k} (t :: k). Proxy t
Proxy @1)
    rate :: Int
rate = forall (n :: Nat). KnownNat n => Proxy n -> Int
natVal (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 forall a. Ord a => a -> a -> Bool
> a
0 Bool -> Bool -> Bool
&& b
y forall a. Eq a => a -> a -> Bool
/= b
0 = (a
x, b
0) 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) = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ()
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]
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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e a. Exception e => e -> IO a
Exception.throwIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Exception
Exception
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((HasCallStack => Text
CallStack.getStack 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
_ = forall (m :: * -> *) a. Monad m => a -> m a
return ()
assert Bool
False Text
msg = forall (m :: * -> *) a. (HasCallStack, MonadIO m) => Text -> m a
throwIO forall a b. (a -> b) -> a -> b
$ Text
"assertion: " 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 = forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Stream (Of Block) m () -> Stream (Of Block) m ())
-> Audio m rate chan -> Audio m rate chan
apply (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 = forall a. Storable a => Int -> a -> Vector a
V.replicate (forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount (forall {k} (t :: k). Proxy t
Proxy @1) Frames
blockSize) Float
0

-- * conversions

linearToDb, dbToLinear :: Float -> Float
linearToDb :: Float -> Float
linearToDb Float
x = forall a. Floating a => a -> a -> a
logBase Float
10 Float
x forall a. Num a => a -> a -> a
* Float
20
dbToLinear :: Float -> Float
dbToLinear Float
x = Float
10forall a. Floating a => a -> a -> a
**(Float
x 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 <- forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Of [a] r)
S.toList forall a b. (a -> b) -> a -> b
$
        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 -> (forall a. Num a => a -> a -> a
+Frames
n) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan
chan) Frames
0 (forall a. Ord a => a -> a -> Bool
>=Frames
frames) Stream (Of Block) m ()
audio
    forall (m :: * -> *) a. Monad m => a -> m a
return ([Block]
blocks, 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 = 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 forall a. Ord a => a -> a -> Bool
<= Frames
0 = forall (m :: * -> *) a. Monad m => a -> m a
return ([], forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio Stream (Of Block) m ()
audio)
    | Bool
otherwise = 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 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left () -> forall (m :: * -> *) a. Monad m => a -> m a
return ([], forall a. Monoid a => a
mempty)
        Right (Block
block, Stream (Of Block) m ()
audio)
            | Frames
produced forall a. Ord a => a -> a -> Bool
< Frames
frames ->
                forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Block
block:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
(Monad m, KnownNat chan) =>
Frames -> Audio m rate chan -> m ([Block], Audio m rate chan)
splitAt (Frames
frames forall a. Num a => a -> a -> a
- Frames
produced) (forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio Stream (Of Block) m ()
audio)
            | Frames
produced forall a. Eq a => a -> a -> Bool
== Frames
frames -> forall (m :: * -> *) a. Monad m => a -> m a
return ([Block
block], forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio Stream (Of Block) m ()
audio)
            | Bool
otherwise -> forall (m :: * -> *) a. Monad m => a -> m a
return ([Block
pre], forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ 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 = forall (chan :: Nat).
KnownNat chan =>
Proxy chan -> Block -> Frames
blockFrames Proxy chan
chan Block
block
            (Block
pre, Block
post) = Int -> Block -> (Block, Block)
blockSplit (forall (chan :: Nat). KnownNat chan => Proxy chan -> Frames -> Int
framesCount Proxy chan
chan Frames
frames) Block
block
    where
    chan :: Proxy chan
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) = 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 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Left () -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Right (Block
block, Stream (Of Block) m ()
audio) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (Block
block, 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) = 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 forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Left () -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Right (Block
block, Stream (Of Block) m ()
audio) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (rate :: Nat) (chan :: Nat).
Stream (Of Block) m () -> Audio m rate chan
Audio forall a b. (a -> b) -> a -> b
$ 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 = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
int) of
    Maybe SomeNat
Nothing -> forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"not a natural: " forall a. Semigroup a => a -> a -> a
<> 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 = 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 = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (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) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left a
r -> forall (m :: * -> *) a. Monad m => a -> m a
return (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 -> forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield a
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Stream (Of a) m a
as
            | Bool
otherwise -> forall (m :: * -> *) a. Monad m => a -> Stream (Of a) m ()
S.yield a
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