diff --git a/src/AudioUtils.c b/src/AudioUtils.c
deleted file mode 100644
index 2f14d85cec052e90e98667f7f3831e3c2d7393e3..0000000000000000000000000000000000000000
--- a/src/AudioUtils.c
+++ /dev/null
@@ -1,131 +0,0 @@
-#include "AudioUtils.hh"
-
-#include <assert.h>
-#include <libavutil/opt.h>
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <libswresample/swresample.h>
-#include <libavcodec/avfft.h>
-
-#define MAXPIXVALUE 7 /* Some magix AV magic stuff */
-
-int
-decodeAudioFile(const char *path, const int sample_rate, double **const data, size_t *const size)
-{
-    AVPacket packet;
-    AVFormatContext *format      = avformat_alloc_context();
-    struct SwrContext *swr       = swr_alloc();
-    AVFrame *frame               = av_frame_alloc();
-    int ret_code                 = -1;
-    ssize_t stream_index         = -1;
-    AVStream *stream             = NULL;
-    AVCodecContext *codec_ctx    = NULL;
-    AVCodecParameters *codec_par = NULL;
-    AVCodec *codec               = NULL;
-
-    if (!frame) {
-        fprintf(stderr, "Error allocating the frame\n");
-        goto exit_error;
-    }
-
-    /* Get format from audio file */
-    if (avformat_open_input(&format, path, NULL, NULL) != 0) {
-        fprintf(stderr, "Could not open file '%s'\n", path);
-        goto exit_error;
-    }
-    if (avformat_find_stream_info(format, NULL) < 0) {
-        fprintf(stderr, "Could not retrieve stream info from file '%s'\n", path);
-        return -1;
-    }
-
-    /* Find the index of the first audio stream */
-    for (unsigned int i = 0; i < format->nb_streams; i++) {
-        codec = avcodec_find_encoder(format->streams[i]->codecpar->codec_id);
-        if (codec->type == AVMEDIA_TYPE_AUDIO) {
-            stream_index = i;
-            break;
-        }
-    }
-    if (stream_index == -1) {
-        fprintf(stderr, "Could not retrieve audio stream from file '%s'\n", path);
-        goto exit_error;
-    }
-    stream = format->streams[stream_index];
-
-    /* Find & open codec */
-    codec_ctx = stream->codec;
-    codec_par = stream->codecpar;
-    codec     = avcodec_find_decoder(codec_par->codec_id);
-
-    if (codec == NULL) {
-        fprintf(stderr, "Failed to find decoder for stream #%zu in file '%s'\n", stream_index,
-                path);
-        goto exit_error;
-    }
-
-    if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
-        fprintf(stderr, "Failed to open decoder for stream #%zu in file '%s'\n", stream_index,
-                path);
-        goto exit_error;
-    }
-
-    /* Prepare resampler */
-    av_opt_set_int(swr, "in_channel_count", codec_ctx->channels, 0);
-    av_opt_set_int(swr, "out_channel_count", 1, 0);
-    av_opt_set_int(swr, "in_channel_layout", (int64_t)codec_ctx->channel_layout, 0);
-    av_opt_set_int(swr, "out_channel_layout", AV_CH_LAYOUT_MONO, 0);
-    av_opt_set_int(swr, "in_sample_rate", codec_ctx->sample_rate, 0);
-    av_opt_set_int(swr, "out_sample_rate", sample_rate, 0);
-    av_opt_set_sample_fmt(swr, "in_sample_fmt", codec_ctx->sample_fmt, 0);
-    av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_DBL, 0);
-    swr_init(swr);
-    if (!swr_is_initialized(swr)) {
-        fprintf(stderr, "Resampler has not been properly initialized\n");
-        goto exit_error;
-    }
-
-    /* Prepare to read data */
-    av_init_packet(&packet);
-
-    /* Iterate through frames */
-    *data = NULL;
-    *size = 0;
-    while (av_read_frame(format, &packet) >= 0) {
-        /* Decode one frame */
-        int gotFrame;
-        if (avcodec_decode_audio4(codec_ctx, frame, &gotFrame, &packet) < 0) {
-            break;
-        }
-        if (!gotFrame) {
-            continue;
-        }
-
-        /* Resample frames */
-        double *buffer;
-        av_samples_alloc((uint8_t **)&buffer, NULL, 1, frame->nb_samples, AV_SAMPLE_FMT_DBL, 0);
-        const int frame_count_int = swr_convert(swr, (uint8_t **)&buffer, frame->nb_samples,
-                                                (const uint8_t **)frame->data, frame->nb_samples);
-        assert(frame_count_int >= 0);
-        const size_t frame_count = (size_t)frame_count_int;
-
-        /* Append resampled frames to data */
-        *data = (double *)realloc(*data, (*size + (size_t)frame->nb_samples) * sizeof(double));
-        memcpy(*data + *size, buffer, frame_count * sizeof(double));
-        av_free(buffer);
-        *size += frame_count;
-    }
-
-    /* Clean up */
-    ret_code = 0;
-exit_error:
-    if (frame != NULL)
-        av_frame_free(&frame);
-    if (swr != NULL)
-        swr_free(&swr);
-    if (codec_ctx != NULL)
-        avcodec_close(codec_ctx);
-    if (format != NULL)
-        avformat_free_context(format);
-
-    return ret_code;
-}
diff --git a/src/AudioUtils.cc b/src/AudioUtils.cc
index 187983c7eaa60f854b2fd28afddfa15c371f2272..fb65325d5b5c030c90d02b7ce1cfe550cb2634a2 100644
--- a/src/AudioUtils.cc
+++ b/src/AudioUtils.cc
@@ -40,10 +40,20 @@ DecoderOption::getDecalage() const noexcept
 RawImageData
 RawImageData::fromAudioFile(const DecoderOption &opt, const QString &path)
 {
+    auto avFrameDeleter = [](AVFrame *ptr) noexcept -> void {
+        if (ptr)
+            av_frame_free(&ptr);
+    };
+
+    auto swrContenxtDeleter = [](SwrContext *swr) noexcept -> void {
+        if (swr)
+            swr_free(&swr);
+    };
+
     AVPacket packet;
-    AVFormatContext *format      = avformat_alloc_context();
-    struct SwrContext *swr       = swr_alloc();
-    AVFrame *frame               = av_frame_alloc();
+    AVFormatContext *format = avformat_alloc_context();
+    std::unique_ptr<SwrContext, decltype(swrContenxtDeleter)> swr(swr_alloc(), swrContenxtDeleter);
+    std::unique_ptr<AVFrame, decltype(avFrameDeleter)> frame(av_frame_alloc(), avFrameDeleter);
     ssize_t stream_index         = -1;
     AVStream *stream             = nullptr;
     AVCodecContext *codec_ctx    = nullptr;
@@ -98,16 +108,17 @@ RawImageData::fromAudioFile(const DecoderOption &opt, const QString &path)
     }
 
     /* Prepare resampler */
-    av_opt_set_int(swr, "in_channel_count", codec_ctx->channels, 0);
-    av_opt_set_int(swr, "out_channel_count", 1, 0);
-    av_opt_set_int(swr, "in_channel_layout", static_cast<int64_t>(codec_ctx->channel_layout), 0);
-    av_opt_set_int(swr, "out_channel_layout", AV_CH_LAYOUT_MONO, 0);
-    av_opt_set_int(swr, "in_sample_rate", codec_ctx->sample_rate, 0);
-    av_opt_set_int(swr, "out_sample_rate", opt.getSampleRate(), 0);
-    av_opt_set_sample_fmt(swr, "in_sample_fmt", codec_ctx->sample_fmt, 0);
-    av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_DBL, 0);
-    swr_init(swr);
-    if (!swr_is_initialized(swr)) {
+    av_opt_set_int(swr.get(), "in_channel_count", codec_ctx->channels, 0);
+    av_opt_set_int(swr.get(), "out_channel_count", 1, 0);
+    av_opt_set_int(swr.get(), "in_channel_layout", static_cast<int64_t>(codec_ctx->channel_layout),
+                   0);
+    av_opt_set_int(swr.get(), "out_channel_layout", AV_CH_LAYOUT_MONO, 0);
+    av_opt_set_int(swr.get(), "in_sample_rate", codec_ctx->sample_rate, 0);
+    av_opt_set_int(swr.get(), "out_sample_rate", opt.getSampleRate(), 0);
+    av_opt_set_sample_fmt(swr.get(), "in_sample_fmt", codec_ctx->sample_fmt, 0);
+    av_opt_set_sample_fmt(swr.get(), "out_sample_fmt", AV_SAMPLE_FMT_DBL, 0);
+    swr_init(swr.get());
+    if (!swr_is_initialized(swr.get())) {
         fprintf(stderr, "Resampler has not been properly initialized\n");
         throw std::runtime_error("failed to initialize resampler");
     }
@@ -119,7 +130,7 @@ RawImageData::fromAudioFile(const DecoderOption &opt, const QString &path)
     while (av_read_frame(format, &packet) >= 0) {
         /* Decode one frame */
         int gotFrame;
-        if (avcodec_decode_audio4(codec_ctx, frame, &gotFrame, &packet) < 0) {
+        if (avcodec_decode_audio4(codec_ctx, frame.get(), &gotFrame, &packet) < 0) {
             break;
         }
         if (!gotFrame) {
@@ -129,7 +140,7 @@ RawImageData::fromAudioFile(const DecoderOption &opt, const QString &path)
         /* Resample frames */
         double *buffer;
         av_samples_alloc((uint8_t **)&buffer, NULL, 1, frame->nb_samples, AV_SAMPLE_FMT_DBL, 0);
-        const int frame_count_int = swr_convert(swr, (uint8_t **)&buffer, frame->nb_samples,
+        const int frame_count_int = swr_convert(swr.get(), (uint8_t **)&buffer, frame->nb_samples,
                                                 (const uint8_t **)frame->data, frame->nb_samples);
         assert(frame_count_int >= 0);
         const size_t frame_count = (size_t)frame_count_int;
@@ -141,12 +152,6 @@ RawImageData::fromAudioFile(const DecoderOption &opt, const QString &path)
         size += frame_count;
     }
 
-    /* Clean up */
-exit_error:
-    if (frame != NULL)
-        av_frame_free(&frame);
-    if (swr != NULL)
-        swr_free(&swr);
     if (codec_ctx != NULL)
         avcodec_close(codec_ctx);
     if (format != NULL)
diff --git a/src/AudioUtils.hh b/src/AudioUtils.hh
index a8022c5675d2d86f0b588290935c290c03e0a79d..7953909bea91eb85b1eeec3c64033307458490a1 100644
--- a/src/AudioUtils.hh
+++ b/src/AudioUtils.hh
@@ -1,25 +1,17 @@
 #ifndef VIVY_AUDIOUTILS_H
 #define VIVY_AUDIOUTILS_H
 
-#ifdef __cplusplus
-extern "C" {
+#ifndef __cplusplus
+#error "This is a C++ header"
 #endif
 
+extern "C" {
 #include <libavutil/opt.h>
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
 #include <libswresample/swresample.h>
 #include <libavcodec/avfft.h>
-
-int decodeAudioFile(const char *path, const int sample_rate, double **const data,
-                    size_t *const size);
-
-#ifdef __cplusplus
 }
-#endif
-
-/* C++ only code */
-#ifdef __cplusplus
 
 #include <QtGlobal>
 #include <memory.h>
@@ -78,6 +70,4 @@ public:
 };
 }
 
-#endif
-
 #endif // VIVY_AUDIOUTILS_H
diff --git a/src/UI/AudioVisualizer.cc b/src/UI/AudioVisualizer.cc
index 41b21aa973042babda524b3aeab2f7817add0189..ec0e03ffca181d91bbfb09388ac11df517c74207 100644
--- a/src/UI/AudioVisualizer.cc
+++ b/src/UI/AudioVisualizer.cc
@@ -31,23 +31,8 @@ AudioVisualizer::fromFile(const QString &filename)
     if (filename.isEmpty())
         return nullptr;
 
-    const int sample_rate = 44100;
-    double *data          = nullptr;
-    size_t size           = 0;
-    int rc            = decodeAudioFile(filename.toStdString().c_str(), sample_rate, &data, &size);
-    auto data_deleter = [](double *ptr) -> void {
-        if (ptr != nullptr) {
-            av_free(ptr);
-        }
-    };
-    std::unique_ptr<double, decltype(data_deleter)> data_holder(data, data_deleter);
-
-    if (rc != 0) {
-        printf("ERROR\n");
-        return nullptr;
-    }
-
-    Utils::RawImageData rawImage(Utils::DecoderOption{}, data, size);
+    Utils::RawImageData rawImage =
+        Utils::RawImageData::fromAudioFile(Utils::DecoderOption{}, filename);
     QImage img = QImage(rawImage.releasePixels(), rawImage.getWidth(), rawImage.getHeight(),
                         rawImage.getWidth(), QImage::Format_Grayscale8,
                         Utils::RawImageData::pixelsDeleter, rawImage.releasePixels())