View | Details | Raw Unified | Return to bug 220231
Collapse All | Expand All

(-)b/multimedia/kodi/Makefile (-1 / +5 lines)
Lines 89-95 PLIST_SUB= ARCH=${KODI_ARCH_${ARCH}} Link Here
89
OPTIONS_SUB=	yes
89
OPTIONS_SUB=	yes
90
OPTIONS_DEFINE=	AIRPLAY AIRTUNES AVAHI CEC DOCS \
90
OPTIONS_DEFINE=	AIRPLAY AIRTUNES AVAHI CEC DOCS \
91
		LIBBLURAY LIRC MYSQL NFS NONFREE PULSEAUDIO RTMP \
91
		LIBBLURAY LIRC MYSQL NFS NONFREE PULSEAUDIO RTMP \
92
		SFTP SMB VAAPI VDPAU WEBSERVER
92
		SFTP SNDIO SMB VAAPI VDPAU WEBSERVER
93
OPTIONS_SINGLE=		RPI
93
OPTIONS_SINGLE=		RPI
94
OPTIONS_SINGLE_RPI=	RPI1 RPI2
94
OPTIONS_SINGLE_RPI=	RPI1 RPI2
95
95
Lines 146-151 RPI2_CONFIGURE_ON= --with-platform=raspberry-pi2 Link Here
146
RTMP_LIB_DEPENDS=	librtmp.so:multimedia/librtmp
146
RTMP_LIB_DEPENDS=	librtmp.so:multimedia/librtmp
147
RTMP_CONFIGURE_ENABLE=	rtmp
147
RTMP_CONFIGURE_ENABLE=	rtmp
148
148
149
SNDIO_LIB_DEPENDS=	libsndio.so:audio/sndio
150
SNDIO_CONFIGURE_ENABLE=	sndio
151
SNDIO_EXTRA_PATCHES=	${PATCHDIR}/extra-patch-sndio
152
149
SMB_USES=		samba:lib
153
SMB_USES=		samba:lib
150
SMB_CONFIGURE_ENABLE=	samba
154
SMB_CONFIGURE_ENABLE=	samba
151
155
(-)b/multimedia/kodi/files/extra-patch-sndio (+542 lines)
Added Link Here
1
diff --git configure.ac configure.ac
2
index 47eb1d9e33..c61564bb0e 100644
3
--- configure.ac
4
+++ configure.ac
5
@@ -315,6 +315,12 @@ AC_ARG_ENABLE([pulse],
6
   [use_pulse=$enableval],
7
   [use_pulse=auto])
8
 
9
+AC_ARG_ENABLE([sndio],
10
+  [AS_HELP_STRING([--enable-sndio],
11
+  [enable sndio support (default is auto)])],
12
+  [use_sndio=$enableval],
13
+  [use_sndio=auto])
14
+
15
 AC_ARG_ENABLE([ssh],
16
   [AS_HELP_STRING([--disable-ssh],
17
   [disable SSH SFTP support (default is enabled)])],
18
@@ -1210,6 +1216,22 @@ else
19
   USE_PULSE=0
20
 fi
21
 
22
+# sndio
23
+if test "x$use_sndio" != "xno"; then
24
+   USE_SNDIO=0
25
+   AC_CHECK_HEADER(sndio.h, HAVE_SNDIO="yes", HAVE_SNDIO="no")
26
+   if test "x$HAVE_SNDIO" = "xyes"; then
27
+       AC_CHECK_LIB(sndio, sio_open, HAVE_SNDIO="yes", HAVE_SNDIO="no", [])
28
+       if test "x$HAVE_SNDIO" = "xyes"; then
29
+            LIBS="$LIBS -lsndio"
30
+            USE_SNDIO=1
31
+            AC_DEFINE([HAVE_SNDIO],[1],[sndio enabled])
32
+       fi
33
+   fi
34
+else
35
+   USE_SNDIO=0
36
+fi
37
+
38
 # avahi
39
 if test "$use_avahi" = "yes"; then
40
   AC_CHECK_LIB([avahi-common], [main],,
41
@@ -1924,6 +1946,12 @@ else
42
   final_message="$final_message\n  PulseAudio:\tNo"
43
 fi
44
 
45
+if test "$use_sndio" = "yes"; then
46
+  final_message="$final_message\n  Sndio Support:\tYes"
47
+else
48
+  final_message="$final_message\n  Sndio Support:\tNo"
49
+fi
50
+
51
 # Google Test Framework
52
 if test "$configure_gtest" = "yes"; then
53
   AC_MSG_NOTICE($gtest_enabled)
54
@@ -2247,6 +2275,8 @@ AC_SUBST(USE_AIRPLAY)
55
 AC_SUBST(USE_OPENMAX)
56
 AC_SUBST(USE_PULSE)
57
 AC_SUBST(HAVE_LIBPULSE)
58
+AC_SUBST(USE_SNDIO)
59
+AC_SUBST(HAVE_SNDIO)
60
 AC_SUBST(USE_ALSA)
61
 AC_SUBST(USE_TEXTUREPACKER)
62
 AC_SUBST(TEXTUREPACKER)
63
diff --git xbmc/cores/AudioEngine/AESinkFactory.cpp xbmc/cores/AudioEngine/AESinkFactory.cpp
64
index d7b05cdbfe..617b5dba83 100644
65
--- xbmc/cores/AudioEngine/AESinkFactory.cpp
66
+++ xbmc/cores/AudioEngine/AESinkFactory.cpp
67
@@ -36,6 +36,9 @@
68
   #if defined(HAS_ALSA)
69
     #include "Sinks/AESinkALSA.h"
70
   #endif
71
+  #if defined(HAS_SNDIO)
72
+    #include "Sinks/AESinkSNDIO.h"
73
+  #endif
74
   #if defined(TARGET_FREEBSD)
75
     #include "Sinks/AESinkOSS.h"
76
   #endif
77
@@ -77,6 +80,9 @@
78
   #if defined(HAS_ALSA)
79
         driver == "ALSA"        ||
80
   #endif
81
+  #if defined(HAS_SNDIO)
82
+        driver == "SNDIO"       ||
83
+  #endif
84
   #if defined(TARGET_FREEBSD)
85
         driver == "OSS"         ||
86
   #endif
87
@@ -116,11 +122,15 @@ IAESink *CAESinkFactory::TrySink(std::string &driver, std::string &device, AEAud
88
     sink = new CAESinkDARWINIOS();
89
 #elif defined(TARGET_DARWIN_OSX)
90
     sink = new CAESinkDARWINOSX();
91
-#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
92
+#elif defined(TARGET_LINUX) || defined(TARGET_FREEBSD) || defined(TARGET_OPENBSD)
93
  #if defined(HAS_PULSEAUDIO)
94
     if (driver == "PULSE")
95
       sink = new CAESinkPULSE();
96
  #endif
97
+ #if defined(HAS_SNDIO)
98
+    if (driver == "SNDIO")
99
+        sink = new CAESinkSNDIO();
100
+ #endif
101
  #if defined(HAS_ALSA)
102
     if (driver == "ALSA")
103
       sink = new CAESinkALSA();
104
@@ -236,6 +246,10 @@ void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force)
105
     if (envSink == "PULSE")
106
       CAESinkPULSE::EnumerateDevicesEx(info.m_deviceInfoList, force);
107
     #endif
108
+    #if defined(HAS_SNDIO)
109
+    if (envSink == "SNDIO")
110
+        CAESinkSNDIO::EnumerateDevicesEx(info.m_deviceInfoList, force);
111
+    #endif
112
     #if defined(HAS_ALSA)
113
     if (envSink == "ALSA")
114
       CAESinkALSA::EnumerateDevicesEx(info.m_deviceInfoList, force);
115
@@ -264,6 +278,17 @@ void CAESinkFactory::EnumerateEx(AESinkInfoList &list, bool force)
116
   }
117
   #endif
118
 
119
+  #if defined(HAS_SNDIO)
120
+  info.m_deviceInfoList.clear();
121
+  info.m_sinkName = "SNDIO";
122
+  CAESinkSNDIO::EnumerateDevicesEx(info.m_deviceInfoList, force);
123
+  if(!info.m_deviceInfoList.empty())
124
+  {
125
+      list.push_back(info);
126
+      return;
127
+  }
128
+  #endif
129
+
130
   #if defined(HAS_ALSA)
131
   info.m_deviceInfoList.clear();
132
   info.m_sinkName = "ALSA";
133
diff --git xbmc/cores/AudioEngine/Makefile.in xbmc/cores/AudioEngine/Makefile.in
134
index 7aab111f81..788786e2d1 100644
135
--- xbmc/cores/AudioEngine/Makefile.in
136
+++ xbmc/cores/AudioEngine/Makefile.in
137
@@ -55,6 +55,9 @@ SRCS += Sinks/AESinkOSS.cpp
138
 ifeq (@USE_PULSE@,1)
139
 SRCS += Sinks/AESinkPULSE.cpp
140
 endif
141
+ifeq (@USE_SNDIO@,1)
142
+SRCS += Sinks/AESinkSNDIO.cpp
143
+endif
144
 endif
145
 
146
 SRCS += DSPAddons/ActiveAEDSP.cpp
147
diff --git xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.cpp xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.cpp
148
new file mode 100644
149
index 0000000000..879b9a90a3
150
--- /dev/null
151
+++ xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.cpp
152
@@ -0,0 +1,313 @@
153
+/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
154
+/*
155
+ *      Copyright (C) 2010-2013 Team XBMC
156
+ *      http://xbmc.org
157
+ *
158
+ *  This Program is free software; you can redistribute it and/or modify
159
+ *  it under the terms of the GNU General Public License as published by
160
+ *  the Free Software Foundation; either version 2, or (at your option)
161
+ *  any later version.
162
+ *
163
+ *  This Program is distributed in the hope that it will be useful,
164
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
165
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
166
+ *  GNU General Public License for more details.
167
+ *
168
+ *  You should have received a copy of the GNU General Public License
169
+ *  along with XBMC; see the file COPYING.  If not, see
170
+ *  <http://www.gnu.org/licenses/>.
171
+ *
172
+ */
173
+
174
+#include "system.h"
175
+#ifdef HAS_SNDIO
176
+#include "AESinkSNDIO.h"
177
+#include "cores/AudioEngine/Utils/AEUtil.h"
178
+#include "utils/log.h"
179
+
180
+#include <sys/param.h>
181
+
182
+#ifndef nitems
183
+#define nitems(x) (sizeof((x))/sizeof((x)[0]))
184
+#endif
185
+
186
+static enum AEChannel channelMap[] =
187
+{
188
+  AE_CH_FL,
189
+  AE_CH_FR,
190
+  AE_CH_BL,
191
+  AE_CH_BR,
192
+  AE_CH_FC,
193
+  AE_CH_LFE,
194
+  AE_CH_SL,
195
+  AE_CH_SR,
196
+};
197
+
198
+struct sndio_formats
199
+{
200
+  AEDataFormat fmt;
201
+  unsigned int bits;
202
+  unsigned int bps;
203
+  unsigned int sig;
204
+  unsigned int le;
205
+  unsigned int msb;
206
+};
207
+
208
+static struct sndio_formats formats[] =
209
+{
210
+  { AE_FMT_S32LE, 32, 4, 1, 1, 1 },
211
+  { AE_FMT_S32BE, 32, 4, 1, 0, 1 },
212
+
213
+  { AE_FMT_S24LE4, 24, 4, 1, 1, 0 },
214
+  { AE_FMT_S24BE4, 24, 4, 1, 0, 0 },
215
+  { AE_FMT_S24LE4, 24, 4, 1, 1, 1 },
216
+  { AE_FMT_S24BE4, 24, 4, 1, 0, 1 },
217
+
218
+  { AE_FMT_S24LE3, 24, 3, 1, 1, 0 },
219
+  { AE_FMT_S24BE3, 24, 3, 1, 0, 0 },
220
+  { AE_FMT_S24LE3, 24, 3, 1, 1, 1 },
221
+  { AE_FMT_S24BE3, 24, 3, 1, 0, 1 },
222
+
223
+  { AE_FMT_S16LE, 16, 2, 1, 1, 1 },
224
+  { AE_FMT_S16LE, 16, 2, 1, 1, 0 },
225
+  { AE_FMT_S16BE, 16, 2, 1, 0, 1 },
226
+  { AE_FMT_S16BE, 16, 2, 1, 0, 0 },
227
+
228
+  { AE_FMT_U8, 8, 1, 0, 0, 0 },
229
+  { AE_FMT_U8, 8, 1, 0, 0, 1 },
230
+  { AE_FMT_U8, 8, 1, 0, 1, 0 },
231
+  { AE_FMT_U8, 8, 1, 0, 1, 1 },
232
+};
233
+
234
+static AEDataFormat lookupDataFormat(int bits, int bps, int sig, int le, int msb)
235
+{
236
+  for (size_t i = 0; i < nitems(formats); i++)
237
+  {
238
+    if (bits == formats[i].bits &&
239
+        bps == formats[i].bps &&
240
+        sig == formats[i].sig &&
241
+        le == formats[i].le &&
242
+        msb == formats[i].msb)
243
+    {
244
+      return formats[i].fmt;
245
+    }
246
+  }
247
+  return AE_FMT_INVALID;
248
+}
249
+
250
+void CAESinkSNDIO::AudioFormatToPar(AEAudioFormat& format)
251
+{
252
+  sio_initpar(&par);
253
+
254
+  par.rate = format.m_sampleRate;
255
+  par.xrun = SIO_IGNORE;
256
+  par.pchan = format.m_channelLayout.Count();
257
+
258
+  for (size_t i = 0; i < nitems(formats); i++)
259
+  {
260
+    if (formats[i].fmt == format.m_dataFormat)
261
+    {
262
+      par.bits = formats[i].bits;
263
+      par.sig = formats[i].sig;
264
+      par.le = formats[i].le;
265
+      par.msb = formats[i].msb;
266
+      par.bps = formats[i].bps;
267
+      return;
268
+    }
269
+  }
270
+
271
+  /* Default to AE_FMT_S16LE */
272
+  par.bits = 16;
273
+  par.bps = SIO_BPS(16);
274
+  par.sig = 1;
275
+  par.le = 1;
276
+  par.msb = 0;
277
+}
278
+
279
+bool CAESinkSNDIO::ParToAudioFormat(AEAudioFormat& format)
280
+{
281
+  AEDataFormat dataFormat = lookupDataFormat(par.bits, par.bps, par.sig, par.le, par.msb);
282
+  if (dataFormat == AE_FMT_INVALID)
283
+  {
284
+    CLog::Log(LOGERROR, "CAESinkSNDIO::ParToAudioFormat - invalid data format");
285
+    return false;
286
+  }
287
+
288
+  if (par.pchan > nitems(channelMap))
289
+  {
290
+    CLog::Log(LOGERROR, "CAESinkSNDIO::ParToAudioFormat - too many channels: %d", par.pchan);
291
+    return false;
292
+  }
293
+
294
+  CAEChannelInfo info;
295
+  for (unsigned int i = 0; i < par.pchan; i++)
296
+      info += channelMap[i];
297
+  format.m_channelLayout = info;
298
+  format.m_dataFormat = dataFormat;
299
+  format.m_sampleRate = par.rate;
300
+  format.m_frameSize = par.bps * par.pchan;
301
+  format.m_frames = par.bufsz / format.m_frameSize;
302
+
303
+  return true;
304
+}
305
+
306
+CAESinkSNDIO::CAESinkSNDIO()
307
+{
308
+  m_hdl = nullptr;
309
+}
310
+
311
+CAESinkSNDIO::~CAESinkSNDIO()
312
+{
313
+  Deinitialize();
314
+}
315
+
316
+bool CAESinkSNDIO::Initialize(AEAudioFormat &format, std::string &device)
317
+{
318
+  if ((m_hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0)) == nullptr)
319
+  {
320
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - Failed to open device");
321
+    return false;
322
+  }
323
+
324
+  AudioFormatToPar(format);
325
+  if (!sio_setpar(m_hdl, &par) ||
326
+      !sio_getpar(m_hdl, &par) ||
327
+      !ParToAudioFormat(format))
328
+  {
329
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - could not negotiate parameters");
330
+    return false;
331
+  }
332
+
333
+  played = written = 0;
334
+
335
+  sio_onmove(m_hdl, CAESinkSNDIO::OnmoveCb, this);
336
+
337
+  if (!sio_start(m_hdl))
338
+  {
339
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - sio_start failed");
340
+    return false;
341
+  }
342
+
343
+  return true;
344
+}
345
+
346
+void CAESinkSNDIO::Deinitialize()
347
+{
348
+  if (m_hdl != nullptr)
349
+  {
350
+    sio_close(m_hdl);
351
+    m_hdl = nullptr;
352
+  }
353
+}
354
+
355
+void CAESinkSNDIO::Stop()
356
+{
357
+  if (!m_hdl)
358
+    return;
359
+
360
+  if (!sio_stop(m_hdl))
361
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Stop - Failed");
362
+
363
+  written = played = 0;
364
+}
365
+
366
+void CAESinkSNDIO::OnmoveCb(void *arg, int delta) {
367
+  CAESinkSNDIO* self = static_cast<CAESinkSNDIO*>(arg);
368
+  self->played += delta;
369
+}
370
+
371
+void CAESinkSNDIO::GetDelay(AEDelayStatus& status)
372
+{
373
+  unsigned int frameSize = par.bps * par.pchan;
374
+  double delay = 1.0 * ((written / frameSize) - played) / par.rate;
375
+  status.SetDelay(delay);
376
+}
377
+
378
+unsigned int CAESinkSNDIO::AddPackets(uint8_t **data, unsigned int frames, unsigned int offset)
379
+{
380
+  if (!m_hdl)
381
+    return INT_MAX;
382
+
383
+  unsigned int frameSize = par.bps * par.pchan;
384
+  size_t size = frames * frameSize;
385
+  void *buffer = data[0] + offset * frameSize;
386
+  size_t wrote = sio_write(m_hdl, buffer, size);
387
+  written += wrote;
388
+  return wrote / frameSize;
389
+}
390
+
391
+void CAESinkSNDIO::Drain()
392
+{
393
+  if(!m_hdl)
394
+    return;
395
+
396
+  if (!sio_stop(m_hdl) || !sio_start(m_hdl))
397
+    CLog::Log(LOGERROR, "CAESinkSNDIO::Drain - failed");
398
+
399
+  written = played = 0;
400
+}
401
+
402
+void CAESinkSNDIO::EnumerateDevicesEx(AEDeviceInfoList &list, bool force)
403
+{
404
+  struct sio_hdl *hdl;
405
+  struct sio_cap cap;
406
+
407
+  if ((hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0)) == nullptr)
408
+  {
409
+    CLog::Log(LOGERROR, "CAESinkSNDIO::EnumerateDevicesEx - sio_open");
410
+    return;
411
+  }
412
+
413
+  if (!sio_getcap(hdl, &cap))
414
+  {
415
+    CLog::Log(LOGERROR, "CAESinkSNDIO::EnumerateDevicesEx - sio_getcap");
416
+    return;
417
+  }
418
+
419
+  sio_close(hdl);
420
+  hdl = nullptr;
421
+
422
+  for (unsigned int i = 0; i < cap.nconf; i++)
423
+  {
424
+    CAEDeviceInfo info;
425
+    sio_cap::sio_conf conf = cap.confs[i];
426
+
427
+    info.m_deviceName = SIO_DEVANY;
428
+    info.m_displayName = "sndio";
429
+    info.m_displayNameExtra = "#" + std::to_string(i);
430
+    info.m_deviceType = AE_DEVTYPE_PCM;
431
+
432
+    unsigned int maxchan = 0;
433
+    for (unsigned int j = 0; j < SIO_NCHAN; j++)
434
+    {
435
+      if (conf.pchan & (1 << j))
436
+        maxchan = MAX(maxchan, cap.pchan[j]);
437
+    }
438
+
439
+    maxchan = MIN(maxchan, nitems(channelMap));
440
+    for (unsigned int j = 0; j < maxchan; j++)
441
+      info.m_channels += channelMap[j];
442
+
443
+    for (unsigned int j = 0; j < SIO_NRATE; j++)
444
+    {
445
+      if (conf.rate & (1 << j))
446
+      {
447
+        info.m_sampleRates.push_back(cap.rate[j]);
448
+      }
449
+    }
450
+
451
+    for (unsigned int j = 0; j < SIO_NENC; j++)
452
+    {
453
+      if (conf.enc & (1 << j))
454
+      {
455
+        AEDataFormat format = lookupDataFormat(cap.enc[j].bits, cap.enc[j].bps, cap.enc[j].sig, cap.enc[j].le, cap.enc[j].msb);
456
+        if (format != AE_FMT_INVALID)
457
+          info.m_dataFormats.push_back(format);
458
+      }
459
+    }
460
+
461
+    list.push_back(info);
462
+  }
463
+}
464
+
465
+#endif
466
diff --git xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.h xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.h
467
new file mode 100644
468
index 0000000000..55719cd305
469
--- /dev/null
470
+++ xbmc/cores/AudioEngine/Sinks/AESinkSNDIO.h
471
@@ -0,0 +1,57 @@
472
+/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
473
+#pragma once
474
+/*
475
+ *      Copyright (C) 2010-2013 Team XBMC
476
+ *      http://xbmc.org
477
+ *
478
+ *  This Program is free software; you can redistribute it and/or modify
479
+ *  it under the terms of the GNU General Public License as published by
480
+ *  the Free Software Foundation; either version 2, or (at your option)
481
+ *  any later version.
482
+ *
483
+ *  This Program is distributed in the hope that it will be useful,
484
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
485
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
486
+ *  GNU General Public License for more details.
487
+ *
488
+ *  You should have received a copy of the GNU General Public License
489
+ *  along with XBMC; see the file COPYING.  If not, see
490
+ *  <http://www.gnu.org/licenses/>.
491
+ *
492
+ */
493
+
494
+#include "cores/AudioEngine/Interfaces/AESink.h"
495
+#include "cores/AudioEngine/Utils/AEDeviceInfo.h"
496
+#include <stdint.h>
497
+#include <sndio.h>
498
+
499
+#include "threads/CriticalSection.h"
500
+
501
+class CAESinkSNDIO : public IAESink
502
+{
503
+public:
504
+  virtual const char *GetName() { return "sndio"; }
505
+
506
+  CAESinkSNDIO();
507
+  virtual ~CAESinkSNDIO();
508
+
509
+  virtual bool Initialize(AEAudioFormat &format, std::string &device);
510
+  virtual void Deinitialize();
511
+
512
+  virtual void Stop();
513
+  virtual void GetDelay(AEDelayStatus& status);
514
+  virtual double GetCacheTotal() { return 0.0; }
515
+  virtual unsigned int AddPackets(uint8_t **data, unsigned int frames, unsigned int offset);
516
+  virtual void Drain();
517
+  static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false);
518
+private:
519
+  void AudioFormatToPar(AEAudioFormat& format);
520
+  bool ParToAudioFormat(AEAudioFormat& format);
521
+  static void OnmoveCb(void *arg, int delta);
522
+
523
+  struct sio_hdl *m_hdl;
524
+  struct sio_par par;
525
+  ssize_t played;
526
+  ssize_t written;
527
+};
528
+
529
diff --git xbmc/system.h xbmc/system.h
530
index d426ade093..ed01ab53fd 100644
531
--- xbmc/system.h
532
+++ xbmc/system.h
533
@@ -172,6 +172,9 @@
534
 #ifdef HAVE_LIBPULSE
535
 #define HAS_PULSEAUDIO
536
 #endif
537
+#ifdef HAVE_SNDIO
538
+#define HAS_SNDIO
539
+#endif
540
 #ifdef HAVE_ALSA
541
 #define HAS_ALSA
542
 #endif

Return to bug 220231