From a6ec9b8525ec397240928489992769932ff440e7 Mon Sep 17 00:00:00 2001 From: Andrea Ciliberti Date: Tue, 3 Jan 2023 00:15:40 +0100 Subject: [PATCH] Filter example compiles, still WIP --- ctru-rs/examples/audio_filters.rs | 80 +++++++++++++++++-------------- ctru-rs/src/services/ndsp/mod.rs | 20 ++++++-- ctru-rs/src/services/ndsp/wave.rs | 4 +- 3 files changed, 63 insertions(+), 41 deletions(-) diff --git a/ctru-rs/examples/audio_filters.rs b/ctru-rs/examples/audio_filters.rs index 437ba77..0bfb466 100644 --- a/ctru-rs/examples/audio_filters.rs +++ b/ctru-rs/examples/audio_filters.rs @@ -18,21 +18,24 @@ const AUDIO_WAVE_LENGTH: usize = (SAMPLES_PER_BUF * BYTES_PER_SAMPLE * 2) as usi 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 = audioData.chunks_exact_mut(2); - - 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; - - // 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 fill_buffer(audio_data: &mut [u8], frequency: u32) { + let formatted_data = audio_data.chunks_exact_mut(4); + + 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; + + // This operation is safe, since we are writing to a slice of exactly 16 bits + let chunk_ptr: &mut u32 = unsafe { std::mem::transmute(chunk.as_mut_ptr()) }; + // Stereo samples are interleaved: left and right channels. + *chunk_ptr = ((sample as u32) << 16) | (sample & 0x7FFF) as u32; + + i += 1; + } } fn main() { @@ -44,14 +47,12 @@ fn main() { println!("libctru filtered streamed audio\n"); - let mut audioBuffer = Box::new_in( - [0u8; AUDIO_WAVE_LENGTH], - LinearAllocator, - ); - fill_buffer(&mut audioBuffer[..], NOTEFREQ[4]); + let mut audio_data = Box::new_in([0u8; AUDIO_WAVE_LENGTH], LinearAllocator); + fill_buffer(&mut audio_data[..], NOTEFREQ[4]); - let mut audioBuffer1 = WaveBuffer::new(audioBuffer, AudioFormat::PCM16Stereo).expect("Couldn't sync DSP cache"); - let mut audioBuffer2 = audioBuffer1.clone(); + let mut audio_buffer1 = + WaveBuffer::new(audio_data, AudioFormat::PCM16Stereo).expect("Couldn't sync DSP cache"); + let mut audio_buffer2 = audio_buffer1.clone(); let mut ndsp = Ndsp::init().expect("Couldn't obtain NDSP controller"); @@ -88,17 +89,18 @@ fn main() { // We set up two wave buffers and alternate between the two, // effectively streaming an infinitely long sine wave. - let mut bufs: [WaveInfo; 2] = [ WaveInfo::new(&mut audioBuffer1, false), WaveInfo::new(&mut audioBuffer2, false)]; + let mut wave_info1 = WaveInfo::new(&mut audio_buffer1, false); + let mut wave_info2 = WaveInfo::new(&mut audio_buffer2, false); - channel_zero.queue_wave(&mut bufs[0]); - channel_zero.queue_wave(&mut bufs[1]); + 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]); - let mut fillBlock = false; + let mut altern = true; // true is wave_info1, false is wave_info2 while apt.main_loop() { hid.scan_input(); @@ -110,9 +112,7 @@ fn main() { if keys_down.contains(KeyPad::KEY_DOWN) { note = note.saturating_sub(1); - if note < 0 { - note = NOTEFREQ.len() - 1; - } + println!("\x1b[6;1Hnote = {} Hz ", NOTEFREQ[note]); } else if keys_down.contains(KeyPad::KEY_UP) { note += 1; @@ -128,9 +128,7 @@ fn main() { let mut update_params = false; if keys_down.contains(KeyPad::KEY_LEFT) { filter = filter.saturating_sub(1); - if filter < 0 { - filter = filter_names.len() - 1; - } + update_params = true; } else if keys_down.contains(KeyPad::KEY_LEFT) { filter += 1; @@ -152,12 +150,22 @@ fn main() { } } - let status = bufs[fillBlock as usize].get_status(); + let current: Option<&mut WaveInfo>; + + if altern { + current = Some(&mut wave_info1); + } else { + current = Some(&mut wave_info2); + } + + let current = current.unwrap(); + + let status = current.get_status(); if let WaveStatus::Done = status { - fillBlock = !fillBlock; + altern = !altern; - fill_buffer(bufs[fillBlock as usize].get_mut_wavebuffer().get_mut_data(), NOTEFREQ[note]); - channel_zero.queue_wave(&mut bufs[fillBlock as usize]); + fill_buffer(current.get_mut_wavebuffer().get_mut_data(), NOTEFREQ[note]); + channel_zero.queue_wave(current); } // Flush and swap framebuffers diff --git a/ctru-rs/src/services/ndsp/mod.rs b/ctru-rs/src/services/ndsp/mod.rs index 01947f2..a1ff70f 100644 --- a/ctru-rs/src/services/ndsp/mod.rs +++ b/ctru-rs/src/services/ndsp/mod.rs @@ -152,7 +152,9 @@ impl Channel { } pub fn iir_biquad_set_params_high_pass_filter(&self, cut_off_freq: f32, quality: f32) { - unsafe { ctru_sys::ndspChnIirBiquadSetParamsHighPassFilter(self.id, cut_off_freq, quality) }; + unsafe { + ctru_sys::ndspChnIirBiquadSetParamsHighPassFilter(self.id, cut_off_freq, quality) + }; } pub fn iir_biquad_set_params_low_pass_filter(&self, cut_off_freq: f32, quality: f32) { @@ -167,8 +169,20 @@ impl Channel { unsafe { ctru_sys::ndspChnIirBiquadSetParamsBandPassFilter(self.id, mid_freq, quality) }; } - pub fn iir_biquad_set_params_peaking_equalizer(&self, central_freq: f32, quality: f32, gain: f32) { - unsafe { ctru_sys::ndspChnIirBiquadSetParamsPeakingEqualizer(self.id, central_freq, quality, gain) }; + pub fn iir_biquad_set_params_peaking_equalizer( + &self, + central_freq: f32, + quality: f32, + gain: f32, + ) { + unsafe { + ctru_sys::ndspChnIirBiquadSetParamsPeakingEqualizer( + self.id, + central_freq, + quality, + gain, + ) + }; } } diff --git a/ctru-rs/src/services/ndsp/wave.rs b/ctru-rs/src/services/ndsp/wave.rs index 9c5c9ff..84ff55e 100644 --- a/ctru-rs/src/services/ndsp/wave.rs +++ b/ctru-rs/src/services/ndsp/wave.rs @@ -63,7 +63,7 @@ impl WaveBuffer { }) } - pub fn get_mut_data(&mut self) -> &mut Box<[u8], LinearAllocator> { + pub fn get_mut_data(&mut self) -> &mut [u8] { &mut self.data } @@ -97,7 +97,7 @@ impl<'b> WaveInfo<'b> { Self { buffer, raw_data } } - pub fn get_mut_wavebuffer(&'b mut self) -> &'b mut WaveBuffer { + pub fn get_mut_wavebuffer(&mut self) -> &mut WaveBuffer { &mut self.buffer }