rportaudio 0.1.1

PortAudio bindings for Rust
Documentation
use rportaudio::{device, hostapi, stream, types};
use rportaudio::types::{PaStreamCallbackResult, PaStreamParameters, PaStreamTimeInfo};
use rportaudio::types::PaStreamCallbackResult::Continue;

fn main() {
  println!("version: {} \"{}\"", rportaudio::version(), rportaudio::version_text());
  println!("init: {:?}", rportaudio::initialize());

  print_info();
  doit();

  println!("term: {:?}", rportaudio::terminate());
}

fn print_info() {
  match hostapi::count() {
    Ok(api_count) => {
      for i in 0..api_count {
        let name = match hostapi::info(i) {
          None => "???".to_string(),
          Some(ha) => ha.name,
        };
        println!("api {}: {}", i, name);
      }
    }
    _ => {}
  }

  match device::count() {
    Ok(device_count) => {
      for i in 0..device_count {
        let name = match device::info(i) {
          None => "???".to_string(),
          Some(d) => d.name,
        };
        println!("dev {}: {}", i, name);
      }
    }
    _ => {}
  }
}

fn doit() {
  callback_demo();
  write_demo();
  mixed_demo();
}

fn callback_demo() {
  let callback = Box::new(|_input: &[f32], output: &mut [f32], _time: PaStreamTimeInfo, _flags: types::PaStreamCallbackFlags| -> PaStreamCallbackResult{
    static mut LP: f32 = 0.0;
    static mut RP: f32 = 0.0;

    let mut left_phase = unsafe { LP };
    let mut right_phase = unsafe { RP };

    for i in 0..output.len() / 2 {
      output[i * 2] = left_phase;
      output[i * 2 + 1] = right_phase;

      left_phase += 0.01;
      if left_phase >= 1.0 { left_phase -= 2.0; }

      right_phase += 0.03;
      if right_phase >= 1.0 { right_phase -= 2.0; }
    }

    unsafe { LP = left_phase; }
    unsafe { RP = right_phase; }

    Continue
  });

  let finished_callback = Box::new(|| println!("Finshed callback called"));
  let mut stream = match stream::Stream::open_default(0, 2, 44100f64, stream::FRAMES_PER_BUFFER_UNSPECIFIED, Some(callback)) {
    Err(v) => {
      println!("Err({:?})", v);
      return;
    }
    Ok(stream) => stream,
  };
  println!("finished_callback: {:?}", stream.set_finished_callback(finished_callback));
  println!("start: {:?}", stream.start());
  std::thread::sleep(std::time::Duration::from_secs(1));
  println!("stop: {:?}", stream.stop());

  println!("finished_callback: {:?}", stream.unset_finished_callback());
  println!("start: {:?}", stream.start());
  std::thread::sleep(std::time::Duration::from_secs(1));
  println!("stop: {:?}", stream.stop());
}

fn write_demo() {
  let stream = match stream::Stream::open_default(0, 2, 44100f64, stream::FRAMES_PER_BUFFER_UNSPECIFIED, None) {
    Err(v) => {
      println!("Err({:?})", v);
      return;
    }
    Ok(stream) => stream,
  };

  println!("start: {:?}", stream.start());
  println!("write: {:?}", stream.write(&get_buffer(44100 * 3)));
  println!("stop: {:?}", stream.stop());
}

fn get_buffer(len: usize) -> Vec<f32> {
  let mut left = 0.0f32;
  let mut right = 0.0f32;
  let mut result = Vec::with_capacity(len);
  for _ in 0..len / 2 {
    result.push(left);
    result.push(right);
    left += 0.03;
    right += 0.01;
    if left >= 1.0 { left -= 2.0; }
    if right >= 1.0 { right -= 2.0; }
  }
  result
}

fn mixed_demo() {
  let out_idx = match device::default_output() {
    Some(o) => o,
    None => return,
  };
  let out_lat = match device::info(out_idx) {
    None => return,
    Some(d) => d.default_low_output_latency,
  };
  let output = PaStreamParameters { device: out_idx, channel_count: 2, suggested_latency: out_lat, data: 0i8 };

  let supported = stream::is_format_supported::<i8, _>(None, Some(output), 44100f64);
  println!("support? {:?}", supported);
  if supported.is_err() { return; }

  let stream = match stream::Stream::<i8, _>::open(None, Some(output), 44100f64, stream::FRAMES_PER_BUFFER_UNSPECIFIED, types::PaStreamFlags::empty(), None) {
    Ok(s) => s,
    Err(o) => {
      println!("stream: Err({:?})", o);
      return;
    }
  };

  let buffer = get_buffer(2 * 44100).into_iter().map(|v| (v * 127.0) as i8).collect::<Vec<i8>>();
  println!("start: {:?}", stream.start());
  println!("write: {:?}", stream.write(&buffer));
  println!("stop: {:?}", stream.stop());
}