Skip to content

Instantly share code, notes, and snippets.

@jarkkojs
Created November 19, 2021 06:09
Show Gist options
  • Save jarkkojs/efe195731675bc28a5531bbbbc687d08 to your computer and use it in GitHub Desktop.
Save jarkkojs/efe195731675bc28a5531bbbbc687d08 to your computer and use it in GitHub Desktop.
//! Copyright (c) Jarkko Sakkinen 2021
//!
//! A simple synthesis and playback test.
use cpal::Device;
use cpal::Sample;
use cpal::SampleFormat;
use cpal::StreamConfig;
use cpal::StreamError;
use cpal::traits::DeviceTrait;
use cpal::traits::HostTrait;
use cpal::traits::StreamTrait;
use libm::fmod;
fn main() {
let host = cpal::default_host();
let device = host
.default_output_device()
.expect("unable to find an output device");
let config = device.default_output_config().unwrap();
match config.sample_format() {
SampleFormat::F32 => play::<f32>(&device, &config.into()),
SampleFormat::I16 => play::<i16>(&device, &config.into()),
SampleFormat::U16 => play::<u16>(&device, &config.into()),
};
}
fn play<T: Sample>(device: &Device, config: &StreamConfig) -> () {
let sample_rate = config.sample_rate.0 as u32;
let mut sample = 0;
let mut oscillator = move || {
sample = (sample + 1) % sample_rate;
let cycle = 1.0 / 55.0;
let time = fmod(sample as f64 / sample_rate as f64, cycle);
((time / cycle) * 2.0 - 1.0) as f32
};
let channels = config.channels as usize;
let stream = device
.build_output_stream(
config,
move |data: &mut [T], _| data_callback(data, channels, &mut oscillator),
error_callback,
)
.unwrap();
stream.play().unwrap();
std::thread::sleep(std::time::Duration::from_secs(10));
}
fn data_callback<T: Sample>(output: &mut [T], channels: usize, oscillator: &mut dyn FnMut() -> f32)
{
for frame in output.chunks_mut(channels) {
let value: T = cpal::Sample::from::<f32>(&oscillator());
for sample in frame.iter_mut() {
*sample = value;
}
}
}
fn error_callback(err: StreamError) {
eprintln!("{}", err);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment