diff --git configure.ac configure.ac
index 47eb1d9e33..c61564bb0e 100644
--- configure.ac
+++ configure.ac
@@ -315,6 +315,12 @@ AC_ARG_ENABLE([pulse],
   [use_pulse=$enableval],
   [use_pulse=auto])
 
+AC_ARG_ENABLE([sndio],
+  [AS_HELP_STRING([--enable-sndio],
+  [enable sndio support (default is auto)])],
+  [use_sndio=$enableval],
+  [use_sndio=auto])
+
 AC_ARG_ENABLE([ssh],
   [AS_HELP_STRING([--disable-ssh],
   [disable SSH SFTP support (default is enabled)])],
@@ -1210,6 +1216,22 @@ else
   USE_PULSE=0
 fi
 
+# sndio
+if test "x$use_sndio" != "xno"; then
+   USE_SNDIO=0
+   AC_CHECK_HEADER(sndio.h, HAVE_SNDIO="yes", HAVE_SNDIO="no")
+   if test "x$HAVE_SNDIO" = "xyes"; then
+       AC_CHECK_LIB(sndio, sio_open, HAVE_SNDIO="yes", HAVE_SNDIO="no", [])
+       if test "x$HAVE_SNDIO" = "xyes"; then
+            LIBS="$LIBS -lsndio"
+            USE_SNDIO=1
+            AC_DEFINE([HAVE_SNDIO],[1],[sndio enabled])
+       fi
+   fi
+else
+   USE_SNDIO=0
+fi
+
 # avahi
 if test "$use_avahi" = "yes"; then
   AC_CHECK_LIB([avahi-common], [main],,
@@ -1924,6 +1946,12 @@ else
   final_message="$final_message\n  PulseAudio:\tNo"
 fi
 
+if test "$use_sndio" = "yes"; then
+  final_message="$final_message\n  Sndio Support:\tYes"
+else
+  final_message="$final_message\n  Sndio Support:\tNo"
+fi
+
 # Google Test Framework
 if test "$configure_gtest" = "yes"; then
   AC_MSG_NOTICE($gtest_enabled)
@@ -2247,6 +2275,8 @@ AC_SUBST(USE_AIRPLAY)
 AC_SUBST(USE_OPENMAX)
 AC_SUBST(USE_PULSE)
 AC_SUBST(HAVE_LIBPULSE)
+AC_SUBST(USE_SNDIO)
+AC_SUBST(HAVE_SNDIO)
 AC_SUBST(USE_ALSA)
 AC_SUBST(USE_TEXTUREPACKER)
 AC_SUBST(TEXTUREPACKER)
diff --git xbmc/cores/AudioEngine/AESinkFactory.cpp xbmc/cores/AudioEngine/AESinkFactory.cpp
index d7b05cdbfe..617b5dba83 100644
--- xbmc/cores/AudioEngine/AESinkFactory.cpp
+++ xbmc/cores/AudioEngine/AESinkFactory.cpp
@@ -36,6 +36,9 @@
   #if defined(HAS_ALSA)
     #include "Sinks/AESinkALSA.h"
   #endif
+  #if defined(HAS_SNDIO)
+    #include "Sinks/AESinkSNDIO.h"
+  #endif
   #if defined(TARGET_FREEBSD)
     #include "Sinks/AESinkOSS.h"
   #endif
@@ -77,6 +80,9 @@
   #if defined(HAS_ALSA)
         driver == "ALSA"        ||
   #endif
+  #if defined(HAS_SNDIO)
+        driver == "SNDIO"       ||
+  #endif
   #if defined(TARGET_FREEBSD)
         driver == "OSS"         ||
   #endif
@@ -116,11 +122,15 @@ IAESink *CAESinkFactory::TrySink(std::string &driver, std::string &device, AEAud
     sink = new CAESinkDARWINIOS();
 #elif defined(TARGET_DARWIN_OSX)
     sink = new CAESinkDARWINOSX();
-#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
+#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) || defined(TARGET_OPENBSD)
  #if defined(HAS_PULSEAUDIO)
     if (driver == "PULSE")
       sink = new CAESinkPULSE();
  #endif
+ #if defined(HAS_SNDIO)
+    if (driver == "SNDIO")
+        sink = new CAESinkSNDIO();
+ #endif
  #if defined(HAS_ALSA)
     if (driver == "ALSA")
       sink = new CAESinkALSA();
@@ -236,6 +246,10 @@ void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force)
     if (envSink == "PULSE")
       CAESinkPULSE::EnumerateDevicesEx(info.m_deviceInfoList, force);
     #endif
+    #if defined(HAS_SNDIO)
+    if (envSink == "SNDIO")
+        CAESinkSNDIO::EnumerateDevicesEx(info.m_deviceInfoList, force);
+    #endif
     #if defined(HAS_ALSA)
     if (envSink == "ALSA")
       CAESinkALSA::EnumerateDevicesEx(info.m_deviceInfoList, force);
@@ -264,6 +278,17 @@ void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force)
   }
   #endif
 
+  #if defined(HAS_SNDIO)
+  info.m_deviceInfoList.clear();
+  info.m_sinkName = "SNDIO";
+  CAESinkSNDIO::EnumerateDevicesEx(info.m_deviceInfoList, force);
+  if(!info.m_deviceInfoList.empty())
+  {
+      list.push_back(info);
+      return;
+  }
+  #endif
+
   #if defined(HAS_ALSA)
   info.m_deviceInfoList.clear();
   info.m_sinkName = "ALSA";
diff --git xbmc/cores/AudioEngine/Makefile.in xbmc/cores/AudioEngine/Makefile.in
index 7aab111f81..788786e2d1 100644
--- xbmc/cores/AudioEngine/Makefile.in
+++ xbmc/cores/AudioEngine/Makefile.in
@@ -55,6 +55,9 @@ SRCS += Sinks/AESinkOSS.cpp
 ifeq (@USE_PULSE@,1)
 SRCS += Sinks/AESinkPULSE.cpp
 endif
+ifeq (@USE_SNDIO@,1)
+SRCS += Sinks/AESinkSNDIO.cpp
+endif
 endif
 
 SRCS += DSPAddons/ActiveAEDSP.cpp
diff --git xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.cpp xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.cpp
new file mode 100644
index 0000000000..879b9a90a3
--- /dev/null
+++ xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.cpp
@@ -0,0 +1,313 @@
+/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
+/*
+ *      Copyright (C) 2010-2013 Team XBMC
+ *      http://xbmc.org
+ *
+ *  This Program 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 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program 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 XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system.h"
+#ifdef HAS_SNDIO
+#include "AESinkSNDIO.h"
+#include "cores/AudioEngine/Utils/AEUtil.h"
+#include "utils/log.h"
+
+#include <sys/param.h>
+
+#ifndef nitems
+#define nitems(x) (sizeof((x))/sizeof((x)[0]))
+#endif
+
+static enum AEChannel channelMap[] =
+{
+  AE_CH_FL,
+  AE_CH_FR,
+  AE_CH_BL,
+  AE_CH_BR,
+  AE_CH_FC,
+  AE_CH_LFE,
+  AE_CH_SL,
+  AE_CH_SR,
+};
+
+struct sndio_formats
+{
+  AEDataFormat fmt;
+  unsigned int bits;
+  unsigned int bps;
+  unsigned int sig;
+  unsigned int le;
+  unsigned int msb;
+};
+
+static struct sndio_formats formats[] =
+{
+  { AE_FMT_S32LE, 32, 4, 1, 1, 1 },
+  { AE_FMT_S32BE, 32, 4, 1, 0, 1 },
+
+  { AE_FMT_S24LE4, 24, 4, 1, 1, 0 },
+  { AE_FMT_S24BE4, 24, 4, 1, 0, 0 },
+  { AE_FMT_S24LE4, 24, 4, 1, 1, 1 },
+  { AE_FMT_S24BE4, 24, 4, 1, 0, 1 },
+
+  { AE_FMT_S24LE3, 24, 3, 1, 1, 0 },
+  { AE_FMT_S24BE3, 24, 3, 1, 0, 0 },
+  { AE_FMT_S24LE3, 24, 3, 1, 1, 1 },
+  { AE_FMT_S24BE3, 24, 3, 1, 0, 1 },
+
+  { AE_FMT_S16LE, 16, 2, 1, 1, 1 },
+  { AE_FMT_S16LE, 16, 2, 1, 1, 0 },
+  { AE_FMT_S16BE, 16, 2, 1, 0, 1 },
+  { AE_FMT_S16BE, 16, 2, 1, 0, 0 },
+
+  { AE_FMT_U8, 8, 1, 0, 0, 0 },
+  { AE_FMT_U8, 8, 1, 0, 0, 1 },
+  { AE_FMT_U8, 8, 1, 0, 1, 0 },
+  { AE_FMT_U8, 8, 1, 0, 1, 1 },
+};
+
+static AEDataFormat lookupDataFormat(int bits, int bps, int sig, int le, int msb)
+{
+  for (size_t i = 0; i < nitems(formats); i++)
+  {
+    if (bits == formats[i].bits &&
+        bps == formats[i].bps &&
+        sig == formats[i].sig &&
+        le == formats[i].le &&
+        msb == formats[i].msb)
+    {
+      return formats[i].fmt;
+    }
+  }
+  return AE_FMT_INVALID;
+}
+
+void CAESinkSNDIO::AudioFormatToPar(AEAudioFormat& format)
+{
+  sio_initpar(&par);
+
+  par.rate = format.m_sampleRate;
+  par.xrun = SIO_IGNORE;
+  par.pchan = format.m_channelLayout.Count();
+
+  for (size_t i = 0; i < nitems(formats); i++)
+  {
+    if (formats[i].fmt == format.m_dataFormat)
+    {
+      par.bits = formats[i].bits;
+      par.sig = formats[i].sig;
+      par.le = formats[i].le;
+      par.msb = formats[i].msb;
+      par.bps = formats[i].bps;
+      return;
+    }
+  }
+
+  /* Default to AE_FMT_S16LE */
+  par.bits = 16;
+  par.bps = SIO_BPS(16);
+  par.sig = 1;
+  par.le = 1;
+  par.msb = 0;
+}
+
+bool CAESinkSNDIO::ParToAudioFormat(AEAudioFormat& format)
+{
+  AEDataFormat dataFormat = lookupDataFormat(par.bits, par.bps, par.sig, par.le, par.msb);
+  if (dataFormat == AE_FMT_INVALID)
+  {
+    CLog::Log(LOGERROR, "CAESinkSNDIO::ParToAudioFormat - invalid data format");
+    return false;
+  }
+
+  if (par.pchan > nitems(channelMap))
+  {
+    CLog::Log(LOGERROR, "CAESinkSNDIO::ParToAudioFormat - too many channels: %d", par.pchan);
+    return false;
+  }
+
+  CAEChannelInfo info;
+  for (unsigned int i = 0; i < par.pchan; i++)
+      info += channelMap[i];
+  format.m_channelLayout = info;
+  format.m_dataFormat = dataFormat;
+  format.m_sampleRate = par.rate;
+  format.m_frameSize = par.bps * par.pchan;
+  format.m_frames = par.bufsz / format.m_frameSize;
+
+  return true;
+}
+
+CAESinkSNDIO::CAESinkSNDIO()
+{
+  m_hdl = nullptr;
+}
+
+CAESinkSNDIO::~CAESinkSNDIO()
+{
+  Deinitialize();
+}
+
+bool CAESinkSNDIO::Initialize(AEAudioFormat &format, std::string &device)
+{
+  if ((m_hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0)) == nullptr)
+  {
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - Failed to open device");
+    return false;
+  }
+
+  AudioFormatToPar(format);
+  if (!sio_setpar(m_hdl, &par) ||
+      !sio_getpar(m_hdl, &par) ||
+      !ParToAudioFormat(format))
+  {
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - could not negotiate parameters");
+    return false;
+  }
+
+  played = written = 0;
+
+  sio_onmove(m_hdl, CAESinkSNDIO::OnmoveCb, this);
+
+  if (!sio_start(m_hdl))
+  {
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - sio_start failed");
+    return false;
+  }
+
+  return true;
+}
+
+void CAESinkSNDIO::Deinitialize()
+{
+  if (m_hdl != nullptr)
+  {
+    sio_close(m_hdl);
+    m_hdl = nullptr;
+  }
+}
+
+void CAESinkSNDIO::Stop()
+{
+  if (!m_hdl)
+    return;
+
+  if (!sio_stop(m_hdl))
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Stop - Failed");
+
+  written = played = 0;
+}
+
+void CAESinkSNDIO::OnmoveCb(void *arg, int delta) {
+  CAESinkSNDIO* self = static_cast<CAESinkSNDIO*>(arg);
+  self->played += delta;
+}
+
+void CAESinkSNDIO::GetDelay(AEDelayStatus& status)
+{
+  unsigned int frameSize = par.bps * par.pchan;
+  double delay = 1.0 * ((written / frameSize) - played) / par.rate;
+  status.SetDelay(delay);
+}
+
+unsigned int CAESinkSNDIO::AddPackets(uint8_t **data, unsigned int frames, unsigned int offset)
+{
+  if (!m_hdl)
+    return INT_MAX;
+
+  unsigned int frameSize = par.bps * par.pchan;
+  size_t size = frames * frameSize;
+  void *buffer = data[0] + offset * frameSize;
+  size_t wrote = sio_write(m_hdl, buffer, size);
+  written += wrote;
+  return wrote / frameSize;
+}
+
+void CAESinkSNDIO::Drain()
+{
+  if(!m_hdl)
+    return;
+
+  if (!sio_stop(m_hdl) || !sio_start(m_hdl))
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Drain - failed");
+
+  written = played = 0;
+}
+
+void CAESinkSNDIO::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
+{
+  struct sio_hdl *hdl;
+  struct sio_cap cap;
+
+  if ((hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0)) == nullptr)
+  {
+    CLog::Log(LOGERROR, "CAESinkSNDIO::EnumerateDevicesEx - sio_open");
+    return;
+  }
+
+  if (!sio_getcap(hdl, &cap))
+  {
+    CLog::Log(LOGERROR, "CAESinkSNDIO::EnumerateDevicesEx - sio_getcap");
+    return;
+  }
+
+  sio_close(hdl);
+  hdl = nullptr;
+
+  for (unsigned int i = 0; i < cap.nconf; i++)
+  {
+    CAEDeviceInfo info;
+    sio_cap::sio_conf conf = cap.confs[i];
+
+    info.m_deviceName = SIO_DEVANY;
+    info.m_displayName = "sndio";
+    info.m_displayNameExtra = "#" + std::to_string(i);
+    info.m_deviceType = AE_DEVTYPE_PCM;
+
+    unsigned int maxchan = 0;
+    for (unsigned int j = 0; j < SIO_NCHAN; j++)
+    {
+      if (conf.pchan & (1 << j))
+        maxchan = MAX(maxchan, cap.pchan[j]);
+    }
+
+    maxchan = MIN(maxchan, nitems(channelMap));
+    for (unsigned int j = 0; j < maxchan; j++)
+      info.m_channels += channelMap[j];
+
+    for (unsigned int j = 0; j < SIO_NRATE; j++)
+    {
+      if (conf.rate & (1 << j))
+      {
+        info.m_sampleRates.push_back(cap.rate[j]);
+      }
+    }
+
+    for (unsigned int j = 0; j < SIO_NENC; j++)
+    {
+      if (conf.enc & (1 << j))
+      {
+        AEDataFormat format = lookupDataFormat(cap.enc[j].bits, cap.enc[j].bps, cap.enc[j].sig, cap.enc[j].le, cap.enc[j].msb);
+        if (format != AE_FMT_INVALID)
+          info.m_dataFormats.push_back(format);
+      }
+    }
+
+    list.push_back(info);
+  }
+}
+
+#endif
diff --git xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.h xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.h
new file mode 100644
index 0000000000..55719cd305
--- /dev/null
+++ xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.h
@@ -0,0 +1,57 @@
+/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
+#pragma once
+/*
+ *      Copyright (C) 2010-2013 Team XBMC
+ *      http://xbmc.org
+ *
+ *  This Program 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 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program 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 XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "cores/AudioEngine/Interfaces/AESink.h"
+#include "cores/AudioEngine/Utils/AEDeviceInfo.h"
+#include <stdint.h>
+#include <sndio.h>
+
+#include "threads/CriticalSection.h"
+
+class CAESinkSNDIO : public IAESink
+{
+public:
+  virtual const char *GetName() { return "sndio"; }
+
+  CAESinkSNDIO();
+  virtual ~CAESinkSNDIO();
+
+  virtual bool Initialize(AEAudioFormat &format, std::string &device);
+  virtual void Deinitialize();
+
+  virtual void Stop();
+  virtual void GetDelay(AEDelayStatus& status);
+  virtual double GetCacheTotal() { return 0.0; }
+  virtual unsigned int AddPackets(uint8_t **data, unsigned int frames, unsigned int offset);
+  virtual void Drain();
+  static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false);
+private:
+  void AudioFormatToPar(AEAudioFormat& format);
+  bool ParToAudioFormat(AEAudioFormat& format);
+  static void OnmoveCb(void *arg, int delta);
+
+  struct sio_hdl *m_hdl;
+  struct sio_par par;
+  ssize_t played;
+  ssize_t written;
+};
+
diff --git xbmc/system.h xbmc/system.h
index d426ade093..ed01ab53fd 100644
--- xbmc/system.h
+++ xbmc/system.h
@@ -172,6 +172,9 @@
 #ifdef HAVE_LIBPULSE
 #define HAS_PULSEAUDIO
 #endif
+#ifdef HAVE_SNDIO
+#define HAS_SNDIO
+#endif
 #ifdef HAVE_ALSA
 #define HAS_ALSA
 #endif
