Subject: pkg/28352: rplayd cant play 16 bit stereo 44100 sample rate
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: None <ole.hellqvist@spray.se>
List: pkgsrc-bugs
Date: 11/18/2004 21:54:00
>Number: 28352
>Category: pkg
>Synopsis: rplayd cant play 16 bit stereo 44100 sample rate
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: pkg-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Nov 18 21:54:00 +0000 2004
>Originator: Ole
>Release: NetBSD 2.0B
>Organization:
>Environment:
NetBSD ak73.oxen 2.0B NetBSD 2.0B (AKKERNEL) #0: Mon Apr 12 20:13:09 CEST 2004 ole@ak73.oxen:/src/sys/arch/i386/compile/AKKERNEL i386
>Description:
due to the line:
"CONFIGURE_ENV+= RPLAY_TARGET=generic"
in the Makefile Rplayd can only play :
8000, RPLAY_FORMAT_ULAW, 1, 1
as stated in audio_generic.c
>How-To-Repeat:
Play anything recorded with higher sample rate and stereo using "rplay" and look at the output of "audioctl -a" at the server side.
>Fix:
remove the "CONFIGURE_ENV+= " line from Makefile,
change patch "patch-ab" as below, run autoconf, remake patch: "patch-ar".
add new patches; patch-ca, patch-cb, patch-cc.
ab:
"
--- configure.in.orig Wed Jun 9 08:26:28 1999
+++ configure.in Sun Nov 7 11:31:36 2004
@@ -59,6 +59,7 @@
AC_HEADER_TIME
dnl AC_PATH_XTRA
AC_CHECK_HEADERS(fcntl.h sys/file.h sys/ioctl.h sys/time.h stdlib.h unistd.h memory.h string.h strings.h utime.h limits.h gsm.h gsm/gsm.h rxposix.h rx/rxposix.h)
+AC_CHECK_HEADERS(readline.h history.h readline/readline.h readline/history.h)
AC_HEADER_SYS_WAIT
dnl Check for typedefs, structures, and compiler characteristics.
@@ -74,7 +75,20 @@
AC_CHECK_LIB(socket, socket, [LIBS="$LIBS -lsocket"])
AC_CHECK_LIB(nsl, t_accept, [LIBS="$LIBS -lnsl"])
-AC_CHECK_LIB(readline, readline, [RL_LIBS="-lreadline"])
+if test "$ac_cv_header_readline_h" = "yes" ||
+ test "$ac_cv_header_readline_readline_h" = "yes"; then
+ AC_CHECK_LIB(termcap, tputs,
+ [AC_CHECK_LIB(edit, readline,
+ [AC_DEFINE(HAVE_LIBEDIT)
+ AC_DEFINE(HAVE_READLINE)
+ RL_LIBS="-ledit -ltermcap"],
+ [AC_CHECK_LIB(readline, readline,
+ [AC_DEFINE(HAVE_LIBREADLINE)
+ AC_DEFINE(HAVE_READLINE)
+ RL_LIBS="-ledit -ltermcap"], -ltermcap)
+ ], -ltermcap)
+ ])
+fi
AC_SUBST(RL_LIBS)
AC_CHECK_LIB(gsm, gsm_decode, [HAVE_GSM="yes"])
@@ -209,6 +223,24 @@
AC_MSG_RESULT($is_freebsd)
if test $is_freebsd = "yes"; then
RPLAY_TARGET="FreeBSD"
+fi
+fi
+
+
+dnl
+dnl Check for NetBSD
+dnl
+if test -z "$RPLAY_TARGET"; then
+AC_MSG_CHECKING(for NetBSD)
+AC_EGREP_CPP(yes,
+[
+#ifdef __NetBSD__
+ yes
+#endif
+], is_netbsd=yes, is_netbsd=no)
+AC_MSG_RESULT($is_netbsd)
+if test $is_netbsd = "yes"; then
+ RPLAY_TARGET="NetBSD"
fi
fi
"
ca:
"
--- rplayd/audio/audio_NetBSD.h.orig Thu Nov 18 22:37:44 2004
+++ rplayd/audio/audio_NetBSD.h Thu Nov 18 22:46:15 2004
@@ -0,0 +1,40 @@
+/* $Id: audio_NetBSD.h, $ */
+
+/*
+ *
+ * This file is part of rplay.
+ *
+ * rplay 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 of the License, or
+ * (at your option) any later version.
+ *
+ * rplay 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 rplay; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+
+#ifndef _audio_NetBSD_h
+#define _audio_NetBSD_h
+
+#include "rplay.h"
+
+#define RPLAY_AUDIO_DEVICE "/dev/sound"
+#define RPLAY_MIXER_DEVICE "/dev/mixer"
+#define RPLAY_AUDIO_TIMEOUT 3
+#define RPLAY_AUDIO_FLUSH_TIMEOUT -1
+#define RPLAY_AUDIO_RATE 49
+#if BYTE_ORDER == BIG_ENDIAN
+#define RPLAY_AUDIO_BYTE_ORDER RPLAY_BIG_ENDIAN
+#else
+#define RPLAY_AUDIO_BYTE_ORDER RPLAY_LITTLE_ENDIAN
+#endif
+#endif /* _audio_NetBSD_h */
"
cb:
"
--- rplayd/audio/audio_NetBSD.c.orig Thu Nov 18 22:37:44 2004
+++ rplayd/audio/audio_NetBSD.c Thu Nov 18 22:47:14 2004
@@ -0,0 +1,555 @@
+/* $Id: audio_NetBSD 0.01 2004/11/16 OHt $ */
+
+/*
+ *
+ * This file is part of rplay.
+ *
+ * rplay 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 of the License, or
+ * (at your option) any later version.
+ *
+ * rplay 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 rplay; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+
+#include "rplayd.h"
+
+/*
+ * System audio include files:
+ */
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#include <sys/errno.h>
+#include <sys/audioio.h>
+#include <errno.h>
+
+/*
+ * External variables:
+ */
+extern char *rplay_audio_device;
+extern int rplay_audio_sample_rate;
+extern int rplay_audio_channels;
+extern int rplay_audio_precision;
+extern int rplay_audio_format;
+extern int rplay_audio_port;
+extern int optional_sample_rate;
+extern int optional_precision;
+extern int optional_channels;
+extern int optional_format;
+extern int optional_port;
+
+/*
+ * Internal variables:
+ */
+static int rplay_audio_fd = -1;
+static RPLAY_AUDIO_TABLE generic_table[] =
+{
+ {44100, RPLAY_FORMAT_LINEAR_16, 16, 2},
+ {0, 0, 0, 0}
+};
+
+static RPLAY_AUDIO_TABLE NetBSD_table[50 * AUDIO_ENCODING_MPEG_L2_SYSTEM];
+ int enc_table[20];
+ int i;
+
+
+ const int sratetab[]=
+ { 6615,
+ 8000,
+ 9600,
+ 11025,
+ 16000,
+ 22050,
+ 32000,
+ 44100,
+ 48000
+ };
+
+
+char *encoding_name;
+audio_encoding_t enc_st;
+audio_info_t prinfo;
+int n =1;
+
+
+char *soundbuff;
+audio_info_t a;
+
+/*
+ * Initialize the audio device.
+ * This routine must set the following external variables:
+ * rplay_audio_sample_rate
+ * rplay_audio_precision
+ * rplay_audio_channels
+ * rplay_audio_format
+ * rplay_audio_port
+ *
+ * and may use the following optional parameters:
+ * optional_sample_rate
+ * optional_precision
+ * optional_channels
+ * optional_format
+ * optional_port
+ *
+ * optional_* variables with values of zero should be ignored.
+ *
+ * Return 0 on success and -1 on error.
+ */
+int
+rplay_audio_init()
+{
+ audio_info_t a;
+ audio_device_t d;
+ int enc_table[20];
+ int i;
+ int j;
+
+
+ if (rplay_audio_fd == -1)
+ {
+ rplay_audio_open();
+ if (rplay_audio_fd == -1)
+ {
+ report(REPORT_ERROR, "rplay_audio_init: cannot open %s\n",
+ rplay_audio_device);
+ return -1;
+ }
+ }
+
+ if (ioctl(rplay_audio_fd, AUDIO_GETINFO, &a) < 0)
+ {
+ report(REPORT_ERROR, "rplay_audio_init: failed to get audio info%s\n",
+ rplay_audio_device);
+ return -1;
+ }
+
+
+ if (ioctl(rplay_audio_fd, AUDIO_GETDEV, &d) < 0)
+ {
+ report(REPORT_ERROR, "rplay_audio_init: AUDIO_GETDEV: %s\n",
+ sys_err_str(errno));
+ return -1;
+ }
+ for (i = AUDIO_ENCODING_NONE ; i < AUDIO_ENCODING_MPEG_L2_SYSTEM; ++i)
+ {
+ enc_st.index = i;
+ if (ioctl(rplay_audio_fd, AUDIO_GETENC, &enc_st) == -1)
+ {
+ asprintf(&encoding_name, "%d", prinfo.play.encoding);
+ }
+ else
+ {
+ switch (enc_st.encoding)
+ {
+ case AUDIO_ENCODING_ULAW:
+ enc_table[i] = RPLAY_FORMAT_ULAW;
+ break;
+ case AUDIO_ENCODING_SLINEAR:
+ enc_table[i]= RPLAY_FORMAT_LINEAR_8;
+ break;
+ case AUDIO_ENCODING_ULINEAR:
+ enc_table[i] = RPLAY_FORMAT_ULINEAR_8;
+ break;
+ case AUDIO_ENCODING_SLINEAR_LE:
+ enc_table[i] =RPLAY_FORMAT_LINEAR_16;
+ break;
+ case AUDIO_ENCODING_ULINEAR_LE:
+ enc_table[i]= RPLAY_FORMAT_ULINEAR_16;
+ break;
+ default:
+ enc_table[i] = RPLAY_FORMAT_NONE;
+ break;
+
+ }
+ }
+ }
+ for (j = 1 ; j < 7 ; j++)
+ {
+ prinfo.play.sample_rate = sratetab[j];
+
+ for (i = AUDIO_ENCODING_NONE ; i <= AUDIO_ENCODING_MPEG_L2_SYSTEM; i++)
+ {
+ if (enc_table[i] != RPLAY_FORMAT_NONE)
+ {
+
+ int k;
+ enc_st.index = i;
+ prinfo.play.encoding = i;
+ AUDIO_INITINFO (&prinfo) ;
+ /* for (j = 1 ; j < 7 ; j++)
+ {
+ int k;
+ prinfo.play.sample_rate = sratetab[j];*/
+ for (k = 1 ; k < 5 ; k++)
+ {
+ switch (k)
+ {
+ case 1:
+ prinfo.play.precision = 8;
+ prinfo.play.channels = 1;
+ break;
+ case 2:
+ prinfo.play.precision = 16;
+ prinfo.play.channels = 1;
+ break;
+ case 3:
+ prinfo.play.precision = 8;
+ prinfo.play.channels = 2;
+ break;
+ case 4:
+ prinfo.play.precision = 16;
+ prinfo.play.channels = 2;
+ break;
+ }
+ if (ioctl(rplay_audio_fd, AUDIO_SETINFO, &prinfo) != -1)
+ {
+ NetBSD_table[n].format = enc_table[i];
+ NetBSD_table[n].sample_rate = prinfo.play.sample_rate;
+ NetBSD_table[n].bits = prinfo.play.precision;
+ NetBSD_table[n].channels = prinfo.play.channels;
+ n++;
+ }
+ }
+ }
+ }
+ }
+ report(REPORT_DEBUG," rplay_audio_bufsize: %d \n", rplay_audio_bufsize);
+ report(REPORT_DEBUG," rplay_audio_rate: %d \n", rplay_audio_rate);
+
+ {
+ NetBSD_table[n].format = RPLAY_FORMAT_NONE ;
+ NetBSD_table[n].sample_rate = 0;
+ NetBSD_table[n].bits = 0;
+ NetBSD_table[n].channels = 0 ;
+ }
+
+ n = 1;
+
+ rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 44100;
+ rplay_audio_precision = optional_precision ? optional_precision : 16;
+ rplay_audio_channels = optional_channels ? optional_channels : 2;
+ rplay_audio_format = optional_format ? optional_format :
+ rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8;
+ rplay_audio_table =( RPLAY_AUDIO_TABLE *) NetBSD_table ;
+ report(REPORT_DEBUG, "%s device detected\n", d.name);
+
+
+
+ /* Verify the precision and format. */
+ switch (rplay_audio_precision)
+ {
+ case 8:
+ if (rplay_audio_format != RPLAY_FORMAT_ULAW
+ && rplay_audio_format != RPLAY_FORMAT_LINEAR_8 && rplay_audio_format != RPLAY_FORMAT_ULINEAR_8)
+ {
+ report(REPORT_ERROR, "rplay_audio_init: can't use %d bits with format=%d\n",
+ rplay_audio_precision, rplay_audio_format);
+ return -1;
+ }
+ break;
+
+ case 16:
+ if (rplay_audio_format != RPLAY_FORMAT_LINEAR_16)
+ {
+ report(REPORT_ERROR, "rplay_audio_init: can't use %d bits with format=%d\n",
+ rplay_audio_precision, rplay_audio_format);
+ return -1;
+ }
+ break;
+
+ default:
+ report(REPORT_ERROR, "rplay_audio_init: `%d' unsupported audio precision\n",
+ rplay_audio_precision);
+ return -1;
+ }
+
+ AUDIO_INITINFO(&a);
+
+ switch (rplay_audio_format)
+ {
+ case RPLAY_FORMAT_ULAW:
+ a.play.encoding = AUDIO_ENCODING_ULAW;
+ break;
+
+ case RPLAY_FORMAT_LINEAR_8:
+ a.play.encoding = AUDIO_ENCODING_SLINEAR;
+ break;
+ case RPLAY_FORMAT_LINEAR_16:
+ a.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
+ break;
+
+ default:
+ report(REPORT_ERROR, "rplay_audio_init: unsupported audio format `%d'\n",
+ rplay_audio_format);
+ return -1;
+ }
+
+
+ a.play.sample_rate = rplay_audio_sample_rate;
+ a.play.precision = rplay_audio_precision;
+ a.play.channels = rplay_audio_channels;
+
+ if (ioctl(rplay_audio_fd, AUDIO_SETINFO, &a) < 0)
+ {
+ report(REPORT_DEBUG, "rplay_audio_init: AUDIO_SETINFO: %s\n", sys_err_str(errno));
+ report(REPORT_ERROR, "rplay_audio_init: AUDIO_SETINFO: %s\n", sys_err_str(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+/***************************************************************/
+/*
+ * Open the audio device.
+ *
+ * Return 0 on success and -1 on error.
+ */
+
+
+int
+rplay_audio_open()
+{
+ int flags;
+
+ rplay_audio_fd = open(rplay_audio_device, O_WRONLY | O_NDELAY, 0);
+ if (rplay_audio_fd < 0)
+ {
+ return -1;
+ }
+
+ if (fcntl(rplay_audio_fd, F_SETFD, 1) < 0)
+ {
+ report(REPORT_ERROR,
+ "rplay_audio_open: close-on-exec %d\n",
+ sys_err_str(errno));
+ /* return -1; */
+ }
+
+ if (rplay_audio_init() < 0)
+ {
+ return -1;
+ }
+
+ /*
+ * Make sure the audio device writes are non-blocking.
+ */
+ flags = fcntl(rplay_audio_fd, F_GETFL, 0);
+ if (flags < 0)
+ {
+ return -1;
+ }
+ flags |= FNDELAY;
+ if (fcntl(rplay_audio_fd, F_SETFL, flags) < 0)
+ {
+ return -1;
+ }
+ soundbuff = malloc( a.play.buffer_size);
+ return 0;
+}
+
+/*
+ * Is the audio device open?
+ *
+ * Return 1 for true and 0 for false.
+ */
+int
+rplay_audio_isopen()
+{
+ return rplay_audio_fd != -1;
+}
+
+/*
+ * Flush the audio device.
+ *
+ * Return 0 on success and -1 on error.
+ */
+int
+rplay_audio_flush()
+{
+ if (rplay_audio_fd != -1)
+ {
+ ioctl(rplay_audio_fd, AUDIO_DRAIN, 0);
+ }
+
+ return 0;
+}
+
+
+/************************************************************************/
+/*
+ * Write nbytes from buf to the audio device.
+ *
+ * Return the number of bytes written on success and -1 on error.
+ */
+
+#ifdef __STDC__
+int
+rplay_audio_write(char *buf, int nbytes)
+#else
+int
+rplay_audio_write(buf, nbytes)
+ char *buf;
+ int nbytes;
+#endif
+{
+ int n, nleft, nwritten;
+ char *p;
+ audio_info_t a;
+
+ nleft = nbytes;
+ nwritten = 0;
+
+
+ if (ioctl(rplay_audio_fd, AUDIO_GETINFO, &a) < 0)
+ {
+ report(REPORT_ERROR, "rplay_audio_init: failed to get audio info%s\n",
+ rplay_audio_device);
+ return -1;
+ }
+
+
+ for (p = buf; nleft > 0; nleft -= n, p += n)
+ {
+ n = write(rplay_audio_fd, p, nleft);
+ if (n < 0)
+ {
+ if (errno == EWOULDBLOCK)
+ {
+ return nwritten;
+ }
+ else if (errno != EINTR)
+ {
+ return -1;
+ }
+ n = 0;
+ }
+ else
+ {
+ nwritten += n;
+ }
+ }
+
+
+
+
+
+ return nwritten;
+}
+
+/*
+ * Close the audio device.
+ *
+ * Return 0 on success and -1 on error.
+ */
+int
+rplay_audio_close()
+{
+ if (rplay_audio_fd != -1)
+ {
+ close(rplay_audio_fd);
+ }
+
+ rplay_audio_fd = -1;
+
+ return 0;
+}
+
+/*
+ * Return the volume of the audio device.
+ *
+ * Return 0-255 or -1 on error.
+ */
+int
+rplay_audio_get_volume()
+{
+#ifdef FAKE_VOLUME
+ return rplay_audio_volume;
+#else /* not FAKE_VOLUME */
+ audio_info_t a;
+
+ if (rplay_audio_fd < 0)
+ {
+ rplay_audio_open();
+ }
+ if (rplay_audio_fd < 0)
+ {
+ return -1;
+ }
+ if (ioctl(rplay_audio_fd, AUDIO_GETINFO, &a) < 0)
+ {
+ return -1;
+ }
+ else
+ {
+ return a.play.gain;
+ }
+#endif /* not FAKE_VOLUME */
+}
+
+/*
+ * Set the volume of the audio device.
+ * Input should be 0-255.
+ *
+ * Return the volume of the audio device 0-255 or -1.
+ */
+#ifdef __STDC__
+int
+rplay_audio_set_volume(int volume)
+#else
+int
+rplay_audio_set_volume(volume)
+ int volume;
+#endif
+{
+#ifdef FAKE_VOLUME
+ if (volume < RPLAY_MIN_VOLUME)
+ {
+ volume = RPLAY_MIN_VOLUME;
+ }
+ else if (volume > RPLAY_MAX_VOLUME)
+ {
+ volume = RPLAY_MAX_VOLUME;
+ }
+ rplay_audio_volume = volume;
+
+ return rplay_audio_volume;
+#else /* not FAKE_VOLUME */
+ audio_info_t a;
+
+ rplay_audio_volume = 0;
+
+ if (rplay_audio_fd < 0)
+ {
+ rplay_audio_open();
+ }
+ if (rplay_audio_fd < 0)
+ {
+ return -1;
+ }
+
+ AUDIO_INITINFO(&a);
+ a.play.gain = volume;
+ if (ioctl(rplay_audio_fd, AUDIO_SETINFO, &a) < 0)
+ {
+ return -1;
+ }
+
+ rplay_audio_volume = rplay_audio_get_volume();
+
+ return rplay_audio_volume;
+#endif /* not FAKE_VOLUME */
+}
+
"
cc:
"
--- adpcm/g72x.h.orig Wed Jul 15 00:35:23 1998
+++ adpcm/g72x.h Sun Nov 7 19:10:04 2004
@@ -32,11 +32,15 @@
*/
#ifndef _G72X_H
#define _G72X_H
+#ifdef __NetBSD__
+#include <sys/types.h>
+#include <sys/audioio.h>
+#else
#define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */
#define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */
#define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */
-
+#endif
/*
* The following is the definition of the state structure
* used by the G.721/G.723 encoder and decoder to preserve their internal
"