diff --git a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs
index a52821616..73e914083 100644
--- a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs
+++ b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs
@@ -65,7 +65,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
             {
                 OpenALAudioBuffer driverBuffer = new()
                 {
-                    DriverIdentifier = buffer.DataPointer,
+                    DriverIdentifier = buffer.HostTag,
                     BufferId = AL.GenBuffer(),
                     SampleCount = GetSampleCount(buffer),
                 };
@@ -131,7 +131,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
                     return true;
                 }
 
-                return driverBuffer.DriverIdentifier != buffer.DataPointer;
+                return driverBuffer.DriverIdentifier != buffer.HostTag;
             }
         }
 
diff --git a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs
index 7a683f4ed..cf3be473e 100644
--- a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs
+++ b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs
@@ -151,7 +151,7 @@ namespace Ryujinx.Audio.Backends.SDL2
 
             if (_outputStream != 0)
             {
-                SDL2AudioBuffer driverBuffer = new(buffer.DataPointer, GetSampleCount(buffer));
+                SDL2AudioBuffer driverBuffer = new(buffer.HostTag, GetSampleCount(buffer));
 
                 _ringBuffer.Write(buffer.Data, 0, buffer.Data.Length);
 
@@ -205,7 +205,7 @@ namespace Ryujinx.Audio.Backends.SDL2
                 return true;
             }
 
-            return driverBuffer.DriverIdentifier != buffer.DataPointer;
+            return driverBuffer.DriverIdentifier != buffer.HostTag;
         }
 
         protected virtual void Dispose(bool disposing)
diff --git a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs
index 123cfd27a..b9070dc48 100644
--- a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs
+++ b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs
@@ -54,7 +54,7 @@ namespace Ryujinx.Audio.Backends.SoundIo
 
         public override void QueueBuffer(AudioBuffer buffer)
         {
-            SoundIoAudioBuffer driverBuffer = new(buffer.DataPointer, GetSampleCount(buffer));
+            SoundIoAudioBuffer driverBuffer = new(buffer.HostTag, GetSampleCount(buffer));
 
             _ringBuffer.Write(buffer.Data, 0, buffer.Data.Length);
 
@@ -90,7 +90,7 @@ namespace Ryujinx.Audio.Backends.SoundIo
                 return true;
             }
 
-            return driverBuffer.DriverIdentifier != buffer.DataPointer;
+            return driverBuffer.DriverIdentifier != buffer.HostTag;
         }
 
         private unsafe void Update(int minFrameCount, int maxFrameCount)
diff --git a/src/Ryujinx.Audio/Backends/Common/HardwareDeviceSessionOutputBase.cs b/src/Ryujinx.Audio/Backends/Common/HardwareDeviceSessionOutputBase.cs
index 5599c0827..f193d9861 100644
--- a/src/Ryujinx.Audio/Backends/Common/HardwareDeviceSessionOutputBase.cs
+++ b/src/Ryujinx.Audio/Backends/Common/HardwareDeviceSessionOutputBase.cs
@@ -40,7 +40,7 @@ namespace Ryujinx.Audio.Backends.Common
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        protected ulong GetSampleCount(int dataSize)
+        public virtual ulong GetSampleCount(int dataSize)
         {
             return (ulong)BackendHelper.GetSampleCount(RequestedSampleFormat, (int)RequestedChannelCount, dataSize);
         }
diff --git a/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs b/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs
index a9acabec9..0cfbefd1e 100644
--- a/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs
+++ b/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs
@@ -39,6 +39,11 @@ namespace Ryujinx.Audio.Backends.CompatLayer
             _realSession.PrepareToClose();
         }
 
+        public override ulong GetSampleCount(int dataSize)
+        {
+            return _realSession.GetSampleCount(dataSize);
+        }
+
         public override void QueueBuffer(AudioBuffer buffer)
         {
             SampleFormat realSampleFormat = _realSession.RequestedSampleFormat;
@@ -119,6 +124,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
             AudioBuffer fakeBuffer = new()
             {
                 BufferTag = buffer.BufferTag,
+                HostTag = buffer.HostTag,
                 DataPointer = buffer.DataPointer,
                 DataSize = (ulong)samples.Length,
             };
diff --git a/src/Ryujinx.Audio/Backends/DelayLayer/DelayLayerHardwareDeviceDriver.cs b/src/Ryujinx.Audio/Backends/DelayLayer/DelayLayerHardwareDeviceDriver.cs
new file mode 100644
index 000000000..cdd5eb8a8
--- /dev/null
+++ b/src/Ryujinx.Audio/Backends/DelayLayer/DelayLayerHardwareDeviceDriver.cs
@@ -0,0 +1,86 @@
+using Ryujinx.Audio.Backends.Common;
+using Ryujinx.Audio.Common;
+using Ryujinx.Audio.Integration;
+using Ryujinx.Memory;
+using System;
+using System.Threading;
+using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
+
+namespace Ryujinx.Audio.Backends.DelayLayer
+{
+    public class DelayLayerHardwareDeviceDriver : IHardwareDeviceDriver
+    {
+        private readonly IHardwareDeviceDriver _realDriver;
+
+        public static bool IsSupported => true;
+
+        public ulong SampleDelay48k;
+
+        public DelayLayerHardwareDeviceDriver(IHardwareDeviceDriver realDevice, ulong sampleDelay48k)
+        {
+            _realDriver = realDevice;
+            SampleDelay48k = sampleDelay48k;
+        }
+
+        public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume)
+        {
+            IHardwareDeviceSession session = _realDriver.OpenDeviceSession(direction, memoryManager, sampleFormat, sampleRate, channelCount, volume);
+
+            if (direction == Direction.Output)
+            {
+                return new DelayLayerHardwareDeviceSession(this, session as HardwareDeviceSessionOutputBase, sampleFormat, channelCount);
+            }
+
+            return session;
+        }
+
+        public ManualResetEvent GetUpdateRequiredEvent()
+        {
+            return _realDriver.GetUpdateRequiredEvent();
+        }
+
+        public ManualResetEvent GetPauseEvent()
+        {
+            return _realDriver.GetPauseEvent();
+        }
+
+        public void Dispose()
+        {
+            GC.SuppressFinalize(this);
+            Dispose(true);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposing)
+            {
+                _realDriver.Dispose();
+            }
+        }
+
+        public bool SupportsSampleRate(uint sampleRate)
+        {
+            return _realDriver.SupportsSampleRate(sampleRate);
+        }
+
+        public bool SupportsSampleFormat(SampleFormat sampleFormat)
+        {
+            return _realDriver.SupportsSampleFormat(sampleFormat);
+        }
+
+        public bool SupportsDirection(Direction direction)
+        {
+            return _realDriver.SupportsDirection(direction);
+        }
+
+        public bool SupportsChannelCount(uint channelCount)
+        {
+            return _realDriver.SupportsChannelCount(channelCount);
+        }
+
+        public IHardwareDeviceDriver GetRealDeviceDriver()
+        {
+            return _realDriver.GetRealDeviceDriver();
+        }
+    }
+}
diff --git a/src/Ryujinx.Audio/Backends/DelayLayer/DelayLayerHardwareDeviceSession.cs b/src/Ryujinx.Audio/Backends/DelayLayer/DelayLayerHardwareDeviceSession.cs
new file mode 100644
index 000000000..996a2a369
--- /dev/null
+++ b/src/Ryujinx.Audio/Backends/DelayLayer/DelayLayerHardwareDeviceSession.cs
@@ -0,0 +1,151 @@
+using Ryujinx.Audio.Backends.Common;
+using Ryujinx.Audio.Common;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Ryujinx.Audio.Backends.DelayLayer
+{
+    internal class DelayLayerHardwareDeviceSession : HardwareDeviceSessionOutputBase
+    {
+        private readonly HardwareDeviceSessionOutputBase _realSession;
+        private readonly ManualResetEvent _updateRequiredEvent;
+
+        private readonly ulong _delayTarget;
+
+        private object _sampleCountLock = new();
+
+        private List<AudioBuffer> _buffers = new();
+
+        public DelayLayerHardwareDeviceSession(DelayLayerHardwareDeviceDriver driver, HardwareDeviceSessionOutputBase realSession, SampleFormat userSampleFormat, uint userChannelCount) : base(realSession.MemoryManager, realSession.RequestedSampleFormat, realSession.RequestedSampleRate, userChannelCount)
+        {
+            _realSession = realSession;
+            _delayTarget = driver.SampleDelay48k;
+
+            _updateRequiredEvent = driver.GetUpdateRequiredEvent();
+        }
+
+        public override void Dispose()
+        {
+            _realSession.Dispose();
+        }
+
+        public override ulong GetPlayedSampleCount()
+        {
+            lock (_sampleCountLock)
+            {
+                // Update the played samples count.
+                WasBufferFullyConsumed(null);
+
+                return _playedSamplesCount;
+            }
+        }
+
+        public override float GetVolume()
+        {
+            return _realSession.GetVolume();
+        }
+
+        public override void PrepareToClose()
+        {
+            _realSession.PrepareToClose();
+        }
+
+        public override void QueueBuffer(AudioBuffer buffer)
+        {
+            _realSession.QueueBuffer(buffer);
+
+            ulong samples = GetSampleCount(buffer);
+
+            lock (_sampleCountLock)
+            {
+                _buffers.Add(buffer);
+            }
+
+            _updateRequiredEvent.Set();
+        }
+
+        public override ulong GetSampleCount(int dataSize)
+        {
+            return _realSession.GetSampleCount(dataSize);
+        }
+
+        public override void SetVolume(float volume)
+        {
+            _realSession.SetVolume(volume);
+        }
+
+        public override void Start()
+        {
+            _realSession.Start();
+        }
+
+        public override void Stop()
+        {
+            _realSession.Stop();
+        }
+
+        private ulong _playedSamplesCount = 0;
+        private int _frontIndex = -1;
+
+        public override bool WasBufferFullyConsumed(AudioBuffer buffer)
+        {
+            ulong delaySamples = 0;
+            bool isConsumed = true;
+            // True if it's in the _delayedSamples range.
+            lock (_sampleCountLock)
+            {
+                for (int i = 0; i < _buffers.Count; i++)
+                {
+                    AudioBuffer elem = _buffers[i];
+                    isConsumed = isConsumed && _realSession.WasBufferFullyConsumed(elem);
+                    ulong samples = GetSampleCount(elem);
+
+                    bool afterFront = i > _frontIndex;
+
+                    if (isConsumed)
+                    {
+                        if (_frontIndex > -1)
+                        {
+                            _frontIndex--;
+                        }
+
+                        _buffers.RemoveAt(i--);
+
+                        if (afterFront)
+                        {
+                            _playedSamplesCount += samples;
+                        }
+
+                        if (buffer == elem)
+                        {
+                            return true;
+                        }
+                    }
+                    else
+                    {
+                        if (afterFront && delaySamples < _delayTarget)
+                        {
+                            _playedSamplesCount += samples;
+                            _frontIndex = i;
+                        }
+
+                        if (buffer == elem)
+                        {
+                            return i <= _frontIndex;
+                        }
+
+                        delaySamples += samples;
+                    }
+                }
+
+                // Buffer was not queued.
+                return true;
+            }
+        }
+
+        public override bool RegisterBuffer(AudioBuffer buffer, byte[] samples)
+        {
+            return _realSession.RegisterBuffer(buffer, samples);
+        }
+    }
+}
diff --git a/src/Ryujinx.Audio/Common/AudioBuffer.cs b/src/Ryujinx.Audio/Common/AudioBuffer.cs
index 87a7d5f32..2c04e9e60 100644
--- a/src/Ryujinx.Audio/Common/AudioBuffer.cs
+++ b/src/Ryujinx.Audio/Common/AudioBuffer.cs
@@ -1,4 +1,5 @@
 using Ryujinx.Audio.Integration;
+using System.Threading;
 
 namespace Ryujinx.Audio.Common
 {
@@ -7,12 +8,19 @@ namespace Ryujinx.Audio.Common
     /// </summary>
     public class AudioBuffer
     {
+        private static ulong UniqueIdGlobal = 0;
+
         /// <summary>
-        /// Unique tag of this buffer.
+        /// Unique tag of this buffer, from the guest.
         /// </summary>
         /// <remarks>Unique per session</remarks>
         public ulong BufferTag;
 
+        /// <summary>
+        /// Globally unique ID of the buffer on the host.
+        /// </summary>
+        public ulong HostTag = Interlocked.Increment(ref UniqueIdGlobal);
+
         /// <summary>
         /// Pointer to the user samples.
         /// </summary>
diff --git a/src/Ryujinx.HLE/Switch.cs b/src/Ryujinx.HLE/Switch.cs
index ae063a47d..859eac5f5 100644
--- a/src/Ryujinx.HLE/Switch.cs
+++ b/src/Ryujinx.HLE/Switch.cs
@@ -1,4 +1,5 @@
 using Ryujinx.Audio.Backends.CompatLayer;
+using Ryujinx.Audio.Backends.DelayLayer;
 using Ryujinx.Audio.Integration;
 using Ryujinx.Common.Configuration;
 using Ryujinx.Graphics.Gpu;
@@ -46,7 +47,7 @@ namespace Ryujinx.HLE
                 : MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable;
 
 #pragma warning disable IDE0055 // Disable formatting
-            AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
+            AudioDeviceDriver = AddAudioCompatLayers(Configuration.AudioDeviceDriver);
             Memory            = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
             Gpu               = new GpuContext(Configuration.GpuRenderer);
             System            = new HOS.Horizon(this);
@@ -67,6 +68,19 @@ namespace Ryujinx.HLE
 #pragma warning restore IDE0055
         }
 
+        private IHardwareDeviceDriver AddAudioCompatLayers(IHardwareDeviceDriver driver)
+        {
+            ulong sampleDelay = 0;
+            driver = new CompatLayerHardwareDeviceDriver(driver);
+
+            if (sampleDelay > 0)
+            {
+                driver = new DelayLayerHardwareDeviceDriver(driver, sampleDelay);
+            }
+
+            return driver;
+        }
+
         public bool LoadCart(string exeFsDir, string romFsFile = null)
         {
             return Processes.LoadUnpackedNca(exeFsDir, romFsFile);