[Haskell-cafe] Sample rate inference

Glynn Clements glynn at gclements.plus.com
Thu Nov 11 07:50:45 EST 2004


Henning Thielemann wrote:

>  I want to connect several functions for signal processing. The typical
> case is that in a network of signal processor there are parts that are
> already discretized such as sampled sounds, and there are processors with
> no particular sample rate such as amplifiers. But when it comes to
> computation each processor must choose a sample rate for processing. There
> are also processors for converting sample rates. They divide the network
> into components of equal sample rate.
>  The computation sample rate should be propagated through the network as
> follows:
>   If in a component of equal sample rate some processors have the same
> fixed sample rate, all uncertain processors must adapt that. 
>   If some processors have different fixed sample rates this is an error. 
>   If no processor has a fixed sample rate, the user must provide one
> manually.
>  To me this looks very similar to type inference. Is there some mechanism
> in Haskell which supports this programming structure? 

If you define a class for sample rates, and an instance for each
possible sample rate, then you could use type inference, e.g.

> class Rate a where
> 	rate :: a -> Int;
> 
> data Rate22050 = Rate22050;
> instance Rate Rate22050 where
> 	rate _ = 22050;
> 
> data Rate44100 = Rate44100;
> instance Rate Rate44100 where
> 	rate _ = 44100;
> 
> data (Rate a) => Stream a = ...
> 
> type unaryProcessor a = (Rate a) => Stream a -> Stream a
> type binaryProcessor a = (Rate a) => Stream a -> Stream a -> Stream a
> ...
> 
> resample :: (Rate a, Rate b) => Stream a -> Stream b
> resample s = ...

Supporting arbitrary sample rates would require being able to
construct a distinct type for every possible sample rate; e.g. using
Church numerals:

> data Rate0 = Rate0
> instance Rate Rate0 where
> 	rate _ = 0;
> 
> data (Rate a) => RateN a
> instance (Rate a) => Rate (RateN a) where
> 	rate (RateN x) = 1 + rate x;
> 
> fourHertzFilter :: unaryProcessor (RateN (RateN (RateN (RateN Rate0))))
> fourHertzFilter = ...

I doubt that this specific example wouldn't work in practice (the type
inference would probably give the compiler a heart attack), but you
could presumably construct an equivalent mechanism using base-N
numerals.

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the Haskell-Cafe mailing list