dasp icon indicating copy to clipboard operation
dasp copied to clipboard

Downsampling using Sinc causes aliasing

Open Azorlogh opened this issue 2 years ago • 0 comments

Thanks to @ollpu for figuring this out

Here is a minimal example: It generates a 900hz sine wave at a 2000hz sample rate, which is then downsampled to 1500hz. The Nyquist frequency of the new signal is 750hz, so we hear an alias of our original signal at 600hz. If I understand correctly, the sinc should have the cutoff set to filter out everything above 750hz in our original signal to avoid this.

use dasp::{interpolate::sinc::Sinc, ring_buffer, signal, Sample, Signal};
use hound::{WavSpec, WavWriter};

fn main() {
    let my_signal = signal::rate(2000.0).const_hz(900.0).sine();

    let mut spec = WavSpec {
        channels: 1,
        sample_rate: 2000,
        bits_per_sample: 16,
        sample_format: hound::SampleFormat::Int,
    };

    let ring_buffer = ring_buffer::Fixed::from([0.0; 100]);
    let sinc = Sinc::new(ring_buffer);
    let my_signal = my_signal.from_hz_to_hz(sinc, 2000.0, 1500.0);
    spec.sample_rate = 1500;

    let mut writer = WavWriter::create("my_output.wav", spec).unwrap();

    for frame in my_signal.take(2000 * 4) {
        writer
            .write_sample((frame * i16::MAX as f64) as i16)
            .unwrap();
    }
}

Azorlogh avatar Jun 11 '22 22:06 Azorlogh