RustAudio / dasp

The fundamentals for Digital Audio Signal Processing. Formerly `sample`.
Other
883 stars 64 forks source link

Implement Frame generically over arbitrary N channels #179

Open rawler opened 1 year ago

rawler commented 1 year ago

Currently, the Frame trait is only implemented for [S; N] where S: Sample for N = 1-32. While realistically more than sufficient, it makes it difficult for dependent code to be generic over Frames of arbitrary N.

I.E. the (admittedly contrived) example of

fn do_something(f: &impl Frame) {}

struct MyFilter<const CHANNELS: usize> {
    buffer: [f32; CHANNELS]
}

impl<const CHANNELS: usize> MyFilter<CHANNELS> {
    pub fn emit(&self) {
        do_something(&self.buffer)
    }
}

will fail compilation with error:

error[E0277]: the trait bound `[f32; CHANNELS]: Frame` is not satisfied
  --> examples/bleh.rs:13:22
   |
13 |         do_something(&self.buffer)
   |         ------------ ^^^^^^^^^^^^ the trait `Frame` is not implemented for `[f32; CHANNELS]`
   |         |
   |         required by a bound introduced by this call
   |
   = help: the following other types implement trait `Frame`:
             [S; 10]
             [S; 11]
             [S; 12]
             [S; 13]
             [S; 14]
             [S; 15]
             [S; 16]
             [S; 17]
           and 24 others
note: required by a bound in `do_something`
  --> examples/bleh.rs:3:26
   |
3  | fn do_something(f: &impl Frame) {
   |                          ^^^^^ required by this bound in `do_something`

For more information about this error, try `rustc --explain E0277`.
rawler commented 1 year ago

For example, this is currently blocking a cleanup of generics in the ebur128 crate. I managed to clean up some of the code, but got stuck with the larger cleanup, partly due to missing generic implementations of Frame