synthesizer-core-0.8.1: Audio signal processing coded in Haskell: Low level part

Safe HaskellNone



Process chunks of data in the IO monad. Typical inputs are strict storable vectors and piecewise constant values, and typical outputs are strict storable vectors. You may also combine several of these types using the Zip type constructor.

We may substitute IO by ST in the future, but I am uncertain about that. On the one hand, the admissible IO functionality is very restricted, only memory manipulation is allowed, on the other hand we use ForeignPtrs that are not part of ST framework.



data T a b Source #


Cons (a -> state -> IO (b, state)) (IO state) (state -> IO ()) 


Arrow T Source # 


arr :: (b -> c) -> T b c #

first :: T b c -> T (b, d) (c, d) #

second :: T b c -> T (d, b) (d, c) #

(***) :: T b c -> T b' c' -> T (b, b') (c, c') #

(&&&) :: T b c -> T b c' -> T b (c, c') #

Category * T Source # 


id :: cat a a #

(.) :: cat b c -> cat a b -> cat a c #

(Transform a, Read b, Monoid b) => Monoid (T a b) Source #

mappend should be used sparingly. In a loop it will have to construct types at runtime which is rather expensive.


mempty :: T a b #

mappend :: T a b -> T a b -> T a b #

mconcat :: [T a b] -> T a b #

fromCausal :: Monoid b => T a b -> T a b Source #

mapAccum :: (a -> state -> (b, state)) -> state -> T a b Source #

traverse :: state -> (a -> State state b) -> T a b Source #

runCont :: (Transform a, Transform b) => T a b -> IO (([a] -> [b]) -> [a] -> [b]) Source #

This function converts a process into a function on lazy storable vectors. To this end it must call unsafePerformIO, that is, the effects of all functions called in the process must not be observable.

I am not sure, we need this function at all.

runStorableChunkyCont :: (Storable a, Storable b) => T (Vector a) (Vector b) -> IO ((Vector a -> Vector b) -> Vector a -> Vector b) Source #

The same restrictions as for runCont apply.

zip :: Arrow arrow => arrow a b -> arrow a c -> arrow a (T b c) Source #

continue :: (Transform a, Transform sig b) => T a (sig b) -> (b -> T a (sig b)) -> T a (sig b) Source #

If the first process does not produce any output, then the continuing process will not be started.

continueChunk :: (Transform a, Transform b) => T a b -> (b -> T a b) -> T a b Source #

Pass the last non-empty output chunk as parameter to the continuing process. This breaks the abstraction from the chunk sizes, but we need it for implementing vectorized processing.