diff --git a/ctru-rs/examples/audio_filters.rs b/ctru-rs/examples/audio_filters.rs index 8fc2124..5625d8f 100644 --- a/ctru-rs/examples/audio_filters.rs +++ b/ctru-rs/examples/audio_filters.rs @@ -9,10 +9,10 @@ use ctru::services::ndsp::{ AudioFormat, InterpolationType, Ndsp, OutputMode, }; -const SAMPLE_RATE: u32 = 22050; -const SAMPLES_PER_BUF: u32 = SAMPLE_RATE / 30; // 735 -const BYTES_PER_SAMPLE: u32 = 4; -const AUDIO_WAVE_LENGTH: usize = (SAMPLES_PER_BUF * BYTES_PER_SAMPLE * 2) as usize; +const SAMPLE_RATE: usize = 22050; +const SAMPLES_PER_BUF: usize = SAMPLE_RATE / 30; // 735 +const BYTES_PER_SAMPLE: usize = 2; +const AUDIO_WAVE_LENGTH: usize = SAMPLES_PER_BUF * BYTES_PER_SAMPLE; // Note Frequencies const NOTEFREQ: [f32; 7] = [220., 440., 880., 1760., 3520., 7040., 14080.]; @@ -24,7 +24,7 @@ fn fill_buffer(audio_data: &mut [u8], frequency: f32) { 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: f32 = (frequency * (i / SAMPLE_RATE as f32) * 2. * PI).sin(); + let sample: f32 = (frequency / 30. * (i / SAMPLES_PER_BUF as f32) * 2. * PI).sin(); let amplitude = 0.3 * i16::MAX as f32; // This operation is safe, since we are writing to a slice of exactly 16 bits @@ -43,8 +43,6 @@ fn main() { let apt = Apt::init().expect("Couldn't obtain APT controller"); let _console = Console::init(gfx.top_screen.borrow_mut()); - println!("libctru filtered streamed audio\n"); - 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` @@ -75,11 +73,10 @@ fn main() { "Peaking", ]; - let mut filter = 0; + let mut filter: usize = 0; // We set up two wave buffers and alternate between the two, // effectively streaming an infinitely long sine wave. - let mut audio_data1 = Box::new_in([0u8; AUDIO_WAVE_LENGTH], LinearAllocator); fill_buffer(&mut audio_data1[..], NOTEFREQ[4]); let mut audio_data2 = audio_data1.clone(); @@ -95,10 +92,10 @@ fn main() { channel_zero.queue_wave(&mut wave_info1); channel_zero.queue_wave(&mut wave_info2); - 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]); + println!("\x1b[1;1HPress up/down to change tone frequency"); + println!("\x1b[2;1HPress left/right to change filter"); + println!("\x1b[4;1Hnote = {} Hz ", NOTEFREQ[note]); + println!("\x1b[5;1Hfilter = {} ", filter_names[filter]); let mut altern = true; // true is wave_info1, false is wave_info2 @@ -137,8 +134,8 @@ fn main() { // Check for upper limit note = std::cmp::min(note, NOTEFREQ.len() - 1); - println!("\x1b[6;1Hnote = {} Hz ", NOTEFREQ[note]); - println!("\x1b[7;1Hfilter = {} ", filter_names[filter]); + println!("\x1b[4;1Hnote = {} Hz ", NOTEFREQ[note]); + println!("\x1b[5;1Hfilter = {} ", filter_names[filter]); if update_params { match filter { diff --git a/ctru-rs/src/services/ndsp/mod.rs b/ctru-rs/src/services/ndsp/mod.rs index 7a60242..eb2ff80 100644 --- a/ctru-rs/src/services/ndsp/mod.rs +++ b/ctru-rs/src/services/ndsp/mod.rs @@ -213,6 +213,22 @@ impl Channel { } } +impl AudioFormat { + /// Returns the amount of bytes needed to store one sample + /// Eg. + /// 8 bit formats return 1 (byte) + /// 16 bit formats return 2 (bytes) + pub fn sample_size(self) -> u8 { + match self { + AudioFormat::PCM16Mono | AudioFormat::PCM16Stereo => 2, + AudioFormat::SurroundPreprocessed => { + panic!("Can't find size for Sourround Preprocessed audio: format is under research") + } + _ => 1, + } + } +} + impl Drop for Ndsp { fn drop(&mut self) { for i in 0..24 { diff --git a/ctru-rs/src/services/ndsp/wave.rs b/ctru-rs/src/services/ndsp/wave.rs index 50a868a..8c34dc6 100644 --- a/ctru-rs/src/services/ndsp/wave.rs +++ b/ctru-rs/src/services/ndsp/wave.rs @@ -30,29 +30,12 @@ pub enum WaveStatus { Done = ctru_sys::NDSP_WBUF_DONE as u8, } -impl AudioFormat { - /// Returns the amount of bytes needed to store one sample - /// Eg. - /// 8 bit formats return 1 (byte) - /// 16 bit formats return 2 (bytes) - pub fn sample_size(self) -> u8 { - match self { - AudioFormat::PCM16Mono | AudioFormat::PCM16Stereo => 2, - AudioFormat::SurroundPreprocessed => { - panic!("Can't find size for Sourround Preprocessed audio: format is under research") - } - _ => 1, - } - } -} - impl WaveBuffer { pub fn new(data: Box<[u8], LinearAllocator>, audio_format: AudioFormat) -> crate::Result { let nsamples: usize = data.len() / (audio_format.sample_size() as usize); unsafe { - let _r = - ctru_sys::DSP_FlushDataCache(data.as_ptr().cast(), data.len().try_into().unwrap()); + let _r = ctru_sys::DSP_FlushDataCache(data.as_ptr().cast(), data.len() as u32); } Ok(Self { @@ -83,7 +66,7 @@ impl<'b> WaveInfo<'b> { let raw_data = ctru_sys::ndspWaveBuf { __bindgen_anon_1: address, // Buffer data virtual address - nsamples: buffer.nsamples.try_into().unwrap(), + nsamples: buffer.get_sample_amount() as u32, adpcm_data: std::ptr::null_mut(), offset: 0, looping,