@@ -272,51 +272,65 @@ RUST_LOG=trace cargo test --features log
272272
273273## Example
274274
275- Resample a dummy audio file from 44100 to 48000 Hz.
276- This uses the ` Fft ` resampler, which requires the ` fft_resampler ` feature (enabled by default).
275+ Resample stereo audio from 44100 to 48000 Hz, one chunk at a time.
276+ The input is processed in a loop and can come from anywhere: a file read
277+ chunk by chunk, or a live stream that keeps running indefinitely.
278+ This uses the ` Async ` resampler with polynomial interpolation,
279+ which is always available and needs no optional features.
277280See also the "process_f64" example that can be used to process a file from disk.
278- ``` rust,ignore
281+ ``` rust
279282use rubato :: {
280- Resampler, Fft, FixedSync , Indexing
283+ Resampler , Async , FixedAsync , PolynomialDegree , Indexing
281284};
282285use audioadapter_buffers :: direct :: InterleavedSlice ;
283286
284- let mut resampler = Fft::<f64>::new(48000, 44100, 1024, 2, FixedSync::Both).unwrap();
285-
286- // create a short dummy audio clip, assuming it's stereo stored as interleaved f64 values
287- let audio_clip = vec![0.0; 2*10000];
288-
289- // wrap it with an InterleavedSlice Adapter
290- let nbr_input_frames = audio_clip.len() / 2;
291- let input_adapter = InterleavedSlice::new(&audio_clip, 2, nbr_input_frames).unwrap();
292-
293- // create a buffer for the output
294- let mut outdata = vec![0.0; 2*2*10000];
295- let outdata_capacity = outdata.len() / 2;
296- let mut output_adapter =
297- InterleavedSlice::new_mut(&mut outdata, 2, outdata_capacity).unwrap();
298-
299- // Preparations
300- let mut indexing = Indexing::new();
301-
302- let mut input_frames_left = nbr_input_frames;
303- let mut input_frames_next = resampler.input_frames_next();
304-
305- // Loop over all full chunks.
306- // There will be some unprocessed input frames left after the last full chunk.
307- // see the `process_f64` example for how to handle those
308- // using `partial_len` of the indexing struct.
309- // It is also possible to use the `process_all_into_buffer` method
310- // to process the entire file (including any last partial chunk) with a single call.
311- while input_frames_left >= input_frames_next {
312- let (frames_read, frames_written) = resampler
287+ let channels = 2 ;
288+ let chunk_size = 1024 ;
289+
290+ let mut resampler = Async :: <f64 >:: new_poly (
291+ 48000.0 / 44100.0 ,
292+ 1.1 ,
293+ PolynomialDegree :: Cubic ,
294+ chunk_size ,
295+ channels ,
296+ FixedAsync :: Input ,
297+ ). unwrap ();
298+
299+ // Reusable buffers for a single chunk, assuming interleaved f64 samples.
300+ // With `FixedAsync::Input` every call consumes `chunk_size` input frames and
301+ // produces at most `output_frames_max()` output frames.
302+ let mut indata = vec! [0.0 ; channels * chunk_size ];
303+ let mut outdata = vec! [0.0 ; channels * resampler . output_frames_max ()];
304+ let outdata_capacity = outdata . len () / channels ;
305+
306+ let indexing = Indexing :: new ();
307+
308+ // Keep processing for as long as there is more audio to handle.
309+ // Here the source is a dummy counter that stops after a few chunks;
310+ // in a real application this stands in for "is there more data?".
311+ let mut chunks_left = 10 ;
312+ loop {
313+ // Fetch the next `input_frames_next()` frames from the source into `indata`.
314+ // For a file, break out of the loop once the end is reached (a shorter final
315+ // chunk is handled by setting `partial_len` on the indexing struct, see the
316+ // `process_f64` example). For an endless stream, simply never break.
317+ if chunks_left == 0 {
318+ break ;
319+ }
320+ chunks_left -= 1 ;
321+ let frames_to_read = resampler . input_frames_next ();
322+ // (read `frames_to_read` frames from the file or stream into `indata` here)
323+
324+ let input_adapter = InterleavedSlice :: new (& indata , channels , frames_to_read ). unwrap ();
325+ let mut output_adapter =
326+ InterleavedSlice :: new_mut (& mut outdata , channels , outdata_capacity ). unwrap ();
327+
328+ let (_frames_read , frames_written ) = resampler
313329 . process_into_buffer (& input_adapter , & mut output_adapter , Some (& indexing ))
314330 . unwrap ();
315331
316- indexing.input_offset += frames_read;
317- indexing.output_offset += frames_written;
318- input_frames_left -= frames_read;
319- input_frames_next = resampler.input_frames_next();
332+ // Write the `frames_written` output frames to the destination file or stream.
333+ let _ = frames_written ;
320334}
321335```
322336
0 commit comments