Browse Source

Example works fine, audio feels off

pull/83/head
Andrea Ciliberti 2 years ago
parent
commit
4ef261f6c2
  1. 32
      ctru-rs/examples/audio_filters.rs
  2. 6
      ctru-rs/src/services/ndsp/wave.rs

32
ctru-rs/examples/audio_filters.rs

@ -15,26 +15,24 @@ const BYTES_PER_SAMPLE: u32 = 4;
const AUDIO_WAVE_LENGTH: usize = (SAMPLES_PER_BUF * BYTES_PER_SAMPLE * 2) as usize; const AUDIO_WAVE_LENGTH: usize = (SAMPLES_PER_BUF * BYTES_PER_SAMPLE * 2) as usize;
// Note Frequencies // Note Frequencies
const NOTEFREQ: [u32; 7] = [220, 440, 880, 1760, 3520, 7040, 14080]; const NOTEFREQ: [f32; 7] = [220., 440., 880., 1760., 3520., 7040., 14080.];
// audioBuffer is stereo PCM16 // audioBuffer is stereo PCM16
fn fill_buffer(audio_data: &mut [u8], frequency: u32) { fn fill_buffer(audio_data: &mut [u8], frequency: f32) {
let formatted_data = audio_data.chunks_exact_mut(4); let formatted_data = audio_data.chunks_exact_mut(2);
let mut i = 0; let mut i = 0.;
for chunk in formatted_data { for chunk in formatted_data {
// This is a simple sine wave, with a frequency of `frequency` Hz, and an amplitude 30% of maximum. // This is a simple sine wave, with a frequency of `frequency` Hz, and an amplitude 30% of maximum.
let sample: i16 = (0.3 let sample: f32 = (frequency * (i / SAMPLE_RATE as f32) * 2. * PI).sin();
* i16::MAX as f32 let amplitude = 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 // 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()) }; let chunk_ptr: &mut i16 = unsafe { std::mem::transmute(chunk.as_mut_ptr()) };
// Stereo samples are interleaved: left and right channels. // Stereo samples are interleaved: left and right channels.
*chunk_ptr = ((sample as u32) << 16) | (sample & 0x7FFF) as u32; *chunk_ptr = (sample*amplitude) as i16;
i += 1; i += 1.;
} }
} }
@ -118,7 +116,12 @@ fn main() {
let mut update_params = false; let mut update_params = false;
if keys_down.intersects(KeyPad::KEY_LEFT) { if keys_down.intersects(KeyPad::KEY_LEFT) {
filter = filter.saturating_sub(1); let wraps;
(filter, wraps) = filter.overflowing_sub(1);
if wraps {
filter = filter_names.len() - 1;
}
update_params = true; update_params = true;
} else if keys_down.intersects(KeyPad::KEY_RIGHT) { } else if keys_down.intersects(KeyPad::KEY_RIGHT) {
@ -131,7 +134,6 @@ fn main() {
// Check for upper limit // Check for upper limit
note = std::cmp::min(note, NOTEFREQ.len() - 1); note = std::cmp::min(note, NOTEFREQ.len() - 1);
filter = std::cmp::min(filter, filter_names.len() - 1);
println!("\x1b[6;1Hnote = {} Hz ", NOTEFREQ[note]); println!("\x1b[6;1Hnote = {} Hz ", NOTEFREQ[note]);
println!("\x1b[7;1Hfilter = {} ", filter_names[filter]); println!("\x1b[7;1Hfilter = {} ", filter_names[filter]);
@ -174,7 +176,7 @@ fn main() {
} }
// Ndsp *has* to be dropped before the WaveInfos, // Ndsp *has* to be dropped before the WaveInfos,
// otherwise the status won't be flagged properly and the program will crash. // otherwise the status won't be flagged properly and the program will panic.
// TODO: find a way to get away with this using implicit functionality (rather than an explict `drop`). // TODO: Find a way to get away with this using implicitness.
drop(ndsp); drop(ndsp);
} }

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

@ -49,10 +49,8 @@ impl WaveBuffer {
let nsamples: usize = data.len() / (audio_format.sample_size() as usize); let nsamples: usize = data.len() / (audio_format.sample_size() as usize);
unsafe { unsafe {
let _r = ctru_sys::DSP_FlushDataCache( let _r =
data.as_ptr().cast(), ctru_sys::DSP_FlushDataCache(data.as_ptr().cast(), data.len().try_into().unwrap());
data.len().try_into().unwrap(),
);
} }
Ok(WaveBuffer { Ok(WaveBuffer {

Loading…
Cancel
Save