Browse Source

Readded offset and fixed misunderstanding about sample size

pull/83/head
Andrea Ciliberti 2 years ago
parent
commit
31e3542dd5
  1. 39
      ctru-rs/examples/audio_filters.rs
  2. 11
      ctru-rs/src/services/ndsp/mod.rs

39
ctru-rs/examples/audio_filters.rs

@ -11,29 +11,34 @@ use ctru::services::ndsp::{
const SAMPLE_RATE: usize = 22050; const SAMPLE_RATE: usize = 22050;
const SAMPLES_PER_BUF: usize = SAMPLE_RATE / 30; // 735 const SAMPLES_PER_BUF: usize = SAMPLE_RATE / 30; // 735
const BYTES_PER_SAMPLE: usize = 2; const BYTES_PER_SAMPLE: usize = 4;
const AUDIO_WAVE_LENGTH: usize = SAMPLES_PER_BUF * BYTES_PER_SAMPLE; const AUDIO_WAVE_LENGTH: usize = SAMPLES_PER_BUF * BYTES_PER_SAMPLE;
// Note Frequencies // Note Frequencies
const NOTEFREQ: [f32; 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: f32) { // As such, a sample is made up of 2 "Mono" samples (2 * i16 = u32), one for each channel (left and right)
let formatted_data = audio_data.chunks_exact_mut(2); fn fill_buffer(audio_data: &mut [u8], frequency: f32, offset: &mut usize) {
let formatted_data = audio_data.chunks_exact_mut(4);
let mut i = 0.; let mut i: usize = 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: f32 = (frequency / 30. * (i / SAMPLES_PER_BUF as f32) * 2. * PI).sin(); let sample: f32 = (frequency * ((i + *offset) as f32 / SAMPLE_RATE as f32) * 2. * PI).sin();
let amplitude = 0.3 * i16::MAX as f32; let amplitude = 0.3 * i16::MAX as f32;
// 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 32 bits
let chunk_ptr: &mut i16 = unsafe { std::mem::transmute(chunk.as_mut_ptr()) }; let chunk_ptr: &mut [i16; 2] = 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 * amplitude) as i16; chunk_ptr[0] = (sample * amplitude) as i16;
chunk_ptr[1] = (sample * amplitude) as i16;
i += 1.; i += 1;
} }
// Adds the SAMPLES_PER_BUF length back to the offset
*offset += i;
} }
fn main() { fn main() {
@ -77,9 +82,13 @@ fn main() {
// We set up two wave buffers and alternate between the two, // We set up two wave buffers and alternate between the two,
// effectively streaming an infinitely long sine wave. // effectively streaming an infinitely long sine wave.
let mut offset: usize = 0;
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(&mut audio_data1[..], NOTEFREQ[4], &mut offset);
let mut audio_data2 = audio_data1.clone();
let mut audio_data2 = Box::new_in([0u8; AUDIO_WAVE_LENGTH], LinearAllocator);
fill_buffer(&mut audio_data2[..], NOTEFREQ[4], &mut offset);
let mut audio_buffer1 = let mut audio_buffer1 =
WaveBuffer::new(audio_data1, AudioFormat::PCM16Stereo).expect("Couldn't sync DSP cache"); WaveBuffer::new(audio_data1, AudioFormat::PCM16Stereo).expect("Couldn't sync DSP cache");
@ -158,7 +167,11 @@ 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_wavebuffer().get_mut_data(), NOTEFREQ[note]); fill_buffer(
current.get_mut_wavebuffer().get_mut_data(),
NOTEFREQ[note],
&mut offset,
);
channel_zero.queue_wave(current); channel_zero.queue_wave(current);
altern = !altern; altern = !altern;

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

@ -220,11 +220,16 @@ impl AudioFormat {
/// 16 bit formats return 2 (bytes) /// 16 bit formats return 2 (bytes)
pub fn sample_size(self) -> u8 { pub fn sample_size(self) -> u8 {
match self { match self {
AudioFormat::PCM16Mono | AudioFormat::PCM16Stereo => 2, AudioFormat::PCM8Mono | AudioFormat::ADPCMMono => 1,
AudioFormat::PCM16Mono | AudioFormat::PCM8Stereo => 2,
AudioFormat::PCM16Stereo => 4,
AudioFormat::SurroundPreprocessed => { AudioFormat::SurroundPreprocessed => {
panic!("Can't find size for Sourround Preprocessed audio: format is under research") panic!("Can't find sample size for Sourround Preprocessed audio: format is under research")
}
// TODO: Understand what this is.
AudioFormat::FrontBypass => {
panic!("Can't find sample size for FrontBypass audio")
} }
_ => 1,
} }
} }
} }

Loading…
Cancel
Save