BLAAALAKKLJHSLJHDKHJALKJHLKGSFG
Hello everyone! It seems that the devlogs have become oppositely bidaily — just this once, don’t you worry — than my last two devlogs. Let’s dive right in since we have so much to cover.
audio output master race
After I finished chan 4, it was time to implement master apu registers and channel mixing and panning.
Most of the registers were pretty simple, except the one with the master APU power on/power off, as to implement it I had to gate every write on whether it was on, except the wave RAM. I also did that during my PE class (while exercising, of course), which contributed to the difficulty. Fortunately, I write my code in Neovim, so it really sped things up, including 1-handed editing.
With that, the backend was nearly done, and I had reached the point at which I would no longer need Pan Docs or anything of the like, just straight Rust sailing.
Thread the Needle
In order to get the audio timed correctly, I had to hook up tick_channels() to a channel on which it sends a tuple of u16s (left and right amplitudes) to some receiver. This lets the audio be decoupled from whatever frontend one has.
Your Pal, CPAL
cpal is a a Rust crate for audio and stuff. Here’s the audio stuff because I can’t think straight it’s so late & I have an integration by parts quiz tomorrow and I don’t want to fail something light b/c I didn’t sleep.
fn get_audio_stream(cpu: &mut Cpu) -> Result<Option<Stream>, Box<dyn std::error: :Error>> {
if true && let Some(device) = cpal::default_host().default_output_device() {
let supported_stream_config = device.default_output_config()?;
let stream_config = supported_stream_config.config();
let sample_format = supported_stream_config.sample_format();
let (sender, receiver) = std::sync::mpsc::sync_channel::<(u16, u16)>(5000);
let error_callback = |_err: cpal::Error| {};
cpu.set_audio_sample_rate(stream_config.sample_rate);
cpu.set_audio_sample_sender(sender);
let stream = match sample_format {
cpal::SampleFormat::F32 => {
let data_callback = make_data_callback::<f32>(receiver, stream_config.channels);
let stream = device.build_output_stream(
stream_config,
data_callback,
error_callback,
None,
)?;
stream.play()?;
Some(stream)
}
cpal::SampleFormat::I16 => {
let data_callback = make_data_callback::<i16>(receiver, stream_config.channels);
let stream = device.build_output_stream(
stream_config,
data_callback,
error_callback,
None,
)?;
stream.play()?;
Some(stream)
}
cpal::SampleFormat::U16 => {
let data_callback = make_data_callback::<u16>(receiver, stream_config.channels);
let stream = device.build_output_stream(
stream_config,
data_callback,
error_callback,
None,
)?;
stream.play()?;
Some(stream)
}
_ => Err(
"Audio output sample format not supported! Try disabling audio in your config with 'audio = false'",
)?,
};
return Ok(stream);
}
Ok(None)
}
// makedatacallback not shown due to char limits
Position,Velocity, Acceleration, Jerk, Snap, Crackle, and Pop
After that, I tested it, but there was some terrible audio crackling. Turns out it was due to oversleeping when trying to time things correctly, though before finding this out, I ended up slightly optimising draw_frame().The artifacts seem to be mostly gone and I will leave this to tomorrow silly. nearly @ 5000 sloc 
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.