diff --git a/CMakeLists.txt b/CMakeLists.txt
index afdfccc..ece9b6f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,7 +36,7 @@ if(FREESCALE_FOUND)
endif()
if (AVCODEC_FOUND AND AVUTIL_FOUND AND SWSCALE_FOUND AND SDL_FOUND)
- list(APPEND SRC_LIST ./src/video/ffmpeg.c ./src/video/sdl.c)
+ list(APPEND SRC_LIST ./src/video/ffmpeg.c ./src/video/sdl.c ./src/audio/sdl.c)
list(APPEND MOONLIGHT_DEFINITIONS HAVE_SDL)
endif()
diff --git a/src/audio.h b/src/audio.h
index 421068a..e41a738 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -22,3 +22,6 @@
extern const char* audio_device;
extern AUDIO_RENDERER_CALLBACKS audio_callbacks_alsa;
+#ifdef HAVE_SDL
+extern AUDIO_RENDERER_CALLBACKS audio_callbacks_sdl;
+#endif
\ No newline at end of file
diff --git a/src/audio/sdl.c b/src/audio/sdl.c
new file mode 100644
index 0000000..5590718
--- /dev/null
+++ b/src/audio/sdl.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of Moonlight Embedded.
+ *
+ * Copyright (C) 2015 Iwan Timmer
+ *
+ * Moonlight is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Moonlight 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Moonlight; if not, see .
+ */
+
+#include "../audio.h"
+
+#include
+#include
+
+#include
+#include
+
+#define SAMPLE_RATE 48000
+#define CHANNEL_COUNT 2
+#define FRAME_SIZE 240
+
+static OpusDecoder* decoder;
+static short pcmBuffer[FRAME_SIZE * CHANNEL_COUNT];
+static SDL_AudioDeviceID dev;
+
+static void sdl_renderer_init() {
+ int rc;
+ decoder = opus_decoder_create(SAMPLE_RATE, CHANNEL_COUNT, &rc);
+
+ SDL_InitSubSystem(SDL_INIT_AUDIO);
+
+ SDL_AudioSpec want, have;
+ SDL_zero(want);
+ want.freq = SAMPLE_RATE;
+ want.format = AUDIO_S16LSB;
+ want.channels = CHANNEL_COUNT;
+ want.samples = 4096;
+
+ dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
+ if (dev == 0) {
+ printf("Failed to open audio: %s\n", SDL_GetError());
+ } else {
+ if (have.format != want.format) // we let this one thing change.
+ printf("We didn't get requested audio format.\n");
+ SDL_PauseAudioDevice(dev, 0); // start audio playing.
+ }
+}
+
+static void sdl_renderer_cleanup() {
+ if (decoder != NULL)
+ opus_decoder_destroy(decoder);
+
+ SDL_CloseAudioDevice(dev);
+}
+
+static void sdl_renderer_decode_and_play_sample(char* data, int length) {
+ int decodeLen = opus_decode(decoder, data, length, pcmBuffer, FRAME_SIZE, 0);
+ if (decodeLen > 0) {
+ SDL_QueueAudio(dev, pcmBuffer, decodeLen * CHANNEL_COUNT * sizeof(short));
+ } else {
+ printf("Opus error from decode: %d\n", decodeLen);
+ }
+}
+
+AUDIO_RENDERER_CALLBACKS audio_callbacks_sdl = {
+ .init = sdl_renderer_init,
+ .cleanup = sdl_renderer_cleanup,
+ .decodeAndPlaySample = sdl_renderer_decode_and_play_sample,
+};
diff --git a/src/platform.c b/src/platform.c
index 0de9e08..8c4e0bb 100644
--- a/src/platform.c
+++ b/src/platform.c
@@ -72,6 +72,10 @@ DECODER_RENDERER_CALLBACKS* platform_get_video(enum platform system) {
AUDIO_RENDERER_CALLBACKS* platform_get_audio(enum platform system) {
switch (system) {
+ #ifdef HAVE_SDL
+ case SDL:
+ return &audio_callbacks_sdl;
+ #endif
default:
return &audio_callbacks_alsa;
}