【问题标题】:Is there a better way to organize this behaviour as a collection of traits?有没有更好的方法来组织这种行为作为特征的集合?
【发布时间】:2020-03-10 20:21:56
【问题描述】:

我正在组装一个音频 dsp,并且我正在寻找一种更“rustacean”的方式来实现以下内容:

pub struct TransformOptions<SourceType> {
    transform         : Option<Box<dyn Fn(&mut [SourceType; FFT_SIZE], &mut [SourceType; FFT_SIZE])>>,
    filter            : Option<Box<dyn Fn(&mut [SourceType; FFT_SIZE], [SourceType; FFT_SIZE])>>,
    inverse_transform : Option<Box<dyn Fn(&mut [SourceType; FFT_SIZE], &mut [SourceType; FFT_SIZE])>>
    //should try anddo this in an array
    //options           : [Option; NUM_TRANSFORM_OPTIONS],
}

impl<SourceType : Default> TransformOptions<SourceType> {
    fn cycle_through(&self, input : [SourceType; FFT_SIZE])->[SourceType; FFT_SIZE] {
        //let input : [T ; FFT_SIZE] = arr![T; FFT_SIZE];
        //This represents the amplitude of the signal represented as the distance from the origin on a unit circle
        //Here we transform the signal from the time domain to the frequency domain.
        //Note that humans can only hear sound with a frequency between 20Hz and 20_000Hz
        // fft.process(&mut time_ring_buffer[time_index..time_index + fft_size], &mut complex_freq_buffer[..]);
        if  let Some(_) = self.transform{
            let transform_func = self.transform.unwrap();
            let output = input.clone();
            transform_func(&input, &output);
            input = output;
        }
        //the analytic array acts as a filter, removing the negative and dc portions
        //of the signal as well as filtering out the nyquist portion of the signal
        //Also applies the hamming window here

        // By applying the inverse fourier transform we transform the signal from the frequency domain back into the
        if  let Some(_) = self.filter {
            let filter_func = self.filter.unwrap();
            /*
               this is roughly how it should go down
               | input, coefficient | {
               for input_idx in index.ter() {
                    input_idx = input_idx * coeffcient[input_idx.index];
               }
               }
            */
            input = filter_func(&input);
        }
        // By applying the inverse fourier transform we transform the signal from the frequency domain back into the
        // time domain. However now this signal can be represented as a series of points on a unit circle.
        // ifft.process(&mut complex_freq_buffer[..], &mut complex_analytic_buffer[..]);
        if  let Some(_) = self.inverse_transform {
            let transform_func = self.inverse_transform.unwrap();
            let output = input.clone();
            transform_func(&input, &output);
            input = output;
        }
        input
    }
}

基本上我想做的是拥有某种特征,它收集一些子特征并检查它们是否在这个结构上实现。如果是,则调用它们各自的顶级函数并适当地传递数据。我不确定是否有比目前更好的方法来实现这一点。

编辑:像这样的东西就是我正在拍摄的 是否有可能/建议做这样的事情?


trait Transform {
    fn transform(&self, &mut [SourceType; FFT_SIZE], &mut [SourceType; FFT_SIZE]) {
        // default implementation does nothing
    }
}

trait InverseTransform {
    fn filter(&self, &mut [SourceType; FFT_SIZE], [SourceType; FFT_SIZE]) {
        // default implementation does nothing
    }
}

trait InverseTransform {
    fn inverse_transform(&self, &mut [SourceType; FFT_SIZE], &mut [SourceType; FFT_SIZE]) {
        // default implementation does nothing
    }
}
trait TransformOptions {
    //Check for and use the above traits in here somehow. Leaving room for implementation
}

【问题讨论】:

    标签: struct rust signal-processing traits


    【解决方案1】:

    为什么不具备这样的特质:

    trait TransformOptions {
        fn transform(&self, &mut [SourceType; FFT_SIZE], &mut [SourceType; FFT_SIZE]) {
            // default implementation does nothing
        }
        fn filter(&self, &mut [SourceType; FFT_SIZE], [SourceType; FFT_SIZE]) {
            // default implementation does nothing
        }
        fn inverse_transform(&self, &mut [SourceType; FFT_SIZE], &mut [SourceType; FFT_SIZE]) {
            // default implementation does nothing
        }
    }
    

    然后,每个实现者可以自行决定是否要在transformfilterinverse_transform 中实际工作。然后,您无需检查函数是否存在,而是简单地调用它,它可能是空操作。

    【讨论】:

    • 是的,我确实喜欢将实现留给实现者的方式,我真正想做的是在选择是否存在 inverse_transform 时提供灵活性。或者可能是一些额外的东西,比如 post inverse_filter。
    猜你喜欢
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2012-03-15
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多