logo
Expand description

Audio processing

Process functions which you call in your audio callback are collected here.

These functions also run the scheduler of pd. The chosen function needs to be called in a loop to keep pd “running”.

Examples

use libpd_rs::{
    close_patch,
    init, initialize_audio, open_patch,
    process::process_float,
    convenience::{dsp_on, calculate_ticks},
    receive::receive_messages_from_pd
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    init()?;
    initialize_audio(1, 2, 44100)?;
     
    // Place your own patch here.
    let patch_handle = open_patch("tests/patches/sine.pd")?;

    // Turn the dsp on
    dsp_on()?;

    // Process the audio (imagine that this is your audio callback)
    // We're going to treat this separate thread as the
    // high priority audio callback from the OS for this example.

    // Open some channels to communicate with it.
    let (tx, rx) = std::sync::mpsc::channel::<()>();

    let handle = std::thread::spawn(move || {
        // Mimic audio callback buffers.
        let input_buffer = [0.0f32; 512];
        let mut output_buffer = [0.0f32; 1024];
         
        let output_channels = 2;
        let sample_rate = 44100;
         
        // Run pd
        loop {
            // Mimic the call frequency of the audio callback.
            let approximate_buffer_duration =
                (output_buffer.len() as f32 / sample_rate as f32) * 1000.0;
            std::thread::sleep(std::time::Duration::from_millis(
                approximate_buffer_duration as u64,
            ));
             
            // We may call this to also receive from internal ring buffers in this loop.
            // So our registered listeners receive messages.
            receive_messages_from_pd();
             
            // Calculate ticks for the internal scheduler
            let ticks = calculate_ticks(output_buffer.len() as i32, output_channels);
             
            // Process the audio and advance the internal scheduler by the number of ticks.
            process_float(ticks, &input_buffer, &mut output_buffer);
             
            // This is just meaningful for this example,
            // so we can break from this loop.
            match rx.try_recv() {
                Ok(_) => break,
                _ => continue,
            }
        }
     });

    // When processing starts pd becomes alive because the scheduler is running.
     
    // After some time
    std::thread::sleep(std::time::Duration::from_millis(1000));
     
    // We may join the thread.
    tx.send(()).unwrap();
    handle.join().unwrap();

    // And close the patch
    close_patch(patch_handle)?;

    Ok(())
}

Functions

Processes the audio buffer of f64 in place through the loaded pd patch.

Processes the audio buffer of f32 in place through the loaded pd patch.

Processes the non-interleaved f32 audio buffer in place through the loaded pd patch.

Processes the non-interleaved f64 audio buffer in place through the loaded pd patch.

Processes the non-interleaved i16 audio buffer in place through the loaded pd patch.

Processes the audio buffer of i16 in place through the loaded pd patch.