Browse Source

Feels like hell in here

pull/83/head
Andrea Ciliberti 2 years ago
parent
commit
44e904b0c9
  1. 68
      ctru-rs/examples/audio_filters.rs

68
ctru-rs/examples/audio_filters.rs

@ -5,7 +5,7 @@ use std::f32::consts::PI; @@ -5,7 +5,7 @@ use std::f32::consts::PI;
use ctru::linear::LinearAllocator;
use ctru::prelude::*;
use ctru::services::ndsp::{
wave::{WaveBuffer, WaveInfo},
wave::{WaveBuffer, WaveInfo, WaveStatus},
AudioFormat, InterpolationType, Ndsp, OutputMode,
};
@ -19,15 +19,20 @@ const NOTEFREQ: [u32; 7] = [220, 440, 880, 1760, 3520, 7040, 14080]; @@ -19,15 +19,20 @@ const NOTEFREQ: [u32; 7] = [220, 440, 880, 1760, 3520, 7040, 14080];
// audioBuffer is stereo PCM16
fn fill_buffer(audioData: &mut [u8], frequency: u32) {
let formatted_data: Vec<i16> = audioData.chunks_exact(2).map(|s| i16::from_le_bytes(s.try_into().unwrap())).collect();
let formatted_data = audioData.chunks_exact_mut(2);
for i in 0..audioData.len() {
// This is a simple sine wave, with a frequency of `frequency` Hz, and an amplitude 30% of maximum.
let sample: i16 = (0.3 * i16::MAX as f32 * (frequency as f32 * (2f32 * PI) * (i / SAMPLE_RATE as usize) as f32).sin()) as i16;
let mut i = 0;
for chunk in formatted_data {
// This is a simple sine wave, with a frequency of `frequency` Hz, and an amplitude 30% of maximum.
let sample: i16 = (0.3 * i16::MAX as f32 * (frequency as f32 * (2f32 * PI) * (i as f32 / SAMPLE_RATE as f32)).sin()) as i16;
// Stereo samples are interleaved: left and right channels.
formatted_data[i] = (sample << 16) | (sample & 0xffff);
}
// This operation is safe, since we are writing to a slice of exactly 16 bits
let chunk_ptr: &mut i16 = unsafe { std::mem::transmute(chunk.as_mut_ptr()) };
// Stereo samples are interleaved: left and right channels.
*chunk_ptr = (sample << 16) | (sample & 0xffff);
i += 1;
}
}
fn main() {
@ -39,19 +44,16 @@ fn main() { @@ -39,19 +44,16 @@ fn main() {
println!("libctru filtered streamed audio\n");
let audioBuffer = Box::new_in(
let mut audioBuffer = Box::new_in(
[0u8; AUDIO_WAVE_LENGTH],
LinearAllocator,
);
fill_buffer(&mut audioBuffer, NOTEFREQ[4]);
let audioBuffer1 =
WaveBuffer::new(audioBuffer, AudioFormat::PCM16Stereo).expect("Couldn't sync DSP cache");
let audioBuffer2 = audioBuffer1.clone();
fill_buffer(&mut audioBuffer[..], NOTEFREQ[4]);
let fillBlock = false;
let mut audioBuffer1 = WaveBuffer::new(audioBuffer, AudioFormat::PCM16Stereo).expect("Couldn't sync DSP cache");
let mut audioBuffer2 = audioBuffer1.clone();
let ndsp = Ndsp::init().expect("Couldn't obtain NDSP controller");
let mut ndsp = Ndsp::init().expect("Couldn't obtain NDSP controller");
// This line isn't needed since the default NDSP configuration already sets the output mode to `Stereo`
ndsp.set_output_mode(OutputMode::Stereo);
@ -63,12 +65,12 @@ fn main() { @@ -63,12 +65,12 @@ fn main() {
// Output at 100% on the first pair of left and right channels.
let mix = [0f32; 12];
let mut mix: [f32; 12] = [0f32; 12];
mix[0] = 1.0;
mix[1] = 1.0;
channel_zero.set_mix(&mix);
let note: usize = 4;
let mut note: usize = 4;
// Filters
@ -81,24 +83,23 @@ fn main() { @@ -81,24 +83,23 @@ fn main() {
"Peaking",
];
let filter = 0;
let mut filter = 0;
// We set up two wave buffers and alternate between the two,
// effectively streaming an infinitely long sine wave.
let mut buf1 = WaveInfo::new(&mut audioBuffer1, false);
let mut buf2 = WaveInfo::new(&mut audioBuffer2, false);
let mut bufs: [WaveInfo; 2] = [ WaveInfo::new(&mut audioBuffer1, false), WaveInfo::new(&mut audioBuffer2, false)];
unsafe {
channel_zero.queue_wave(&mut buf1);
channel_zero.queue_wave(&mut buf2);
};
channel_zero.queue_wave(&mut bufs[0]);
channel_zero.queue_wave(&mut bufs[1]);
println!("Press up/down to change tone frequency\n");
println!("Press left/right to change filter\n");
println!("\x1b[6;1Hnote = {} Hz ", NOTEFREQ[note]);
println!("\x1b[7;1Hfilter = {} ", filter_names[filter]);
let mut fillBlock = false;
while apt.main_loop() {
hid.scan_input();
let keys_down = hid.keys_down();
@ -124,7 +125,7 @@ fn main() { @@ -124,7 +125,7 @@ fn main() {
// Check for upper limit
note = std::cmp::max(note, NOTEFREQ.len() - 1);
let update_params = false;
let mut update_params = false;
if keys_down.contains(KeyPad::KEY_LEFT) {
filter = filter.saturating_sub(1);
if filter < 0 {
@ -151,15 +152,12 @@ fn main() { @@ -151,15 +152,12 @@ fn main() {
}
}
if waveBuf[fillBlock].status == NDSP_WBUF_DONE {
if fillBlock {
fill_buffer(buf1.get_mut_wavebuffer().get_mut_data(), NOTEFREQ[note]);
channel_zero.queue_wave(&mut buf1);
} else {
fill_buffer(buf2.get_mut_wavebuffer().get_mut_data(), NOTEFREQ[note]);
channel_zero.queue_wave(&mut buf2);
}
fillBlock = !fillBlock;
let status = bufs[fillBlock as usize].get_status();
if let WaveStatus::Done = status {
fillBlock = !fillBlock;
fill_buffer(bufs[fillBlock as usize].get_mut_wavebuffer().get_mut_data(), NOTEFREQ[note]);
channel_zero.queue_wave(&mut bufs[fillBlock as usize]);
}
// Flush and swap framebuffers

Loading…
Cancel
Save