Files
extra/ptlib/sndio.patch
2025-06-22 20:39:04 -05:00

927 lines
24 KiB
Diff

diff --git a/configure b/configure
index 4c68d59..a872544 100755
--- a/configure
+++ b/configure
@@ -852,6 +852,7 @@ enable_dc
enable_vfw
enable_alsa
enable_oss
+enable_sndio
enable_pulse
enable_memcheck
enable_odbc
@@ -1548,6 +1549,7 @@ Optional Features:
--enable-vfw enable video for windows capture
--enable-alsa enable ALSA audio support
--enable-oss enable OSS audio support
+ --enable-sndio enable SNDIO audio support
--enable-pulse enable PULSE audio support
--enable-memcheck enable leak testing code (off by default)
--disable-odbc disable ODBC support
@@ -10253,6 +10255,11 @@ if test "${enable_oss+set}" = set; then :
enableval=$enable_oss; enable_oss=$enableval
fi
+ # Check whether --enable-sndio was given.
+if test "${enable_sndio+set}" = set; then :
+ enableval=$enable_sndio; enable_sndio=$enableval
+fi
+
# Check whether --enable-pulse was given.
if test "${enable_pulse+set}" = set; then :
enableval=$enable_pulse; enable_pulse=$enableval
diff --git a/configure.ac b/configure.ac
index 74d5921..222021e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1623,6 +1623,7 @@ if test "x${HAS_AUDIO}" = "x1" ; then
dnl these are needed to pass through to the plugin configure program
AC_ARG_ENABLE(alsa, [ --enable-alsa enable ALSA audio support],enable_alsa=$enableval)
AC_ARG_ENABLE(oss, [ --enable-oss enable OSS audio support],enable_oss=$enableval)
+ AC_ARG_ENABLE(sndio, [ --enable-sndio enable SNDIO audio support],enable_sndio=$enableval)
AC_ARG_ENABLE(pulse, [ --enable-pulse enable PULSE audio support],enable_pulse=$enableval)
fi
diff --git a/plugins/Makefile.in b/plugins/Makefile.in
index d613f36..c679671 100644
--- a/plugins/Makefile.in
+++ b/plugins/Makefile.in
@@ -51,6 +51,16 @@ DEFAULT_SOUND = sound_esd
endif
endif
+###################################SNDIO
+HAS_SNDIO = @HAS_SNDIO@
+
+ifeq (1,$(HAS_SNDIO))
+SUBDIRS += sound_sndio
+ifeq (,$(DEFAULT_SOUND))
+DEFAULT_SOUND = sound_sndio
+endif
+endif
+
#################################SundAudio
HAS_SUNAUDIO = @HAS_SUNAUDIO@
diff --git a/plugins/configure b/plugins/configure
index da4858b..c47a09d 100644
--- a/plugins/configure
+++ b/plugins/configure
@@ -648,6 +648,7 @@ HAS_V4L
HAS_AUDIOSHM
HAS_SUNAUDIO
HAS_PULSE
+HAS_SNDIO
HAS_OSS
HAS_ESD
HAS_ALSA
@@ -723,6 +724,7 @@ enable_audio
enable_alsa
enable_esd
enable_oss
+enable_sndio
enable_pulse
enable_sunaudio
enable_shmaudio
@@ -1374,6 +1376,7 @@ disable plugin support]
--enable-alsa enable ALSA audio support
--enable-esd enable ESD audio support
--enable-oss enable OSS audio support
+ --enable-sndio enable sndio audio support
--enable-pulse enable Pulse audio support
--enable-sunaudio enable Sun audio support
--enable-shmaudio enable shm audio support
@@ -4425,6 +4428,161 @@ $as_echo "no" >&6; }
fi
+# Check whether --enable-sndio was given.
+if test "${enable_sndio+set}" = set; then
+ enableval=$enable_sndio;
+else
+ enable_sndio=yes
+fi
+
+
+if test "${enable_sndio}z" = "yesz" ; then
+ if test "${ac_cv_header_sndio_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for sndio.h" >&5
+$as_echo_n "checking for sndio.h... " >&6; }
+if test "${ac_cv_header_sndio_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_sndio_h" >&5
+$as_echo "$ac_cv_header_sndio_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking sndio.h usability" >&5
+$as_echo_n "checking sndio.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <sndio.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking sndio.h presence" >&5
+$as_echo_n "checking sndio.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sndio.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: sndio.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: sndio.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sndio.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: sndio.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: sndio.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: sndio.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sndio.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: sndio.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sndio.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: sndio.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sndio.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: sndio.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sndio.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: sndio.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: sndio.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: sndio.h: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for sndio.h" >&5
+$as_echo_n "checking for sndio.h... " >&6; }
+if test "${ac_cv_header_sndio_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_sndio_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_sndio_h" >&5
+$as_echo "$ac_cv_header_sndio_h" >&6; }
+
+fi
+if test "x$ac_cv_header_sndio_h" = x""yes; then
+ SNDCARDHDR=1
+fi
+
+
+ { $as_echo "$as_me:$LINENO: checking for sndio sound support" >&5
+$as_echo_n "checking for sndio sound support... " >&6; }
+ if test "${SNDCARDHDR}z" != "z"; then
+ HAS_SNDIO=1
+
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+
+
# Check whether --enable-pulse was given.
if test "${enable_pulse+set}" = set; then
enableval=$enable_pulse;
diff --git a/plugins/configure.in b/plugins/configure.in
index 47a16bf..681043c 100644
--- a/plugins/configure.in
+++ b/plugins/configure.in
@@ -107,6 +107,23 @@ if test "${enable_pulse}z" = "yesz" ; then
fi
dnl #########################################################################
+dnl check for sndio sound support
+dnl ########################################################################
+
+AC_ARG_ENABLE(sndio, [ --enable-sndio enable sndio audio support],,enable_sndio=no)
+
+if test "${enable_sndio}z" = "yesz" ; then
+ AC_CHECK_HEADER(sndio.h, SNDCARDHDR=1)
+ AC_MSG_CHECKING(for sndio sound support)
+ if test "${SNDCARDHDR}z" != "z"; then
+ AC_SUBST(HAS_SNDIO, 1)
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+
+dnl #########################################################################
dnl check for sunaudio sound support
dnl ########################################################################
diff --git b/plugins/sound_sndio/Makefile b/plugins/sound_sndio/Makefile
new file mode 100644
index 0000000..fd15500
--- /dev/null
+++ b/plugins/sound_sndio/Makefile
@@ -0,0 +1,7 @@
+
+PLUGIN_NAME = sndio
+PLUGIN_FAMILY = device/sound
+PLUGIN_LIBS = -lsndio
+PLUGIN_SOURCES = sound_sndio.cxx
+
+include ../../make/plugins.mak
diff --git b/plugins/sound_sndio/sound_sndio.cxx b/plugins/sound_sndio/sound_sndio.cxx
new file mode 100644
index 0000000..a581033
--- /dev/null
+++ b/plugins/sound_sndio/sound_sndio.cxx
@@ -0,0 +1,534 @@
+/*
+ * sound_sndio.cxx
+ *
+ * Sound driver implementation.
+ *
+ * Portable Windows Library
+ *
+ * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is Portable Windows Library.
+ *
+ * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
+ *
+ * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
+ * All Rights Reserved.
+ *
+ * $Log: sound_sndio.cxx,v $
+ * Revision 1.2 2010/05/11 07:23:23 espie
+ * make it compile on gcc4, by making the relevant patch dependent on
+ * compiler version.
+ * also removes lvalue cast, that's not ansi.
+ *
+ * Revision 1.1.1.1 2010/03/23 21:10:17 ajacoutot
+ * Import ptlib-2.6.5
+ *
+ * PTLib is a moderately large C++ class library that originated many years
+ * ago as a method to produce applications that run on both Microsoft
+ * Windows and Unix X-Windows systems. It also was to have a Macintosh port
+ * as well, but this never eventuated. In those days it was called the
+ * PWLib the Portable Windows Library.
+ *
+ * Since then, the availability of multi-platform GUI toolkits such as KDE
+ * and wxWindows, and the development of the OpenH323 and OPAL projects as
+ * primary user of the library, has emphasised the focus on networking, I/O
+ * portability, multi-threading and protocol portability. Mostly, the
+ * library is used to create high performance and highly portable
+ * network-centric applications. So all the GUI abstractions ahave been
+ * dropped and it was renamed the Portable Tools Library that you see
+ * today.
+ *
+ * Revision 1.3 2009/06/01 22:19:23 ajacoutot
+ * - aucat.sock is no more
+ *
+ * spotted by robert@ on ekiga
+ *
+ * Revision 1.2 2009/01/19 09:42:21 ajacoutot
+ * - s/SNDIO/SNDIO for consistency
+ * discussed with naddy@
+ *
+ * "sure" jakemsr@
+ *
+ * Revision 1.1 2009/01/17 12:30:08 jakemsr
+ * - add sndio backend
+ * - remove OSS and esd support
+ * ok ajacoutot@ (MAINTAINER)
+ *
+ */
+
+#pragma implementation "sound_sndio.h"
+
+#include "sound_sndio.h"
+
+#include <sys/poll.h>
+
+PCREATE_SOUND_PLUGIN(SNDIO, PSoundChannelSNDIO);
+
+PSoundChannelSNDIO::PSoundChannelSNDIO()
+{
+ PSoundChannelSNDIO::Construct();
+}
+
+
+PSoundChannelSNDIO::PSoundChannelSNDIO(const PString & device,
+ Directions dir,
+ unsigned numChannels,
+ unsigned sampleRate,
+ unsigned bitsPerSample)
+{
+ Construct();
+ Open(device, dir, numChannels, sampleRate, bitsPerSample);
+}
+
+
+void PSoundChannelSNDIO::Construct()
+{
+ os_handle = -1;
+ hdl = NULL;
+}
+
+
+PSoundChannelSNDIO::~PSoundChannelSNDIO()
+{
+ Close();
+}
+
+
+PStringArray PSoundChannelSNDIO::GetDeviceNames(Directions)
+{
+ static const char * const devices[] = {
+ "default",
+ "/dev/audio0",
+ "/dev/audio1",
+ "/dev/audio2"
+ };
+
+ return PStringArray(PARRAYSIZE(devices), devices);
+}
+
+
+PString PSoundChannelSNDIO::GetDefaultDevice(Directions dir)
+{
+ return "default";
+}
+
+PBoolean PSoundChannelSNDIO::Open(const PString & device,
+ Directions dir,
+ unsigned numChannels,
+ unsigned sampleRate,
+ unsigned bitsPerSample)
+{
+ uint mode;
+ char sio_device[32];
+
+ Close();
+
+ if (dir == Recorder)
+ mode = SIO_REC;
+ else
+ mode = SIO_PLAY;
+
+ snprintf(sio_device, 32, "%s", (const char *)device);
+
+ if (strncmp(sio_device, "default", 7) == 0)
+ hdl = sio_open(NULL, mode, 0);
+ else
+ hdl = sio_open(sio_device, mode, 0);
+
+ if (hdl == NULL) {
+ printf("sio_open failed\n");
+ return FALSE;
+ }
+
+ mDirection = dir;
+ mDevice = device;
+ mSampleRate = sampleRate;
+ mNumChannels = numChannels;
+ mBitsPerSample = bitsPerSample;
+ mBytesPerFrame = (bitsPerSample / 8) * numChannels;
+
+ isInitialised = FALSE;
+
+ return TRUE;
+}
+
+PBoolean PSoundChannelSNDIO::Setup()
+{
+ if (!hdl) {
+ PTRACE(6, "SNDIO\tSkipping setup of " << mDevice << " as not open");
+ return FALSE;
+ }
+
+ if (isInitialised) {
+ PTRACE(6, "SNDIO\tSkipping setup of " << mDevice << " as instance already initialised");
+ return TRUE;
+ }
+
+ PTRACE(6, "SNDIO\tInitialising " << mDevice);
+
+ sio_initpar(&par);
+
+ int framesPerFrag = mFragSize / mBytesPerFrame;
+ par.bufsz = mFragCount * framesPerFrag;
+ par.round = framesPerFrag;
+
+ par.bits = mBitsPerSample;
+ par.sig = 1;
+#if PBYTE_ORDER == PLITTLE_ENDIAN
+ par.le = 1;
+#else
+ par.le = 0;
+#endif
+
+ if (mDirection == Recorder)
+ par.rchan = mNumChannels;
+ else
+ par.pchan = mNumChannels;
+
+ par.rate = mSampleRate;
+
+ if (!sio_setpar(hdl, &par)) {
+ printf("sio_setpar failed\n");
+ return FALSE;
+ }
+
+ if (!sio_getpar(hdl, &par)) {
+ printf("sio_getpar failed\n");
+ return FALSE;
+ }
+
+ mFragSize = par.round * mBytesPerFrame;
+ mFragCount = par.bufsz / par.round;
+
+ if (!sio_start(hdl)) {
+ printf("sio_start failed\n");
+ return FALSE;
+ }
+
+ isInitialised = TRUE;
+
+ return TRUE;
+}
+
+PBoolean PSoundChannelSNDIO::Close()
+{
+ if (!hdl)
+ return TRUE;
+
+ sio_close(hdl);
+ hdl = NULL;
+ return PChannel::Close();
+}
+
+PBoolean PSoundChannelSNDIO::IsOpen() const
+{
+ return (hdl != NULL);
+}
+
+PBoolean PSoundChannelSNDIO::Write(const void * buf, PINDEX len)
+{
+ lastWriteCount = 0;
+
+ if (!Setup() || !hdl)
+ return FALSE;
+
+ int did, tot = 0;
+
+ while (len > 0) {
+ did = sio_write(hdl, (void *)buf, len);
+ if (did == 0) {
+ printf("sio_write failed\n");
+ return FALSE;
+ }
+ len -= did;
+ buf = (char*)buf + did;
+ tot += did;
+ }
+ lastWriteCount += tot;
+
+ return TRUE;
+}
+
+PBoolean PSoundChannelSNDIO::Read(void * buf, PINDEX len)
+{
+ lastReadCount = 0;
+
+ if (!Setup() || !hdl)
+ return FALSE;
+
+ int did, tot = 0;
+
+ while (len > 0) {
+ did = sio_read(hdl, buf, len);
+ if (did == 0) {
+ printf("sio_read failed\n");
+ return FALSE;
+ }
+ len -= did;
+ buf = (char*)buf + did;
+ tot += did;
+ }
+ lastReadCount += tot;
+
+ return TRUE;
+}
+
+
+PBoolean PSoundChannelSNDIO::SetFormat(unsigned numChannels,
+ unsigned sampleRate,
+ unsigned bitsPerSample)
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ PAssert((bitsPerSample == 8) || (bitsPerSample == 16), PInvalidParameter);
+ PAssert(numChannels >= 1 && numChannels <= 2, PInvalidParameter);
+
+ if (isInitialised) {
+ if ((numChannels != mNumChannels) ||
+ (sampleRate != mSampleRate) ||
+ (bitsPerSample != mBitsPerSample)) {
+ PTRACE(6, "SNDIO\tTried to change read/write format without stopping");
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ mNumChannels = numChannels;
+ mSampleRate = sampleRate;
+ mBitsPerSample = bitsPerSample;
+ isInitialised = FALSE;
+
+ return TRUE;
+}
+
+
+unsigned PSoundChannelSNDIO::GetChannels() const
+{
+ return mNumChannels;
+}
+
+
+unsigned PSoundChannelSNDIO::GetSampleRate() const
+{
+ return mSampleRate;
+}
+
+
+unsigned PSoundChannelSNDIO::GetSampleSize() const
+{
+ return mBitsPerSample;
+}
+
+
+PBoolean PSoundChannelSNDIO::SetBuffers(PINDEX size, PINDEX count)
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ PAssert(size > 0 && count > 0 && count < 65536, PInvalidParameter);
+
+ if (isInitialised) {
+ if (mFragSize != (unsigned)size || mFragCount != (unsigned)count) {
+ PTRACE(6, "SNDIO\tTried to change buffers without stopping");
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ mFragSize = size;
+ mFragCount = count;
+ isInitialised = FALSE;
+
+ return TRUE;
+}
+
+
+PBoolean PSoundChannelSNDIO::GetBuffers(PINDEX & size, PINDEX & count)
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ count = mFragCount;
+ size = mFragSize;
+
+ return TRUE;
+}
+
+
+PBoolean PSoundChannelSNDIO::PlaySound(const PSound & sound, PBoolean wait)
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ if (!Write((const BYTE *)sound, sound.GetSize()))
+ return FALSE;
+
+ if (wait)
+ return WaitForPlayCompletion();
+
+ return TRUE;
+}
+
+
+PBoolean PSoundChannelSNDIO::PlayFile(const PFilePath & filename, PBoolean wait)
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ PFile file(filename, PFile::ReadOnly);
+ if (!file.IsOpen())
+ return FALSE;
+
+ for (;;) {
+ BYTE buffer[256];
+ if (!file.Read(buffer, 256))
+ break;
+ PINDEX len = file.GetLastReadCount();
+ if (len == 0)
+ break;
+ if (!Write(buffer, len))
+ break;
+ }
+
+ file.Close();
+
+ if (wait)
+ return WaitForPlayCompletion();
+
+ return TRUE;
+}
+
+
+PBoolean PSoundChannelSNDIO::HasPlayCompleted()
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ return TRUE;
+}
+
+
+PBoolean PSoundChannelSNDIO::WaitForPlayCompletion()
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ return TRUE;
+}
+
+
+PBoolean PSoundChannelSNDIO::RecordSound(PSound & sound)
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ return FALSE;
+}
+
+
+PBoolean PSoundChannelSNDIO::RecordFile(const PFilePath & filename)
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ return FALSE;
+}
+
+
+PBoolean PSoundChannelSNDIO::StartRecording()
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ return TRUE;
+}
+
+
+PBoolean PSoundChannelSNDIO::IsRecordBufferFull()
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ struct pollfd pfd;
+ int events = POLLIN;
+ sio_pollfd(hdl, &pfd, events);
+ return ConvertOSError(::poll(&pfd, 1, 0));
+}
+
+
+PBoolean PSoundChannelSNDIO::AreAllRecordBuffersFull()
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ struct pollfd pfd;
+ int events = POLLIN;
+ sio_pollfd(hdl, &pfd, events);
+ return ConvertOSError(::poll(&pfd, 1, 0));
+}
+
+
+PBoolean PSoundChannelSNDIO::WaitForRecordBufferFull()
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ // return PXSetIOBlock(PXReadBlock, readTimeout);
+
+ struct pollfd pfd;
+ int events = POLLIN;
+ sio_pollfd(hdl, &pfd, events);
+ return ConvertOSError(::poll(&pfd, 1, 1000));
+}
+
+
+PBoolean PSoundChannelSNDIO::WaitForAllRecordBuffersFull()
+{
+ if (!hdl)
+ return SetErrorValues(NotOpen, EBADF);
+
+ struct pollfd pfd;
+ int events = POLLIN;
+ sio_pollfd(hdl, &pfd, events);
+ return ConvertOSError(::poll(&pfd, 1, 1000));
+}
+
+
+PBoolean PSoundChannelSNDIO::Abort()
+{
+ return TRUE;
+}
+
+
+PBoolean PSoundChannelSNDIO::SetVolume(unsigned newVal)
+{
+ if (!hdl)
+ return FALSE;
+
+ return FALSE;
+}
+
+
+PBoolean PSoundChannelSNDIO::GetVolume(unsigned &devVol)
+{
+ if (!hdl)
+ return FALSE;
+
+ devVol = 0;
+ return FALSE;
+}
+
+
+
+// End of file
diff --git b/plugins/sound_sndio/sound_sndio.h b/plugins/sound_sndio/sound_sndio.h
new file mode 100644
index 0000000..6fc8325
--- /dev/null
+++ b/plugins/sound_sndio/sound_sndio.h
@@ -0,0 +1,66 @@
+
+#include <ptlib.h>
+#include <ptlib/sound.h>
+#include <ptlib/socket.h>
+
+#include <sndio.h>
+
+class PSoundChannelSNDIO: public PSoundChannel
+{
+ public:
+ PSoundChannelSNDIO();
+ void Construct();
+ PSoundChannelSNDIO(const PString &device,
+ PSoundChannel::Directions dir,
+ unsigned numChannels,
+ unsigned sampleRate,
+ unsigned bitsPerSample);
+ ~PSoundChannelSNDIO();
+ static PStringArray GetDeviceNames(PSoundChannel::Directions = Player);
+ static PString GetDefaultDevice(PSoundChannel::Directions);
+ PBoolean Open(const PString & _device,
+ Directions _dir,
+ unsigned _numChannels,
+ unsigned _sampleRate,
+ unsigned _bitsPerSample);
+ PBoolean Setup();
+ PBoolean Close();
+ PBoolean IsOpen() const;
+ PBoolean Write(const void * buf, PINDEX len);
+ PBoolean Read(void * buf, PINDEX len);
+ PBoolean SetFormat(unsigned numChannels,
+ unsigned sampleRate,
+ unsigned bitsPerSample);
+ unsigned GetChannels() const;
+ unsigned GetSampleRate() const;
+ unsigned GetSampleSize() const;
+ PBoolean SetBuffers(PINDEX size, PINDEX count);
+ PBoolean GetBuffers(PINDEX & size, PINDEX & count);
+ PBoolean PlaySound(const PSound & sound, PBoolean wait);
+ PBoolean PlayFile(const PFilePath & filename, PBoolean wait);
+ PBoolean HasPlayCompleted();
+ PBoolean WaitForPlayCompletion();
+ PBoolean RecordSound(PSound & sound);
+ PBoolean RecordFile(const PFilePath & filename);
+ PBoolean StartRecording();
+ PBoolean IsRecordBufferFull();
+ PBoolean AreAllRecordBuffersFull();
+ PBoolean WaitForRecordBufferFull();
+ PBoolean WaitForAllRecordBuffersFull();
+ PBoolean Abort();
+ PBoolean SetVolume(unsigned newVal);
+ PBoolean GetVolume(unsigned &devVol);
+
+ protected:
+ struct sio_hdl *hdl;
+ struct sio_par par;
+ unsigned mNumChannels;
+ unsigned mSampleRate;
+ unsigned mBitsPerSample;
+ unsigned mFragCount;
+ unsigned mFragSize;
+ unsigned mBytesPerFrame;
+ Directions mDirection;
+ PString mDevice;
+ PBoolean isInitialised;
+};
diff --git a/src/Makefile b/src/Makefile
index 0ac1c3b..99b66c2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -151,7 +151,12 @@ endif # linux
ifdef HAS_ALSA
VPATH_CXX += $(PLUGIN_DIR)/sound_alsa
SOURCES += $(PLUGIN_DIR)/sound_alsa/sound_alsa.cxx
-endif # HAS_ALSA
+
+endif # HAS_SNDIO
+ifdef HAS_SNDIO
+VPATH_CXX += $(PLUGIN_DIR)/sound_sndio
+SOURCES += $(PLUGIN_DIR)/sound_sndio/sound_sndio.cxx
+endif # HAS_SNDIO
ifeq ($(OSTYPE),beos)
SOURCES += $(PLATFORM_SRC_DIR)/beaudio.cxx