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
"