From a319686e4b3c283aced907a4f13204ecfef05959 Mon Sep 17 00:00:00 2001
From: Andrea Ciliberti <meziu210@icloud.com>
Date: Sat, 31 Dec 2022 12:19:00 +0100
Subject: [PATCH] Expanded InvalidChannel error and fixed types

---
 ctru-rs/examples/audio_filters.rs |  2 +-
 ctru-rs/src/error.rs              |  6 ++++--
 ctru-rs/src/services/ndsp.rs      | 11 ++++++-----
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/ctru-rs/examples/audio_filters.rs b/ctru-rs/examples/audio_filters.rs
index d124497..e2a1daa 100644
--- a/ctru-rs/examples/audio_filters.rs
+++ b/ctru-rs/examples/audio_filters.rs
@@ -51,7 +51,7 @@ fn main() {
     // 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);
+    let channel_zero = ndsp.channel(0).unwrap();
     channel_zero.set_interpolation(InterpolationType::Linear);
     channel_zero.set_sample_rate(SAMPLERATE);
     channel_zero.set_format(NDSP_FORMAT_STEREO_PCM16);
diff --git a/ctru-rs/src/error.rs b/ctru-rs/src/error.rs
index 0c3a9bf..1d58c45 100644
--- a/ctru-rs/src/error.rs
+++ b/ctru-rs/src/error.rs
@@ -51,7 +51,7 @@ pub enum Error {
     Libc(String),
     ServiceAlreadyActive,
     OutputAlreadyRedirected,
-    InvalidChannel,
+    InvalidChannel(i32),
 }
 
 impl Error {
@@ -98,6 +98,7 @@ impl fmt::Debug for Error {
             Self::Libc(err) => f.debug_tuple("Libc").field(err).finish(),
             Self::ServiceAlreadyActive => f.debug_tuple("ServiceAlreadyActive").finish(),
             Self::OutputAlreadyRedirected => f.debug_tuple("OutputAlreadyRedirected").finish(),
+            Self::InvalidChannel(id) => f.debug_tuple("InvalidChannel").field(id).finish(),
         }
     }
 }
@@ -113,7 +114,8 @@ impl fmt::Display for Error {
             Self::ServiceAlreadyActive => write!(f, "Service already active"),
             Self::OutputAlreadyRedirected => {
                 write!(f, "output streams are already redirected to 3dslink")
-            }
+            },
+            Self::InvalidChannel(id) => write!(f, "Audio Channel with id {id} doesn't exist")
         }
     }
 }
diff --git a/ctru-rs/src/services/ndsp.rs b/ctru-rs/src/services/ndsp.rs
index 9bbedfa..71f8c48 100644
--- a/ctru-rs/src/services/ndsp.rs
+++ b/ctru-rs/src/services/ndsp.rs
@@ -68,7 +68,7 @@ impl Ndsp {
     /// An error will be returned if the channel id is not between 0 and 23.
     pub fn channel(&self, id: u8) -> crate::Result<Channel> {
         if id > 23 {
-            return Err(crate::Error::InvalidChannel);
+            return Err(crate::Error::InvalidChannel(id.into()));
         }
         
         Ok(Channel { id: id.into() })
@@ -132,7 +132,7 @@ impl Channel {
 
     /// Set the channel's volume mix.
     /// Docs about the buffer usage: https://libctru.devkitpro.org/channel_8h.html#a30eb26f1972cc3ec28370263796c0444
-    pub fn set_mix(&self, mix: &[f32; 12]) {
+    pub fn set_mix(&self, mix: &mut [f32; 12]) {
         unsafe { ctru_sys::ndspChnSetMix(self.id, mix.as_mut_ptr()) }
     }
 
@@ -162,7 +162,7 @@ impl Channel {
     // Sadly `libctru` lacks the infrastructure to make runtime checks on the queued objects, like callbacks and iterators.
     // Also, in most cases the memory is still accessible even after a `free`, so it may not be a problem to the average user.
     // This is still a big "hole" in the Rust wrapper. Upstream changes to `libctru` would be my go-to way to solve this issue.
-    pub unsafe fn queue_wave(&self, buffer: WaveInfo) {
+    pub unsafe fn queue_wave(&self, mut buffer: WaveInfo) {
         unsafe { ctru_sys::ndspChnWaveBufAdd(self.id, &mut buffer.raw_data) };
     }
 }
@@ -230,7 +230,7 @@ impl<'b> WaveInfo<'b> {
         Self { buffer, raw_data }
     }
 
-    pub fn get_mut_wavebuffer(&mut self) -> &'b mut WaveBuffer {
+    pub fn get_mut_wavebuffer(&'b mut self) -> &'b mut WaveBuffer {
         &mut self.buffer
     }
 }
@@ -246,7 +246,8 @@ impl Drop for Ndsp {
 impl Drop for WaveBuffer {
     fn drop(&mut self) {
         unsafe {
-            ctru_sys::DSP_InvalidateDataCache(self.data.as_ptr().cast(), self.data.len().try_into().unwrap());
+            // Result can't be used in any way, let's just shrug it off
+            let _r = ctru_sys::DSP_InvalidateDataCache(self.data.as_ptr().cast(), self.data.len().try_into().unwrap());
         }
     }
 }