diff --git a/src/apu.rs b/src/apu.rs
index 1c55c7befa146cefec123ea505c2a9023bcd18b3..66b6c4bb61966dbda8bb6299ec0a267b457fa6bf 100644
--- a/src/apu.rs
+++ b/src/apu.rs
@@ -1,3 +1,5 @@
+use std::collections::VecDeque;
+
 use crate::warnln;
 
 const DUTY_TABLE: [[u8; 8]; 4] = [
@@ -59,15 +61,16 @@ pub struct Apu {
 
     wave_ram: [u8; 16],
 
-    sampling_frequency: u16,
+    sampling_rate: u16,
     sequencer: u16,
     sequencer_step: u8,
     output_timer: u16,
-    audio_buffer: Vec<u8>,
+    audio_buffer: VecDeque<u8>,
+    audio_buffer_max: usize,
 }
 
 impl Apu {
-    pub fn new() -> Self {
+    pub fn new(sampling_rate: u16) -> Self {
         Self {
             ch1_timer: 0,
             ch1_sequence: 0,
@@ -113,14 +116,15 @@ impl Apu {
 
             wave_ram: [0u8; 16],
 
-            sampling_frequency: 44100,
+            sampling_rate: sampling_rate,
 
             /// Internal sequencer counter that runs at 512Hz
             /// used for the activation of the tick actions.
             sequencer: 0,
             sequencer_step: 0,
             output_timer: 0,
-            audio_buffer: Vec::new(),
+            audio_buffer: VecDeque::with_capacity(sampling_rate as usize),
+            audio_buffer_max: sampling_rate as usize,
         }
     }
 
@@ -232,11 +236,11 @@ impl Apu {
         self.ch1_output + self.ch2_output + self.ch3_output
     }
 
-    pub fn audio_buffer(&self) -> &Vec<u8> {
+    pub fn audio_buffer(&self) -> &VecDeque<u8> {
         &self.audio_buffer
     }
 
-    pub fn audio_buffer_mut(&mut self) -> &mut Vec<u8> {
+    pub fn audio_buffer_mut(&mut self) -> &mut VecDeque<u8> {
         &mut self.audio_buffer
     }
 
@@ -282,10 +286,18 @@ impl Apu {
 
         self.output_timer = self.output_timer.saturating_sub(1);
         if self.output_timer == 0 {
-            self.audio_buffer.push(self.output());
+            // verifies if we've reached the maximum allowed size for the
+            // audio buffer and if that's the case an item is removed from
+            // the buffer (avoiding overflow) and then then the new audio
+            // volume item is added to the queue
+            if self.audio_buffer.len() >= self.audio_buffer_max {
+                self.audio_buffer.pop_front();
+            }
+            self.audio_buffer.push_back(self.output());
+
             // @TODO the CPU clock is hardcoded here, we must handle situations
             // where there's some kind of overclock
-            self.output_timer = (4194304.0 / self.sampling_frequency as f32) as u16;
+            self.output_timer = (4194304.0 / self.sampling_rate as f32) as u16;
         }
     }
 
@@ -480,6 +492,6 @@ impl Apu {
 
 impl Default for Apu {
     fn default() -> Self {
-        Self::new()
+        Self::new(44100)
     }
 }
diff --git a/src/gb.rs b/src/gb.rs
index 7cbafab922b5774fe8ab867124cf54966a23fd5d..26103de99295869fc0ffa15fa0468a31ad639496 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -11,6 +11,8 @@ use crate::{
     util::read_file,
 };
 
+use std::collections::VecDeque;
+
 #[cfg(feature = "wasm")]
 use wasm_bindgen::prelude::*;
 
@@ -55,7 +57,7 @@ pub struct Registers {
 
 pub trait AudioProvider {
     fn audio_output(&self) -> u8;
-    fn audio_buffer(&self) -> &Vec<u8>;
+    fn audio_buffer(&self) -> &VecDeque<u8>;
     fn clear_audio_buffer(&mut self);
 }
 
@@ -63,10 +65,10 @@ pub trait AudioProvider {
 impl GameBoy {
     #[cfg_attr(feature = "wasm", wasm_bindgen(constructor))]
     pub fn new() -> Self {
-        let ppu = Ppu::new();
-        let apu = Apu::new();
-        let pad = Pad::new();
-        let timer = Timer::new();
+        let ppu = Ppu::default();
+        let apu = Apu::default();
+        let pad = Pad::default();
+        let timer = Timer::default();
         let mmu = Mmu::new(ppu, apu, pad, timer);
         let cpu = Cpu::new(mmu);
         Self { cpu }
@@ -165,7 +167,7 @@ impl GameBoy {
     }
 
     pub fn audio_buffer_eager(&mut self, clear: bool) -> Vec<u8> {
-        let buffer = self.audio_buffer().to_vec();
+        let buffer = Vec::from(self.audio_buffer().clone());
         if clear {
             self.clear_audio_buffer();
         }
@@ -287,7 +289,7 @@ impl GameBoy {
         &(self.ppu().frame_buffer)
     }
 
-    pub fn audio_buffer(&mut self) -> &Vec<u8> {
+    pub fn audio_buffer(&mut self) -> &VecDeque<u8> {
         self.apu().audio_buffer()
     }
 
@@ -399,7 +401,7 @@ impl AudioProvider for GameBoy {
         self.apu_i().output()
     }
 
-    fn audio_buffer(&self) -> &Vec<u8> {
+    fn audio_buffer(&self) -> &VecDeque<u8> {
         self.apu_i().audio_buffer()
     }