Subject: pkg/12159: audio/liveice doesn't support soundcard recording (patch incl.)
To: None <gnats-bugs@gnats.netbsd.org>
From: Andrew Hobgood <chaos@strange.net>
List: netbsd-bugs
Date: 02/08/2001 22:00:23
>Number:         12159
>Category:       pkg
>Synopsis:       liveice does not support soundcard recording via liboss
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb 08 22:03:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Andrew Hobgood <chaos@strange.net>
>Release:        liveice-0.20001121 (NetBSD 1.5)
>Organization:
>Environment:
System: NetBSD schizo 1.5 NetBSD 1.5 (SCHIZO) #4: Tue Feb 6 13:40:31 EST 2001 root@schizo:/usr/src/sys/arch/alpha/compile/SCHIZO alpha

>Description:
	The original pkg port of audio/liveice utilizes the liboss 
	compatibility subsystem, which failed to actually record audio on 
	my NetBSD/Alpha box.  Included is a patch to cancel OSS compatibility
	in lieu of native NetBSD audio driver support via the audio/audioctl
	interface.

>How-To-Repeat:
	run liveice -m (non-mp3 mixer mode) and try to record audio.  It looks
	like it's working, but audio never actually comes into the program.

>Fix:
	Apply this patch to the audio/liveice/work/liveice/ directory after
	pkgsrc patches it with the preexisting NetBSD patches. (patch -p1)


diff -N -U4 liveice/Makefile liveice-netbsd_native/Makefile
--- liveice/Makefile	Tue Feb  6 10:06:47 2001
+++ liveice-netbsd_native/Makefile	Fri Feb  9 00:39:00 2001
@@ -1,11 +1,8 @@
 # Generated automatically from Makefile.in by configure.
 CC = cc
 CFLAGS = -O2
 LDFLAGS = -lcurses -lm -lresolv  
-.if ${OPSYS} == "NetBSD"
-LDFLAGS+=	-lossaudio	# Not needed on Solaris
-.endif
 SHELL=/bin/sh
 
 srcdir = .
 
diff -N -U4 liveice/README.NetBSD liveice-netbsd_native/README.NetBSD
--- liveice/README.NetBSD	Wed Dec 31 19:00:00 1969
+++ liveice-netbsd_native/README.NetBSD	Fri Feb  9 00:48:00 2001
@@ -0,0 +1,30 @@
+I've patched this to handle the NetBSD audio driver natively.
+
+Therefore, there are some new config variables which you have to worry 
+about if you intend to use the soundcard-based streaming features.
+
+# SOUND_DEVICE /dev/sound
+
+SOUND_DEVICE is no longer used when compiling under NetBSD.
+
+Instead:
+
+NETBSD_AUDIO_FILE	/dev/audio0
+NETBSD_AUDIOCTL_FILE	/dev/audioctl0
+
+Or something of that nature should be used.
+
+=== Last Updated: 09 February 2001
+=== Andrew Hobgood <chaos@strange.net>
+
+This has been tested on NetBSD-current (1.5 cvs 06 Feb 2001) with my SB
+AWE64 Gold ISA.
+
+NetBSD schizo 1.5 NetBSD 1.5 (SCHIZO) #4: Tue Feb  6 13:40:31 EST 2001     root@schizo:/usr/src/sys/arch/alpha/compile/SCHIZO alpha
+
+isapnp0: read port 0x203
+sb0 at isapnp0 port 0x220/16,0x330/2,0x388/4 irq 5 drq 1,5
+sb0: Creative SB AWE64 Gold Audio: dsp v4.16
+audio0 at sb0: full duplex, mmap, independent
+isapnp0: <Creative SB AWE64 Gold, CTL7002, PNPB02F, Game> port 0x200/8 not configured
+isapnp0: <Creative SB AWE64 Gold, CTL0023, , WaveTable> port 0x620/4 not configured
diff -N -U4 liveice/liveice.h liveice-netbsd_native/liveice.h
--- liveice/liveice.h	Tue Feb  6 10:06:36 2001
+++ liveice-netbsd_native/liveice.h	Fri Feb  9 00:38:43 2001
@@ -45,8 +45,11 @@
 #include <unistd.h>
 #include <termios.h>
 #include <sys/wait.h>
 #include <ctype.h>
+#ifdef __NetBSD__
+#include <sys/audioio.h>
+#endif
 
 /* curses interface support */
 
 #ifdef HAVE_LIBCURSES
@@ -269,8 +272,12 @@
 	char *pipe_dir;       /* put exerything in a hidden dir... */
 	char *recording_file;
 	char *remote_dumpfile;
 	char *sound_input_file; /* the file to read sound input from */
+#ifdef __NetBSD__
+	char *netbsd_audio_file;
+	char *netbsd_audioctl_file;
+#endif /* __NetBSD__ */
         char *random_content_id;
         char *encoder_args;
 	int sound_device;     /* set to 1 if the sound file is a device */
 	int icy_public;
@@ -279,8 +286,12 @@
 	int encoding_quality;
 	int sample_rate;
 	int stereo;
 	int audio_fd;         /* only one soundcard - only one audiofd */
+#ifdef __NetBSD__
+	int audioctl_fd;
+	audio_info_t ctlrestore;
+#endif /* __NetBSD__ */
 	int full_duplex;
 	int soundcard;         /* Are we using the soundcard? */
 	char *decoder_cmd;
 	int hacked_decoder;    /* are we using a hacked decoder? */
diff -N -U4 liveice/setup.c liveice-netbsd_native/setup.c
--- liveice/setup.c	Tue Feb  6 10:06:37 2001
+++ liveice-netbsd_native/setup.c	Fri Feb  9 00:38:37 2001
@@ -38,9 +38,11 @@
 char default_mountpoint[]       = "liveice";
 char default_description[]      = "LiveIce";
 char default_pipe_directory[]   = ".liveice_temp_files";
 #ifdef __NetBSD__
-char default_sound_input_file[] = "/dev/sound";
+char default_sound_input_file[] = "/dev/audio";
+char default_netbsd_audio_file[] = "/dev/audio";
+char default_netbsd_audioctl_file[] = "/dev/audioctl";
 #else
 char default_sound_input_file[] = "/dev/dsp";
 #endif
 
@@ -247,8 +249,15 @@
 	
 	g_conf.sound_input_file=malloc(strlen(default_sound_input_file)+2);
 	strcpy(g_conf.sound_input_file,default_sound_input_file);
 
+#ifdef __NetBSD__
+	g_conf.netbsd_audio_file=malloc(strlen(default_netbsd_audio_file)+2);
+	strcpy(g_conf.netbsd_audio_file,default_netbsd_audio_file);
+
+	g_conf.netbsd_audioctl_file=malloc(strlen(default_netbsd_audioctl_file)+2);
+	strcpy(g_conf.netbsd_audioctl_file,default_netbsd_audioctl_file);
+#endif
 
 	g_conf.icy_public=1;
 	g_conf.bitrate=BITRATE;
 	g_conf.vbr_quality=VBR_QUALITY;
@@ -410,8 +419,14 @@
 	 } else if(!strcmp(cmd,"UPDATE_SCRIPT")){
 	         string_copy(&(g_conf.update_script),line);	  
 	 } else if(!strcmp(cmd,"URL")) {
 		 string_copy(&(g_conf.icy_url),line);
+#ifdef __NetBSD__
+	 } else if(!strcmp(cmd,"NETBSD_AUDIO_FILE")) {
+		 string_copy(&(g_conf.netbsd_audio_file),line); 
+	 } else if(!strcmp(cmd,"NETBSD_AUDIOCTL_FILE")) {
+		 string_copy(&(g_conf.netbsd_audioctl_file),line); 
+#endif
 	 } else if(!strcmp(cmd,"MIXER_CMD")) {
 	 	string_copy(&g_conf.mixer_cmd,line);
 		g_conf.mixer=COMMAND_MODE;
 	 }
diff -N -U4 liveice/streams.c liveice-netbsd_native/streams.c
--- liveice/streams.c	Tue Feb  6 10:06:37 2001
+++ liveice-netbsd_native/streams.c	Fri Feb  9 00:38:26 2001
@@ -36,9 +36,9 @@
 #ifdef HAVE_SYS_SOUNDCARD_H
 #include <sys/soundcard.h>
 #else
 #ifdef __NetBSD__
-#include <soundcard.h>
+#include <sys/audioio.h>
 #else
 #include <machine/soundcard.h>
 #endif /* __NetBSD__ */
 #endif
@@ -80,13 +80,25 @@
 void check_soundcard(void)
 {
         int format,stereo,speed,caps;
 #ifdef SOUNDCARD_SUPPORT
+
+#ifdef __NetBSD__
+	audio_info_t ctlinfo;
+#endif /* __NetBSD__ */
+
 	fprintf(stderr,"Initialising Soundcard\n");
 
+#ifdef __NetBSD__
+	if((g_conf.audioctl_fd=open(g_conf.netbsd_audioctl_file,O_RDWR))==-1)
+	        fatal("Failed to open audioctl device");
+	if((g_conf.audio_fd=open(g_conf.netbsd_audio_file,O_RDONLY))==-1)
+#else
 	if((g_conf.audio_fd=open(g_conf.sound_input_file,O_RDWR))==-1)
+#endif /* __NetBSD__ */
 	        fatal("Failed to open sound device");
 
+#ifndef __NetBSD__
         /* see if the card can do full_duplex */
         if(g_conf.full_duplex){
                 ioctl(g_conf.audio_fd, SNDCTL_DSP_GETCAPS, &caps);
 	        if(caps & DSP_CAP_DUPLEX){
@@ -100,9 +112,35 @@
 		        write_message("Sound Card Driver Can't Do Full Duplex",0);
 			g_conf.full_duplex=0;
 		}
 	}
+#endif /* __NetBSD__ */
+
+#ifdef __NetBSD__
+	if(ioctl(g_conf.audioctl_fd, AUDIO_GETINFO, &(g_conf.ctlrestore)) < 0)
+		fatal("ioctl(AUDIO_GETINFO) failed");
+
+	/* in theory, we should pull ctlrestore.record.buffer_size and use
+	   that to malloc() our audio buffer, but in practice, this has 
+	   shown to be unneccesary.  This will minimize impact to the 
+	   original source and reduce the amount of patching we need.
+	*/
+
+	/* somewhere in here, we should be able to check/set full duplex,
+	   but I don't know enough about the internals of this driver yet.
+	*/
+	g_conf.full_duplex = 0;
+
+	AUDIO_INITINFO(&ctlinfo);
+	ctlinfo.record.sample_rate = g_conf.sample_rate;
+	ctlinfo.record.channels = (g_conf.stereo ? 2 : 1);
+	ctlinfo.record.precision = 16;
+	ctlinfo.record.encoding = AUDIO_ENCODING_SLINEAR_LE;
+	ctlinfo.mode = AUMODE_RECORD;
 
+	if(ioctl(g_conf.audioctl_fd, AUDIO_SETINFO, &ctlinfo) < 0)
+		fatal("ioctl(AUDIO_SETINFO) failed");
+#else
 	ioctl(g_conf.audio_fd, SNDCTL_DSP_GETFMTS, &format);
 	if(!(format&AFMT_S16_LE))
 		fatal("16bit mode not supported by driver");
 
@@ -116,18 +154,21 @@
 
 	speed=g_conf.sample_rate;
 	if(ioctl(g_conf.audio_fd,SNDCTL_DSP_SPEED,&speed)==-1)
 		fatal("Speed Setting failed\n");
+#endif /* __NetBSD__ */
 
 	
 	fprintf(stderr,"16Bit %dHz ",g_conf.sample_rate);
 	if(g_conf.stereo)
 	          fprintf(stderr,"Stereo ");
 	if(g_conf.full_duplex)
 	 	  fprintf(stderr,"Full Duplex ");
 	fprintf(stderr,"\n");
+#ifndef __NetBSD__
 	close(g_conf.audio_fd);
 	g_conf.audio_fd=0;
+#endif /* __NetBSD__ */
 #else
 	write_message("This executable Doesn't Support Soundcards",0);
 #endif
 
@@ -139,11 +180,12 @@
        int format,stereo,speed;
 #ifdef SOUNDCARD_SUPPORT
        write_message("Opening Soundcard",1);
         
+#ifndef __NetBSD__
 	if((g_conf.audio_fd=open(g_conf.sound_input_file,flags))==-1)
 	        fatal("Failed to open sound device");
-	
+
         if(g_conf.full_duplex)
 #ifdef HAVE_SYS_SOUNDCARD_H
 	        ioctl(g_conf.audio_fd, SNDCTL_DSP_SETDUPLEX, 0);  
 #else
@@ -160,8 +202,9 @@
 
 	speed=g_conf.sample_rate;
 	if(ioctl(g_conf.audio_fd,SNDCTL_DSP_SPEED,&speed)==-1)
 		fatal("Speed Setting failed\n");
+#endif /* __NetBSD__ */
 #else
 	write_message("This executable Doesn't Support Soundcards",0);
 #endif
 }
@@ -169,10 +212,23 @@
 void close_soundcard(void)
 {
 #ifdef SOUNDCARD_SUPPORT
 	write_message("Closing Soundcard",1);
+#ifdef __NetBSD__
+	close(g_conf.audio_fd);
+
+	/* In theory, we should reset the device.  In practice, this 
+	   segfaults.  I haven't figured out why.
+
+	if(ioctl(g_conf.audioctl_fd, AUDIO_SETINFO, &(g_conf.ctlrestore)) < 0)
+		fatal("ioctl(AUDIO_SETINFO) failed");
+	*/
+
+	close(g_conf.audioctl_fd);
+#else
 	ioctl(g_conf.audio_fd, SNDCTL_DSP_RESET, 0);
         close(g_conf.audio_fd);
+#endif /* __NetBSD__ */
 #else
 	write_message("This executable Doesn't Support Soundcards",0);
 #endif
 	
>Release-Note:
>Audit-Trail:
>Unformatted: