diff --git a/frontends/sdl/src/audio.rs b/frontends/sdl/src/audio.rs
index c5c113c0b64aa6b1b465445e5570743a9cefcefc..5284f5fae7814bf441c0eb248c990b16930a6d1d 100644
--- a/frontends/sdl/src/audio.rs
+++ b/frontends/sdl/src/audio.rs
@@ -9,13 +9,13 @@ pub struct Audio {
 }
 
 impl Audio {
-    pub fn new(sdl: &Sdl) -> Self {
+    pub fn new(sdl: &Sdl, freq: i32, channels: u8, samples: Option<u16>) -> Self {
         let audio_subsystem = sdl.audio().unwrap();
 
         let desired_spec = AudioSpecDesired {
-            freq: Some(44100),
-            channels: Some(2),
-            samples: Some(4096),
+            freq: Some(freq),
+            channels: Some(channels),
+            samples: Some(samples.unwrap_or(4096)),
         };
 
         // creates the queue that is going to be used to update the
diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs
index 89274d11720ced5bffaf1a25f68d1c44f99573ee..01e3e2cb793fbfc4201826a77a3d3dc701e4845e 100644
--- a/frontends/sdl/src/main.rs
+++ b/frontends/sdl/src/main.rs
@@ -205,7 +205,12 @@ impl Emulator {
     }
 
     pub fn start_audio(&mut self, sdl: &Sdl) {
-        self.audio = Some(Audio::new(sdl));
+        self.audio = Some(Audio::new(
+            sdl,
+            self.system.audio_sampling_rate() as i32,
+            self.system.audio_channels(),
+            None,
+        ));
     }
 
     pub fn load_rom(&mut self, path: Option<&str>) {
diff --git a/frontends/web/ts/gb.ts b/frontends/web/ts/gb.ts
index 253f83739f00aa6d65b48200de3dd2d014a2b685..f36ccc09396666772a1a992740413250e612452b 100644
--- a/frontends/web/ts/gb.ts
+++ b/frontends/web/ts/gb.ts
@@ -606,8 +606,8 @@ export class GameboyEmulator extends EmulatorBase implements Emulator {
 
     get audioSpecs(): AudioSpecs {
         return {
-            samplingRate: 44100,
-            channels: 2
+            samplingRate: this.gameBoy?.audio_sampling_rate() ?? 44100,
+            channels: this.gameBoy?.audio_channels() ?? 2
         };
     }
 
diff --git a/src/apu.rs b/src/apu.rs
index d072e606d8a053e8c91f239dc5e501d2b355bf46..367ad0ede58c7ace60b2bc7558483e32a3f63310 100644
--- a/src/apu.rs
+++ b/src/apu.rs
@@ -2,6 +2,8 @@ use std::collections::VecDeque;
 
 use crate::{gb::GameBoy, warnln};
 
+const CHANNELS: u8 = 2;
+
 const DUTY_TABLE: [[u8; 8]; 4] = [
     [0, 0, 0, 0, 0, 0, 0, 1],
     [1, 0, 0, 0, 0, 0, 0, 1],
@@ -194,9 +196,9 @@ impl Apu {
             sequencer_step: 0,
             output_timer: 0,
             audio_buffer: VecDeque::with_capacity(
-                (sampling_rate as f32 * buffer_size) as usize * 2,
+                (sampling_rate as f32 * buffer_size) as usize * CHANNELS as usize,
             ),
-            audio_buffer_max: (sampling_rate as f32 * buffer_size) as usize * 2,
+            audio_buffer_max: (sampling_rate as f32 * buffer_size) as usize * CHANNELS as usize,
             clock_freq,
         }
     }
@@ -690,38 +692,46 @@ impl Apu {
         }
     }
 
-    pub fn ch1_enabled(&mut self) -> bool {
+    pub fn ch1_out_enabled(&self) -> bool {
         self.ch1_out_enabled
     }
 
-    pub fn set_ch1_enabled(&mut self, enabled: bool) {
+    pub fn set_ch1_out_enabled(&mut self, enabled: bool) {
         self.ch1_out_enabled = enabled;
     }
 
-    pub fn ch2_enabled(&mut self) -> bool {
+    pub fn ch2_out_enabled(&self) -> bool {
         self.ch2_out_enabled
     }
 
-    pub fn set_ch2_enabled(&mut self, enabled: bool) {
+    pub fn set_ch2_out_enabled(&mut self, enabled: bool) {
         self.ch2_out_enabled = enabled;
     }
 
-    pub fn ch3_enabled(&mut self) -> bool {
+    pub fn ch3_out_enabled(&self) -> bool {
         self.ch3_out_enabled
     }
 
-    pub fn set_ch3_enabled(&mut self, enabled: bool) {
+    pub fn set_ch3_out_enabled(&mut self, enabled: bool) {
         self.ch3_out_enabled = enabled;
     }
 
-    pub fn ch4_enabled(&mut self) -> bool {
+    pub fn ch4_out_enabled(&self) -> bool {
         self.ch4_out_enabled
     }
 
-    pub fn set_ch4_enabled(&mut self, enabled: bool) {
+    pub fn set_ch4_out_enabled(&mut self, enabled: bool) {
         self.ch4_out_enabled = enabled;
     }
 
+    pub fn sampling_rate(&self) -> u16 {
+        self.sampling_rate
+    }
+
+    pub fn channels(&self) -> u8 {
+        CHANNELS
+    }
+
     pub fn audio_buffer(&self) -> &VecDeque<u8> {
         &self.audio_buffer
     }
diff --git a/src/gb.rs b/src/gb.rs
index 84191d0f22d2fcb27ed1b48a688687f5ea97e22d..130d82b3b799dcff69d79bb61b4d0b8d0685fd50 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -601,36 +601,44 @@ impl GameBoy {
         self.apu_i().ch4_output()
     }
 
-    pub fn audio_ch1_enabled(&mut self) -> bool {
-        self.apu().ch2_enabled()
+    pub fn audio_ch1_enabled(&self) -> bool {
+        self.apu_i().ch2_out_enabled()
     }
 
     pub fn set_audio_ch1_enabled(&mut self, enabled: bool) {
-        self.apu().set_ch1_enabled(enabled)
+        self.apu().set_ch1_out_enabled(enabled)
     }
 
-    pub fn audio_ch2_enabled(&mut self) -> bool {
-        self.apu().ch2_enabled()
+    pub fn audio_ch2_enabled(&self) -> bool {
+        self.apu_i().ch2_out_enabled()
     }
 
     pub fn set_audio_ch2_enabled(&mut self, enabled: bool) {
-        self.apu().set_ch2_enabled(enabled)
+        self.apu().set_ch2_out_enabled(enabled)
     }
 
-    pub fn audio_ch3_enabled(&mut self) -> bool {
-        self.apu().ch3_enabled()
+    pub fn audio_ch3_enabled(&self) -> bool {
+        self.apu_i().ch3_out_enabled()
     }
 
     pub fn set_audio_ch3_enabled(&mut self, enabled: bool) {
-        self.apu().set_ch3_enabled(enabled)
+        self.apu().set_ch3_out_enabled(enabled)
     }
 
-    pub fn audio_ch4_enabled(&mut self) -> bool {
-        self.apu().ch4_enabled()
+    pub fn audio_ch4_enabled(&self) -> bool {
+        self.apu_i().ch4_out_enabled()
     }
 
     pub fn set_audio_ch4_enabled(&mut self, enabled: bool) {
-        self.apu().set_ch4_enabled(enabled)
+        self.apu().set_ch4_out_enabled(enabled)
+    }
+
+    pub fn audio_sampling_rate(&self) -> u16 {
+        self.apu_i().sampling_rate()
+    }
+
+    pub fn audio_channels(&self) -> u8 {
+        self.apu_i().channels()
     }
 
     pub fn cartridge_eager(&mut self) -> Cartridge {