HEnquist / rubato

An asyncronous resampling library written in Rust
MIT License
197 stars 21 forks source link

Resample a Vec<Vec<f64>> #34

Closed daniellga closed 2 years ago

daniellga commented 2 years ago

Hi! Thank you for your work.

I am rather new to Rust and I am struggling to resample a Vec<Vec<f64>>. I saw you put some examples but they seem to read directly from a file. I tried the code below, which works for FftFixedIn but doesn't work for FftFixedInOut. It gives an error: WrongNumberOfFrames { channel: 0, expected: 104736, actual: 96000 }. Is it expected some treatment to the vector (reshaping, interpolation, etc...) before using process() in each case? Could you help me with a working example?

Here's what I am trying to do, passing chunk_size_in as the as the entire length of a single channel (96000):

let mut resampler = FftFixedIn::<f64>::new(sr_in, sr_out, chunk_size_in, sub_chunks, channels);

//create vec of shape (2, 96000) from ndarray
let mut waves_in: Vec<Vec<f64>> = Vec::with_capacity(channels);

for j in 0..channels {
    waves_in.push(arr_in.slice(s![.., j]).to_vec());
}

let waves_out = resampler.process(&waves_in).expect("cannot process resampler");

and

let mut resampler = FftFixedInOut::<f64>::new(sr_in as usize, sr_out as usize, chunk_size_in, channels);

//create vec of shape (2, 96000) from ndarray
let mut waves_in: Vec<Vec<f64>> = Vec::with_capacity(channels);

for j in 0..channels {
    waves_in.push(arr_in.slice(s![.., j]).to_vec());
}

let waves_out = resampler.process(&waves_in).expect("cannot process resampler");
HEnquist commented 2 years ago

You can still use the approach from the examples even if not reading from a file. I would recommend creating a resampler with a chunksize of a thousand or so. Then you split your data up in chunks of the size the resampler needs. If you use one of the fixed in types, then it's always the same number so it's ok to check only once before the first call to process. Keep feeding the resampler data in chunks until you have gone through the entire input. Pad the last chunk with zeros to get the right length if needed. You will get the output also in chunks, so just make a Vec<Vec> where you keep pushing the new data after each process call.

daniellga commented 2 years ago

Thank you for answering. I am gonna try your suggestions as soon as I have some time.

HEnquist commented 2 years ago

I'm assuming this was solved? Please reopen if not!