Browse Source

Fixed nits

pull/83/head
Andrea Ciliberti 2 years ago
parent
commit
56a106fd63
  1. 46
      ctru-rs/examples/audio-filters.rs
  2. 6
      ctru-rs/src/services/ndsp/mod.rs
  3. 21
      ctru-rs/src/services/ndsp/wave.rs

46
ctru-rs/examples/audio-filters.rs

@ -41,23 +41,6 @@ fn main() {
let apt = Apt::init().expect("Couldn't obtain APT controller"); let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut()); let _console = Console::init(gfx.top_screen.borrow_mut());
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);
let channel_zero = ndsp.channel(0).unwrap();
channel_zero.set_interpolation(InterpolationType::Linear);
channel_zero.set_sample_rate(SAMPLE_RATE as f32);
channel_zero.set_format(AudioFormat::PCM16Stereo);
// Output at 100% on the first pair of left and right channels.
let mut mix: [f32; 12] = [0f32; 12];
mix[0] = 1.0;
mix[1] = 1.0;
channel_zero.set_mix(&mix);
let mut note: usize = 4; let mut note: usize = 4;
// Filters // Filters
@ -77,14 +60,30 @@ fn main() {
// effectively streaming an infinitely long sine wave. // effectively streaming an infinitely long sine wave.
let mut audio_data1 = Box::new_in([0u8; AUDIO_WAVE_LENGTH], LinearAllocator); let mut audio_data1 = Box::new_in([0u8; AUDIO_WAVE_LENGTH], LinearAllocator);
fill_buffer(&mut audio_data1[..], NOTEFREQ[4]); fill_buffer(audio_data1.as_mut_slice(), NOTEFREQ[4]);
let mut audio_data2 = Box::new_in([0u8; AUDIO_WAVE_LENGTH], LinearAllocator); let audio_data2 = audio_data1.clone();
fill_buffer(&mut audio_data2[..], NOTEFREQ[4]);
let mut wave_info1 = WaveInfo::new(audio_data1, AudioFormat::PCM16Stereo, false); let mut wave_info1 = WaveInfo::new(audio_data1, AudioFormat::PCM16Stereo, false);
let mut wave_info2 = WaveInfo::new(audio_data2, AudioFormat::PCM16Stereo, false); let mut wave_info2 = WaveInfo::new(audio_data2, AudioFormat::PCM16Stereo, false);
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);
let channel_zero = ndsp.channel(0).unwrap();
channel_zero.set_interpolation(InterpolationType::Linear);
channel_zero.set_sample_rate(SAMPLE_RATE as f32);
channel_zero.set_format(AudioFormat::PCM16Stereo);
// Output at 100% on the first pair of left and right channels.
let mut mix: [f32; 12] = [0f32; 12];
mix[0] = 1.0;
mix[1] = 1.0;
channel_zero.set_mix(&mix);
channel_zero.queue_wave(&mut wave_info1); channel_zero.queue_wave(&mut wave_info1);
channel_zero.queue_wave(&mut wave_info2); channel_zero.queue_wave(&mut wave_info2);
@ -106,7 +105,7 @@ fn main() {
if keys_down.intersects(KeyPad::KEY_DOWN) { if keys_down.intersects(KeyPad::KEY_DOWN) {
note = note.saturating_sub(1); note = note.saturating_sub(1);
} else if keys_down.intersects(KeyPad::KEY_UP) { } else if keys_down.intersects(KeyPad::KEY_UP) {
note += 1; note = std::cmp::min(note + 1, NOTEFREQ.len() - 1);;
} }
let mut update_params = false; let mut update_params = false;
@ -127,9 +126,6 @@ fn main() {
update_params = true; update_params = true;
} }
// Check for upper limit
note = std::cmp::min(note, NOTEFREQ.len() - 1);
println!("\x1b[4;1Hnote = {} Hz ", NOTEFREQ[note]); println!("\x1b[4;1Hnote = {} Hz ", NOTEFREQ[note]);
println!("\x1b[5;1Hfilter = {} ", filter_names[filter]); println!("\x1b[5;1Hfilter = {} ", filter_names[filter]);
@ -152,7 +148,7 @@ fn main() {
let status = current.get_status(); let status = current.get_status();
if let WaveStatus::Done = status { if let WaveStatus::Done = status {
fill_buffer(current.get_mut_buffer(), NOTEFREQ[note]); fill_buffer(current.get_buffer_mut(), NOTEFREQ[note]);
channel_zero.queue_wave(current); channel_zero.queue_wave(current);

6
ctru-rs/src/services/ndsp/mod.rs

@ -6,6 +6,8 @@ use crate::services::ServiceReference;
use std::sync::Mutex; use std::sync::Mutex;
const NUMBER_OF_CHANNELS: u8 = 24;
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
#[repr(u32)] #[repr(u32)]
pub enum OutputMode { pub enum OutputMode {
@ -64,7 +66,7 @@ impl Ndsp {
/// ///
/// An error will be returned if the channel id is not between 0 and 23. /// An error will be returned if the channel id is not between 0 and 23.
pub fn channel(&self, id: u8) -> crate::Result<Channel> { pub fn channel(&self, id: u8) -> crate::Result<Channel> {
if id > 23 { if id >= NUMBER_OF_CHANNELS as u8 {
return Err(crate::Error::InvalidChannel(id.into())); return Err(crate::Error::InvalidChannel(id.into()));
} }
@ -216,7 +218,7 @@ impl AudioFormat {
impl Drop for Ndsp { impl Drop for Ndsp {
fn drop(&mut self) { fn drop(&mut self) {
for i in 0..24 { for i in 0..NUMBER_OF_CHANNELS {
self.channel(i).unwrap().clear_queue(); self.channel(i).unwrap().clear_queue();
} }
} }

21
ctru-rs/src/services/ndsp/wave.rs

@ -26,8 +26,10 @@ impl WaveInfo {
audio_format: AudioFormat, audio_format: AudioFormat,
looping: bool, looping: bool,
) -> Self { ) -> Self {
let nsamples: usize = buffer.len() / (audio_format.sample_size() as usize); let sample_count: usize = buffer.len() / (audio_format.sample_size() as usize);
// Signal to the DSP processor the buffer's RAM sector.
// This step may seem delicate, but testing reports failure most of the time, while still having no repercussions on the resulting audio.
unsafe { unsafe {
let _r = ctru_sys::DSP_FlushDataCache(buffer.as_ptr().cast(), buffer.len() as u32); let _r = ctru_sys::DSP_FlushDataCache(buffer.as_ptr().cast(), buffer.len() as u32);
} }
@ -38,7 +40,7 @@ impl WaveInfo {
let raw_data = ctru_sys::ndspWaveBuf { let raw_data = ctru_sys::ndspWaveBuf {
__bindgen_anon_1: address, // Buffer data virtual address __bindgen_anon_1: address, // Buffer data virtual address
nsamples: nsamples as u32, nsamples: sample_count as u32,
adpcm_data: std::ptr::null_mut(), adpcm_data: std::ptr::null_mut(),
offset: 0, offset: 0,
looping, looping,
@ -56,7 +58,11 @@ impl WaveInfo {
} }
} }
pub fn get_mut_buffer(&mut self) -> &mut [u8] { pub fn get_buffer(&self) -> &[u8] {
&self.buffer
}
pub fn get_buffer_mut(&mut self) -> &mut [u8] {
&mut self.buffer &mut self.buffer
} }
@ -64,7 +70,7 @@ impl WaveInfo {
self.raw_data.status.try_into().unwrap() self.raw_data.status.try_into().unwrap()
} }
pub fn get_sample_amount(&self) -> u32 { pub fn get_sample_count(&self) -> u32 {
self.raw_data.nsamples self.raw_data.nsamples
} }
@ -78,7 +84,7 @@ impl WaveInfo {
} }
impl TryFrom<u8> for WaveStatus { impl TryFrom<u8> for WaveStatus {
type Error = String; type Error = &'static str;
fn try_from(value: u8) -> Result<Self, Self::Error> { fn try_from(value: u8) -> Result<Self, Self::Error> {
match value { match value {
@ -86,7 +92,7 @@ impl TryFrom<u8> for WaveStatus {
1 => Ok(Self::Queued), 1 => Ok(Self::Queued),
2 => Ok(Self::Playing), 2 => Ok(Self::Playing),
3 => Ok(Self::Done), 3 => Ok(Self::Done),
_ => Err(String::from("Invalid WaveInfo Status code")), _ => Err("Invalid WaveInfo Status code"),
} }
} }
} }
@ -105,7 +111,8 @@ impl Drop for WaveInfo {
} }
unsafe { unsafe {
// Result can't be used in any way, let's just shrug it off // Flag the buffer's RAM sector as unused
// This step has no real effect in normal applications and is skipped even by devkitPRO's own examples.
let _r = ctru_sys::DSP_InvalidateDataCache( let _r = ctru_sys::DSP_InvalidateDataCache(
self.buffer.as_ptr().cast(), self.buffer.as_ptr().cast(),
self.buffer.len().try_into().unwrap(), self.buffer.len().try_into().unwrap(),

Loading…
Cancel
Save