diff --git a/src/AdvancedADC.cpp b/src/AdvancedADC.cpp
index b3b889e..7c5b26e 100644
--- a/src/AdvancedADC.cpp
+++ b/src/AdvancedADC.cpp
@@ -30,7 +30,7 @@ struct adc_descr_t {
     IRQn_Type dma_irqn;
     TIM_HandleTypeDef tim;
     uint32_t  tim_trig;
-    DMABufferPool<Sample> *pool;
+    DMAPool<Sample> *pool;
     DMABuffer<Sample> *dmabuf[2];
 };
 
@@ -124,7 +124,7 @@ DMABuffer<Sample> &AdvancedADC::read() {
         while (!available()) {
             __WFI();
         }
-        return *descr->pool->dequeue();
+        return *descr->pool->alloc(DMA_BUFFER_READ);
     }
     return NULLBUF;
 }
@@ -200,14 +200,14 @@ int AdvancedADC::begin(uint32_t resolution, uint32_t sample_rate, size_t n_sampl
     }
 
     // Allocate DMA buffer pool.
-    descr->pool = new DMABufferPool<Sample>(n_samples, n_channels, n_buffers);
+    descr->pool = new DMAPool<Sample>(n_samples, n_channels, n_buffers);
     if (descr->pool == nullptr) {
         return 0;
     }
 
     // Allocate the two DMA buffers used for double buffering.
-    descr->dmabuf[0] = descr->pool->allocate();
-    descr->dmabuf[1] = descr->pool->allocate();
+    descr->dmabuf[0] = descr->pool->alloc(DMA_BUFFER_WRITE);
+    descr->dmabuf[1] = descr->pool->alloc(DMA_BUFFER_WRITE);
 
     // Init and config DMA.
     if (hal_dma_config(&descr->dma, descr->dma_irqn, DMA_PERIPH_TO_MEMORY) < 0) {
@@ -325,19 +325,16 @@ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *adc) {
     if (descr->pool->writable()) {
         // Make sure any cached data is discarded.
         descr->dmabuf[ct]->invalidate();
-
         // Move current DMA buffer to ready queue.
-        descr->pool->enqueue(descr->dmabuf[ct]);
-
+        descr->dmabuf[ct]->release();
         // Allocate a new free buffer.
-        descr->dmabuf[ct] = descr->pool->allocate();
-
+        descr->dmabuf[ct] = descr->pool->alloc(DMA_BUFFER_WRITE);
         // Currently, all multi-channel buffers are interleaved.
         if (descr->dmabuf[ct]->channels() > 1) {
-            descr->dmabuf[ct]->setflags(DMA_BUFFER_INTRLVD);
+            descr->dmabuf[ct]->set_flags(DMA_BUFFER_INTRLVD);
         }
     } else {
-        descr->dmabuf[ct]->setflags(DMA_BUFFER_DISCONT);
+        descr->dmabuf[ct]->set_flags(DMA_BUFFER_DISCONT);
     }
 
     // Update the next DMA target pointer.
diff --git a/src/AdvancedADC.h b/src/AdvancedADC.h
index 27a466a..a290d4d 100644
--- a/src/AdvancedADC.h
+++ b/src/AdvancedADC.h
@@ -17,12 +17,10 @@
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#include <array>
-#include "DMABuffer.h"
-#include "AdvancedAnalog.h"
+#ifndef __ADVANCED_ADC_H__
+#define __ADVANCED_ADC_H__
 
-#ifndef ARDUINO_ADVANCED_ADC_H_
-#define ARDUINO_ADVANCED_ADC_H_
+#include "AdvancedAnalog.h"
 
 struct adc_descr_t;
 
@@ -96,4 +94,4 @@ class AdvancedADCDual {
         int stop();
 };
 
-#endif /* ARDUINO_ADVANCED_ADC_H_ */
+#endif // __ADVANCED_ADC_H__
diff --git a/src/AdvancedAnalog.h b/src/AdvancedAnalog.h
index d2c46d6..0ffcb2c 100644
--- a/src/AdvancedAnalog.h
+++ b/src/AdvancedAnalog.h
@@ -21,7 +21,7 @@
 #define __ADVANCED_ANALOG_H__
 
 #include "Arduino.h"
-#include "DMABuffer.h"
+#include "api/DMAPool.h"
 #include "pinDefinitions.h"
 
 enum {
diff --git a/src/AdvancedDAC.cpp b/src/AdvancedDAC.cpp
index 54684dd..bcd5967 100644
--- a/src/AdvancedDAC.cpp
+++ b/src/AdvancedDAC.cpp
@@ -30,7 +30,7 @@ struct dac_descr_t {
     uint32_t tim_trig;
     uint32_t resolution;
     uint32_t dmaudr_flag;
-    DMABufferPool<Sample> *pool;
+    DMAPool<Sample> *pool;
     DMABuffer<Sample> *dmabuf[2];
 };
 
@@ -114,7 +114,7 @@ DMABuffer<Sample> &AdvancedDAC::dequeue() {
         while (!available()) {
             __WFI();
         }
-        return *descr->pool->allocate();
+        return *descr->pool->alloc(DMA_BUFFER_WRITE);
     }
     return NULLBUF;
 }
@@ -128,11 +128,11 @@ void AdvancedDAC::write(DMABuffer<Sample> &dmabuf) {
 
     // Make sure any cached data is flushed.
     dmabuf.flush();
-    descr->pool->enqueue(&dmabuf);
+    dmabuf.release();
 
     if (descr->dmabuf[0] == nullptr && (++buf_count % 3) == 0) {
-        descr->dmabuf[0] = descr->pool->dequeue();
-        descr->dmabuf[1] = descr->pool->dequeue();
+        descr->dmabuf[0] = descr->pool->alloc(DMA_BUFFER_READ);
+        descr->dmabuf[1] = descr->pool->alloc(DMA_BUFFER_READ);
 
         // Start DAC DMA.
         HAL_DAC_Start_DMA(descr->dac, descr->channel,
@@ -167,7 +167,7 @@ int AdvancedDAC::begin(uint32_t resolution, uint32_t frequency, size_t n_samples
     }
 
     // Allocate DMA buffer pool.
-    descr->pool = new DMABufferPool<Sample>(n_samples, n_channels, n_buffers);
+    descr->pool = new DMAPool<Sample>(n_samples, n_channels, n_buffers);
     if (descr->pool == nullptr) {
         descr = nullptr;
         return 0;
@@ -226,7 +226,7 @@ void DAC_DMAConvCplt(DMA_HandleTypeDef *dma, uint32_t channel) {
         // NOTE: CT bit is inverted, to get the DMA buffer that's Not currently in use.
         size_t ct = ! hal_dma_get_ct(dma);
         descr->dmabuf[ct]->release();
-        descr->dmabuf[ct] = descr->pool->dequeue();
+        descr->dmabuf[ct] = descr->pool->alloc(DMA_BUFFER_READ);
         hal_dma_update_memory(dma, descr->dmabuf[ct]->data());
     } else {
         dac_descr_deinit(descr, false);
diff --git a/src/AdvancedDAC.h b/src/AdvancedDAC.h
index da199a6..d1084a6 100644
--- a/src/AdvancedDAC.h
+++ b/src/AdvancedDAC.h
@@ -17,12 +17,10 @@
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#include <vector>
-#include "DMABuffer.h"
-#include "AdvancedAnalog.h"
+#ifndef __ADVANCED_DAC_H__
+#define __ADVANCED_DAC_H__
 
-#ifndef ARDUINO_ADVANCED_DAC_H_
-#define ARDUINO_ADVANCED_DAC_H_
+#include "AdvancedAnalog.h"
 
 struct dac_descr_t;
 
@@ -52,4 +50,4 @@ class AdvancedDAC {
         int frequency(uint32_t const frequency);
 };
 
-#endif /* ARDUINO_ADVANCED_DAC_H_ */
+#endif // __ADVANCED_DAC_H__
diff --git a/src/AdvancedI2S.cpp b/src/AdvancedI2S.cpp
index b0d0c98..812e035 100644
--- a/src/AdvancedI2S.cpp
+++ b/src/AdvancedI2S.cpp
@@ -25,11 +25,11 @@ struct i2s_descr_t {
     I2S_HandleTypeDef i2s;
     DMA_HandleTypeDef dmatx;
     IRQn_Type dmatx_irqn;
-    DMABufferPool<Sample> *dmatx_pool;
+    DMAPool<Sample> *dmatx_pool;
     DMABuffer<Sample> *dmatx_buf[2];
     DMA_HandleTypeDef dmarx;
     IRQn_Type dmarx_irqn;
-    DMABufferPool<Sample> *dmarx_pool;
+    DMAPool<Sample> *dmarx_pool;
     DMABuffer<Sample> *dmarx_buf[2];
 };
 
@@ -154,16 +154,16 @@ static int i2s_start_dma_transfer(i2s_descr_t *descr, i2s_mode_t i2s_mode) {
 
     if (i2s_mode & AN_I2S_MODE_IN) {
         // Start I2S DMA.
-        descr->dmarx_buf[0] = descr->dmarx_pool->allocate();
-        descr->dmarx_buf[1] = descr->dmarx_pool->allocate();
+        descr->dmarx_buf[0] = descr->dmarx_pool->alloc(DMA_BUFFER_WRITE);
+        descr->dmarx_buf[1] = descr->dmarx_pool->alloc(DMA_BUFFER_WRITE);
         rx_buf = (uint16_t *) descr->dmarx_buf[0]->data();
         buf_size = descr->dmarx_buf[0]->size();
         HAL_NVIC_DisableIRQ(descr->dmarx_irqn);
     }
 
     if (i2s_mode & AN_I2S_MODE_OUT) {
-        descr->dmatx_buf[0] = descr->dmatx_pool->dequeue();
-        descr->dmatx_buf[1] = descr->dmatx_pool->dequeue();
+        descr->dmatx_buf[0] = descr->dmatx_pool->alloc(DMA_BUFFER_READ);
+        descr->dmatx_buf[1] = descr->dmatx_pool->alloc(DMA_BUFFER_READ);
         tx_buf = (uint16_t *) descr->dmatx_buf[0]->data();
         buf_size = descr->dmatx_buf[0]->size();
         HAL_NVIC_DisableIRQ(descr->dmatx_irqn);
@@ -183,7 +183,7 @@ static int i2s_start_dma_transfer(i2s_descr_t *descr, i2s_mode_t i2s_mode) {
             return 0;
         }
     }
-
+    HAL_I2S_DMAPause(&descr->i2s);
     // Re/enable DMA double buffer mode.
     if (i2s_mode & AN_I2S_MODE_IN) {
         hal_dma_enable_dbm(&descr->dmarx, descr->dmarx_buf[0]->data(), descr->dmarx_buf[1]->data());
@@ -194,6 +194,7 @@ static int i2s_start_dma_transfer(i2s_descr_t *descr, i2s_mode_t i2s_mode) {
         hal_dma_enable_dbm(&descr->dmatx, descr->dmatx_buf[0]->data(), descr->dmatx_buf[1]->data());
         HAL_NVIC_EnableIRQ(descr->dmatx_irqn);
     }
+    HAL_I2S_DMAResume(&descr->i2s);
     return 1;
 }
 
@@ -216,7 +217,7 @@ DMABuffer<Sample> &AdvancedI2S::read() {
         while (!descr->dmarx_pool->readable()) {
             __WFI();
         }
-        return *descr->dmarx_pool->dequeue();
+        return *descr->dmarx_pool->alloc(DMA_BUFFER_READ);
     }
     return NULLBUF;
 }
@@ -227,7 +228,7 @@ DMABuffer<Sample> &AdvancedI2S::dequeue() {
         while (!descr->dmatx_pool->writable()) {
             __WFI();
         }
-        return *descr->dmatx_pool->allocate();
+        return *descr->dmatx_pool->alloc(DMA_BUFFER_WRITE);
     }
     return NULLBUF;
 }
@@ -241,7 +242,7 @@ void AdvancedI2S::write(DMABuffer<Sample> &dmabuf) {
 
     // Make sure any cached data is flushed.
     dmabuf.flush();
-    descr->dmatx_pool->enqueue(&dmabuf);
+    dmabuf.release();
 
     if (descr->dmatx_buf[0] == nullptr && (++buf_count % 3) == 0) {
         i2s_start_dma_transfer(descr, i2s_mode);
@@ -285,7 +286,7 @@ int AdvancedI2S::begin(i2s_mode_t i2s_mode, uint32_t sample_rate, size_t n_sampl
 
     if (i2s_mode & AN_I2S_MODE_IN) {
         // Allocate DMA buffer pool.
-        descr->dmarx_pool = new DMABufferPool<Sample>(n_samples, 2, n_buffers);
+        descr->dmarx_pool = new DMAPool<Sample>(n_samples, 2, n_buffers);
         if (descr->dmarx_pool == nullptr) {
             descr = nullptr;
             return 0;
@@ -299,7 +300,7 @@ int AdvancedI2S::begin(i2s_mode_t i2s_mode, uint32_t sample_rate, size_t n_sampl
 
     if (i2s_mode & AN_I2S_MODE_OUT) {
         // Allocate DMA buffer pool.
-        descr->dmatx_pool = new DMABufferPool<Sample>(n_samples, 2, n_buffers);
+        descr->dmatx_pool = new DMAPool<Sample>(n_samples, 2, n_buffers);
         if (descr->dmatx_pool == nullptr) {
             descr = nullptr;
             return 0;
@@ -358,7 +359,7 @@ void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *i2s) {
     // the next DMA memory address target.
     if (descr->dmatx_pool->readable()) {
         descr->dmatx_buf[ct]->release();
-        descr->dmatx_buf[ct] = descr->dmatx_pool->dequeue();
+        descr->dmatx_buf[ct] = descr->dmatx_pool->alloc(DMA_BUFFER_READ);
         hal_dma_update_memory(&descr->dmatx, descr->dmatx_buf[ct]->data());
     } else {
         i2s_descr_deinit(descr, false);
@@ -384,15 +385,15 @@ void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *i2s) {
         // Make sure any cached data is discarded.
         descr->dmarx_buf[ct]->invalidate();
         // Move current DMA buffer to ready queue.
-        descr->dmarx_pool->enqueue(descr->dmarx_buf[ct]);
+        descr->dmarx_buf[ct]->release();
         // Allocate a new free buffer.
-        descr->dmarx_buf[ct] = descr->dmarx_pool->allocate();
+        descr->dmarx_buf[ct] = descr->dmarx_pool->alloc(DMA_BUFFER_WRITE);
         // Currently, all multi-channel buffers are interleaved.
         if (descr->dmarx_buf[ct]->channels() > 1) {
-            descr->dmarx_buf[ct]->setflags(DMA_BUFFER_INTRLVD);
+            descr->dmarx_buf[ct]->set_flags(DMA_BUFFER_INTRLVD);
         }
     } else {
-        descr->dmarx_buf[ct]->setflags(DMA_BUFFER_DISCONT);
+        descr->dmarx_buf[ct]->set_flags(DMA_BUFFER_DISCONT);
     }
 
     // Update the next DMA target pointer.
diff --git a/src/AdvancedI2S.h b/src/AdvancedI2S.h
index d269e8c..99614d7 100644
--- a/src/AdvancedI2S.h
+++ b/src/AdvancedI2S.h
@@ -16,11 +16,9 @@
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
-#ifndef ARDUINO_ADVANCED_I2S_H
-#define ARDUINO_ADVANCED_I2S_H
+#ifndef __ADVANCED_I2S_H__
+#define __ADVANCED_I2S_H__
 
-#include <vector>
-#include "DMABuffer.h"
 #include "AdvancedAnalog.h"
 
 struct i2s_descr_t;
@@ -55,4 +53,4 @@ class AdvancedI2S {
         int stop();
 };
 
-#endif // ARDUINO_ADVANCED_I2S_H
+#endif // __ADVANCED_I2S_H__
diff --git a/src/Arduino_AdvancedAnalog.h b/src/Arduino_AdvancedAnalog.h
index 13a3b3a..ac89e8b 100644
--- a/src/Arduino_AdvancedAnalog.h
+++ b/src/Arduino_AdvancedAnalog.h
@@ -17,16 +17,12 @@
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#ifndef ADVANCEDANALOGREDUX_ARDUINO_ADVANCEDANALOG_H
-#define ADVANCEDANALOGREDUX_ARDUINO_ADVANCEDANALOG_H
-
-/**************************************************************************************
- * INCLUDE
- **************************************************************************************/
+#ifndef __ARDUINO_ADVANCED_ANALOG_H__
+#define __ARDUINO_ADVANCED_ANALOG_H__
 
 #include "AdvancedADC.h"
 #include "AdvancedDAC.h"
 #include "AdvancedI2S.h"
 #include "WavReader.h"
 
-#endif /* ADVANCEDANALOGREDUX_ARDUINO_ADVANCEDANALOG_H */
+#endif // __ARDUINO_ADVANCED_ANALOG_H__
diff --git a/src/DMABuffer.h b/src/DMABuffer.h
deleted file mode 100644
index 50289fe..0000000
--- a/src/DMABuffer.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
-  This file is part of the Arduino_AdvancedAnalog library.
-  Copyright (c) 2023 Arduino SA. All rights reserved.
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-#ifndef __DMA_BUFFER_H__
-#define __DMA_BUFFER_H__
-
-#include "Arduino.h"
-#include "Queue.h"
-
-#ifndef __SCB_DCACHE_LINE_SIZE
-#define __SCB_DCACHE_LINE_SIZE  32
-#endif
-
-template <size_t A> class AlignedAlloc {
-    // AlignedAlloc allocates extra memory before the aligned memory start, and uses that
-    // extra memory to stash the pointer returned from malloc. Note memory allocated with
-    // Aligned::alloc must be free'd later with Aligned::free.
-    public:
-        static void *malloc(size_t size) {
-            void **ptr, *stashed;
-            size_t offset = A - 1 + sizeof(void *);
-            if ((A % 2) || !((stashed = ::malloc(size + offset)))) {
-                return nullptr;
-            }
-            ptr = (void **) (((uintptr_t) stashed + offset) & ~(A - 1));
-            ptr[-1] = stashed;
-            return ptr;
-        }
-
-        static void free(void *ptr) {
-            if (ptr != nullptr) {
-                ::free(((void **) ptr)[-1]);
-            }
-        }
-
-        static size_t round(size_t size) {
-            return ((size + (A-1)) & ~(A-1));
-        }
-};
-
-enum {
-    DMA_BUFFER_DISCONT  = (1 << 0),
-    DMA_BUFFER_INTRLVD  = (1 << 1),
-};
-
-template <class, size_t> class DMABufferPool;
-
-template <class T, size_t A=__SCB_DCACHE_LINE_SIZE> class DMABuffer {
-    typedef DMABufferPool<T, A> Pool;
-
-    private:
-        Pool *pool;
-        size_t n_samples;
-        size_t n_channels;
-        T *ptr;
-        uint32_t ts;
-        uint32_t flags;
-
-    public:
-        DMABuffer(Pool *pool=nullptr, size_t samples=0, size_t channels=0, T *mem=nullptr):
-            pool(pool), n_samples(samples), n_channels(channels), ptr(mem), ts(0), flags(0) {
-        }
-
-        T *data() {
-            return ptr;
-        }
-
-        size_t size() {
-            return n_samples * n_channels;
-        }
-
-        size_t bytes() {
-            return n_samples * n_channels * sizeof(T);
-        }
-
-        void flush() {
-            #if __DCACHE_PRESENT
-            if (ptr) {
-                SCB_CleanDCache_by_Addr(data(), bytes());
-            }
-            #endif
-        }
-
-        void invalidate() {
-            #if __DCACHE_PRESENT
-            if (ptr) {
-                SCB_InvalidateDCache_by_Addr(data(), bytes());
-            }
-            #endif
-        }
-
-        uint32_t timestamp() {
-            return ts;
-        }
-
-        void timestamp(uint32_t ts) {
-            this->ts = ts;
-        }
-
-        uint32_t channels() {
-            return n_channels;
-        }
-
-        void release() {
-            if (pool && ptr) {
-                pool->release(this);
-            }
-        }
-
-        void setflags(uint32_t f) {
-            flags |= f;
-        }
-
-        bool getflags(uint32_t f) {
-            return flags & f;
-        }
-
-        void clrflags(uint32_t f=0xFFFFFFFFU) {
-            flags &= (~f);
-        }
-
-        T& operator[](size_t i)
-        {
-            assert(ptr && i < size());
-            return ptr[i];
-        }
-
-        const T& operator[](size_t i) const
-        {
-            assert(ptr && i < size());
-            return ptr[i];
-        }
-
-        operator bool() const {
-            return (ptr != nullptr);
-        }
-};
-
-template <class T, size_t A=__SCB_DCACHE_LINE_SIZE> class DMABufferPool {
-    private:
-        Queue<DMABuffer<T>*> wr_queue;
-        Queue<DMABuffer<T>*> rd_queue;
-        std::unique_ptr<uint8_t, decltype(&AlignedAlloc<A>::free)> pool;
-
-    public:
-        DMABufferPool(size_t n_samples, size_t n_channels, size_t n_buffers):
-            wr_queue(n_buffers), rd_queue(n_buffers), pool(nullptr, AlignedAlloc<A>::free) {
-            // Round up to next multiple of alignment.
-            size_t bufsize = AlignedAlloc<A>::round(n_samples * n_channels * sizeof(T));
-            if (bufsize && rd_queue && wr_queue) {
-                // Allocate an aligned memory pool for DMA buffers.
-                pool.reset((uint8_t *) AlignedAlloc<A>::malloc(n_buffers * bufsize));
-                if (!pool) {
-                    // Failed to allocate memory pool.
-                    return;
-                }
-                // Allocate the DMA buffers, initialize them using aligned
-                // pointers from the pool, and add them to the ready queue.
-                for (size_t i=0; i<n_buffers; i++) {
-                    DMABuffer<T> *buf =  new DMABuffer<T>(
-                        this, n_samples, n_channels, (T *) &pool.get()[i * bufsize]
-                    );
-                    if (buf == nullptr) {
-                        break;
-                    }
-                    wr_queue.push(buf);
-                }
-            }
-        }
-
-        ~DMABufferPool() {
-            size_t count = 0;
-            DMABuffer<T> *buf = nullptr;
-
-            while (readable()) {
-                delete dequeue();
-                count ++;
-            }
-
-            while (writable()) {
-                delete allocate();
-                count ++;
-            }
-        }
-
-        bool writable() {
-            return !(wr_queue.empty());
-        }
-
-        bool readable() {
-            return !(rd_queue.empty());
-        }
-
-        void flush() {
-            while (readable()) {
-                release(dequeue());
-            }
-        }
-
-        DMABuffer<T> *allocate() {
-            // Get a DMA buffer from the free queue.
-            return wr_queue.pop();
-        }
-
-        void release(DMABuffer<T> *buf) {
-            // Return DMA buffer to the free queue.
-            buf->clrflags();
-            wr_queue.push(buf);
-        }
-
-        void enqueue(DMABuffer<T> *buf) {
-            // Add DMA buffer to the ready queue.
-            rd_queue.push(buf);
-        }
-
-        DMABuffer<T> *dequeue() {
-            // Return a DMA buffer from the ready queue.
-            return rd_queue.pop();
-        }
-};
-#endif //__DMA_BUFFER_H__
diff --git a/src/HALConfig.cpp b/src/HALConfig.cpp
index f82a9d3..2493211 100644
--- a/src/HALConfig.cpp
+++ b/src/HALConfig.cpp
@@ -271,6 +271,7 @@ int hal_i2s_config(I2S_HandleTypeDef *i2s, uint32_t sample_rate, uint32_t mode,
     i2s->Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_RIGHT;
     i2s->Init.MasterKeepIOState = I2S_MASTER_KEEP_IO_STATE_DISABLE;
 
+    HAL_I2S_DeInit(i2s);
     if (HAL_I2S_Init(i2s) != HAL_OK) {
         return -1;
     }
diff --git a/src/Queue.h b/src/Queue.h
deleted file mode 100644
index 0b7e9f0..0000000
--- a/src/Queue.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-  This file is part of the Arduino_AdvancedAnalog library.
-  Copyright (c) 2023 Arduino SA. All rights reserved.
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-#ifndef __QUEUE_H__
-#define __QUEUE_H__
-
-#include "Arduino.h"
-
-template <class T> class Queue {
-    private:
-        size_t capacity;
-        volatile size_t tail;
-        volatile size_t head;
-        std::unique_ptr<T[]> buff;
-
-    private:
-        inline size_t next_pos(size_t x) {
-            return (((x) + 1) % (capacity));
-        }
-
-    public:
-        Queue(size_t size=0):
-         capacity(size), tail(0), head(0), buff(nullptr) {
-            if (size) {
-                tail = head = 0;
-                capacity = size + 1;
-                buff.reset(new T[capacity]);
-            }
-        }
-
-        void reset() {
-            tail = head = 0;
-        }
-
-        size_t empty() {
-            return tail == head;
-        }
-
-        operator bool() const {
-            return buff.get() != nullptr;
-        }
-
-        bool push(T data) {
-            bool ret = false;
-            size_t next = next_pos(head);
-            if (buff && (next != tail)) {
-                buff[head] = data;
-                head = next;
-                ret = true;
-            }
-            return ret;
-        }
-
-        T pop(bool peek=false) {
-            if (buff && (tail != head)) {
-                T data = buff[tail];
-                if (!peek) {
-                    tail = next_pos(tail);
-                }
-                return data;
-            }
-            return T();
-        }
-};
-#endif //__QUEUE_H__
diff --git a/src/WavReader.cpp b/src/WavReader.cpp
index f5753ec..9040d1c 100644
--- a/src/WavReader.cpp
+++ b/src/WavReader.cpp
@@ -44,7 +44,7 @@ int WavReader::begin(const char *path, size_t n_samples, size_t n_buffers, bool
     }
 
     // Allocate the DMA buffer pool.
-    pool = new DMABufferPool<Sample>(n_samples, header.num_channels, n_buffers);
+    pool = new DMAPool<Sample>(n_samples, header.num_channels, n_buffers);
     if (pool == nullptr) {
         stop();
         return 0;
@@ -75,7 +75,7 @@ DMABuffer<Sample> &WavReader::read() {
         __WFI();
     }
 
-    DMABuffer<Sample> *buf = pool->allocate();
+    DMABuffer<Sample> *buf = pool->alloc(DMA_BUFFER_WRITE);
     size_t offset = 0;
     Sample *rawbuf = buf->data();
     size_t n_samples = buf->size();
@@ -95,6 +95,8 @@ DMABuffer<Sample> &WavReader::read() {
             }
         }
     }
+    buf->clr_flags();
+    buf->set_flags(DMA_BUFFER_READ);
     return *buf;
 }
 
diff --git a/src/WavReader.h b/src/WavReader.h
index 43058ad..2bbc840 100644
--- a/src/WavReader.h
+++ b/src/WavReader.h
@@ -17,10 +17,10 @@
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#include "AdvancedAnalog.h"
+#ifndef __ADVANCED_WAV_READER_H__
+#define __ADVANCED_WAV_READER_H__
 
-#ifndef ARDUINO_WAV_READER_H_
-#define ARDUINO_WAV_READER_H_
+#include "AdvancedAnalog.h"
 
 class WavReader {
     typedef struct {
@@ -43,7 +43,7 @@ class WavReader {
         FILE *file;
         bool loop;
         WavHeader header;
-        DMABufferPool<Sample> *pool;
+        DMAPool<Sample> *pool;
 
     public:
         WavReader(): file(nullptr), loop(false), pool(nullptr) {
@@ -71,4 +71,4 @@ class WavReader {
         SampleBuffer read();
         int rewind();
 };
-#endif /* ARDUINO_WAV_READER_H_ */
+#endif // __ADVANCED_WAV_READER_H__