Created
November 19, 2021 06:09
-
-
Save jarkkojs/efe195731675bc28a5531bbbbc687d08 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! 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