diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index 8da8420da..27e7d723b 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -4,6 +4,8 @@ add_library(audio_core STATIC
     codec.h
     dsp_interface.cpp
     dsp_interface.h
+    hle/adts.h
+    hle/adts_reader.cpp
     hle/common.h
     hle/decoder.cpp
     hle/decoder.h
@@ -30,7 +32,7 @@ add_library(audio_core STATIC
     $<$<BOOL:${SDL2_FOUND}>:sdl2_sink.cpp sdl2_sink.h>
     $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h>
     $<$<BOOL:${FFMPEG_FOUND}>:hle/ffmpeg_decoder.cpp hle/ffmpeg_decoder.h hle/ffmpeg_dl.cpp hle/ffmpeg_dl.h>
-    $<$<BOOL:${ENABLE_MF}>:hle/wmf_decoder.cpp hle/wmf_decoder.h hle/wmf_decoder_utils.cpp hle/wmf_decoder_utils.h hle/adts_reader.cpp>
+    $<$<BOOL:${ENABLE_MF}>:hle/wmf_decoder.cpp hle/wmf_decoder.h hle/wmf_decoder_utils.cpp hle/wmf_decoder_utils.h>
 )
 
 create_target_directory_groups(audio_core)
diff --git a/src/audio_core/hle/adts.h b/src/audio_core/hle/adts.h
index c806e2d82..c2f5304fa 100644
--- a/src/audio_core/hle/adts.h
+++ b/src/audio_core/hle/adts.h
@@ -17,14 +17,6 @@ struct ADTSData {
     u32 samplerate;
 };
 
-typedef struct ADTSData ADTSData;
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
 u32 parse_adts(char* buffer, struct ADTSData* out);
 // last two bytes of MF AAC decoder user data
 u16 mf_get_aac_tag(struct ADTSData input);
-#ifdef __cplusplus
-}
-#endif // __cplusplus
diff --git a/src/audio_core/hle/adts_reader.cpp b/src/audio_core/hle/adts_reader.cpp
index ce3d1eda4..540aed577 100644
--- a/src/audio_core/hle/adts_reader.cpp
+++ b/src/audio_core/hle/adts_reader.cpp
@@ -4,7 +4,7 @@
 #include "adts.h"
 
 constexpr std::array<u32, 16> freq_table = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
-                                 16000, 12000, 11025, 8000,  7350,  0,     0,     0};
+                                            16000, 12000, 11025, 8000,  7350,  0,     0,     0};
 constexpr std::array<u8, 8> channel_table = {0, 1, 2, 3, 4, 5, 6, 8};
 
 u32 parse_adts(char* buffer, struct ADTSData* out) {
diff --git a/src/audio_core/hle/wmf_decoder.cpp b/src/audio_core/hle/wmf_decoder.cpp
index 390ccd8dc..5dd28b7b5 100644
--- a/src/audio_core/hle/wmf_decoder.cpp
+++ b/src/audio_core/hle/wmf_decoder.cpp
@@ -73,7 +73,7 @@ std::optional<BinaryResponse> WMFDecoder::Impl::Initalize(const BinaryRequest& r
     std::memcpy(&response, &request, sizeof(response));
     response.unknown1 = 0x0;
 
-    if (MFDecoderInit(&transform) != 0) {
+    if (!MFDecoderInit(&transform)) {
         LOG_CRITICAL(Audio_DSP, "Can't init decoder");
         return response;
     }
@@ -104,7 +104,7 @@ void WMFDecoder::Impl::Clear() {
 
 int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
                                    std::array<std::vector<u8>, 2>& out_streams) {
-    int output_status = 0;
+    MFOutputState output_status = OK;
     char* output_buffer = nullptr;
     DWORD output_len = 0;
     IMFSample* output = nullptr;
@@ -113,7 +113,7 @@ int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
         output_status = ReceiveSample(transform, out_stream_id, &output);
 
         // 0 -> okay; 3 -> okay but more data available (buffer too small)
-        if (output_status == 0 || output_status == 3) {
+        if (output_status == OK || output_status == HAVE_MORE_DATA) {
             CopySampleToBuffer(output, (void**)&output_buffer, &output_len);
 
             // the following was taken from ffmpeg version of the decoder
@@ -133,20 +133,21 @@ int WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
         }
 
         // in case of "ok" only, just return quickly
-        if (output_status == 0)
+        if (output_status == OK)
             return 0;
 
         // for status = 2, reset MF
-        if (output_status == 2) {
+        if (output_status == NEED_RECONFIG) {
             Clear();
             return -1;
         }
 
         // for status = 3, try again with new buffer
-        if (output_status == 3)
+        if (output_status == HAVE_MORE_DATA)
             continue;
 
-        return output_status; // return on other status
+        LOG_ERROR(Audio_DSP, "Errors occurred when receiving output: {}", output_status);
+        return -1; // return on other status
     }
 
     return -1;
diff --git a/src/audio_core/hle/wmf_decoder_utils.cpp b/src/audio_core/hle/wmf_decoder_utils.cpp
index 50a8a5554..459f5322c 100644
--- a/src/audio_core/hle/wmf_decoder_utils.cpp
+++ b/src/audio_core/hle/wmf_decoder_utils.cpp
@@ -22,7 +22,7 @@ void ReportError(std::string msg, HRESULT hr) {
     LOG_CRITICAL(Audio_DSP, "{}: {:08x}", msg, hr);
 }
 
-int MFCoInit() {
+bool MFCoInit() {
     HRESULT hr = S_OK;
 
     // lite startup is faster and all what we need is included
@@ -30,15 +30,15 @@ int MFCoInit() {
     if (hr != S_OK) {
         // Do you know you can't initialize MF in test mode or safe mode?
         ReportError("Failed to initialize Media Foundation", hr);
-        return -1;
+        return false;
     }
 
     LOG_INFO(Audio_DSP, "Media Foundation activated");
 
-    return 0;
+    return true;
 }
 
-int MFDecoderInit(IMFTransform** transform, GUID audio_format) {
+bool MFDecoderInit(IMFTransform** transform, GUID audio_format) {
     HRESULT hr = S_OK;
     MFT_REGISTER_TYPE_INFO reg = {0};
     GUID category = MFT_CATEGORY_AUDIO_DECODER;
@@ -54,7 +54,7 @@ int MFDecoderInit(IMFTransform** transform, GUID audio_format) {
     if (FAILED(hr) || num_activate < 1) {
         ReportError("Failed to enumerate decoders", hr);
         CoTaskMemFree(activate);
-        return -1;
+        return false;
     }
     LOG_INFO(Audio_DSP, "Windows(R) Media Foundation found {} suitable decoder(s)", num_activate);
     for (unsigned int n = 0; n < num_activate; n++) {
@@ -66,10 +66,10 @@ int MFDecoderInit(IMFTransform** transform, GUID audio_format) {
     if (*transform == nullptr) {
         ReportError("Failed to initialize MFT", hr);
         CoTaskMemFree(activate);
-        return -1;
+        return false;
     }
     CoTaskMemFree(activate);
-    return 0;
+    return true;
 }
 
 void MFDeInit(IMFTransform** transform) {
@@ -117,8 +117,8 @@ IMFSample* CreateSample(void* data, DWORD len, DWORD alignment, LONGLONG duratio
     return sample;
 }
 
-bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, ADTSData adts,
-                           UINT8* user_data, UINT32 user_data_len, GUID audio_format) {
+bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts,
+                          UINT8* user_data, UINT32 user_data_len, GUID audio_format) {
     HRESULT hr = S_OK;
     IMFMediaType* t;
 
@@ -261,8 +261,7 @@ int SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample* in_sample
     return 0;
 }
 
-// return: 0: okay; 1: needs more sample; 2: needs reconfiguring; 3: more data available
-int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample) {
+MFOutputState ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample) {
     HRESULT hr;
     MFT_OUTPUT_DATA_BUFFER out_buffers;
     IMFSample* sample = nullptr;
@@ -272,14 +271,14 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_
 
     if (!out_sample) {
         ReportError("nullptr pointer passed to receive_sample()", MF_E_SAMPLE_NOT_WRITABLE);
-        return -1;
+        return FATAL_ERROR;
     }
 
     hr = transform->GetOutputStreamInfo(out_stream_id, &out_info);
 
     if (FAILED(hr)) {
         ReportError("MFT: Failed to get stream info", hr);
-        return -1;
+        return FATAL_ERROR;
     }
     mft_create_sample = (out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) ||
                         (out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES);
@@ -293,7 +292,7 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_
             sample = CreateSample(nullptr, out_info.cbSize, out_info.cbAlignment);
             if (!sample) {
                 ReportError("MFT: Unable to allocate memory for samples", hr);
-                return -1;
+                return FATAL_ERROR;
             }
         }
 
@@ -309,12 +308,12 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_
 
         if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
             // Most likely reasons: data corrupted; your actions not expected by MFT
-            return 1;
+            return NEED_MORE_INPUT;
         }
 
         if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
             ReportError("MFT: stream format changed, re-configuration required", hr);
-            return 2;
+            return NEED_RECONFIG;
         }
 
         break;
@@ -322,15 +321,15 @@ int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_
 
     if (out_buffers.dwStatus & MFT_OUTPUT_DATA_BUFFER_INCOMPLETE) {
         // this status is also unreliable but whatever
-        return 3;
+        return HAVE_MORE_DATA;
     }
 
     if (*out_sample == nullptr) {
         ReportError("MFT: decoding failure", hr);
-        return -1;
+        return FATAL_ERROR;
     }
 
-    return 0;
+    return OK;
 }
 
 int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len) {
diff --git a/src/audio_core/hle/wmf_decoder_utils.h b/src/audio_core/hle/wmf_decoder_utils.h
index 128c30477..49b443fc2 100644
--- a/src/audio_core/hle/wmf_decoder_utils.h
+++ b/src/audio_core/hle/wmf_decoder_utils.h
@@ -19,6 +19,8 @@
 
 #include "adts.h"
 
+enum MFOutputState { FATAL_ERROR = -1, OK = 0, NEED_MORE_INPUT, NEED_RECONFIG, HAVE_MORE_DATA };
+
 // utility functions
 template <class T>
 void SafeRelease(T** ppT) {
@@ -31,17 +33,17 @@ void SafeRelease(T** ppT) {
 void ReportError(std::string msg, HRESULT hr);
 
 // exported functions
-int MFCoInit();
-int MFDecoderInit(IMFTransform** transform, GUID audio_format = MFAudioFormat_AAC);
+bool MFCoInit();
+bool MFDecoderInit(IMFTransform** transform, GUID audio_format = MFAudioFormat_AAC);
 void MFDeInit(IMFTransform** transform);
 IMFSample* CreateSample(void* data, DWORD len, DWORD alignment = 1, LONGLONG duration = 0);
-bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, ADTSData adts,
-                           UINT8* user_data, UINT32 user_data_len,
-                           GUID audio_format = MFAudioFormat_AAC);
+bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts,
+                          UINT8* user_data, UINT32 user_data_len,
+                          GUID audio_format = MFAudioFormat_AAC);
 int DetectMediaType(char* buffer, size_t len, ADTSData* output, char** aac_tag);
 bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id,
-                            GUID audio_format = MFAudioFormat_PCM);
+                           GUID audio_format = MFAudioFormat_PCM);
 void MFFlush(IMFTransform** transform);
 int SendSample(IMFTransform* transform, DWORD in_stream_id, IMFSample* in_sample);
-int ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample);
+MFOutputState ReceiveSample(IMFTransform* transform, DWORD out_stream_id, IMFSample** out_sample);
 int CopySampleToBuffer(IMFSample* sample, void** output, DWORD* len);