[Mplayer-dev-eng] Update for libao2 sun audio

Juergen Keil jk at tools.de
Thu Jun 21 13:01:17 CEST 2001


Hi,

appended is an update for the (solaris/netbsd) sun audio module.  Timing code
is now based on "sample" counts; get_delay() now returns very precise
information about the amount of unplayed data bytes in the soundcard's
buffer and as a result, video playback is smoother now.

--
Jürgen Keil          		jk at tools.de
Tools GmbH			+49 (228) 9858011
-------------- next part --------------
Index: libao2/ao_sun.c
===================================================================
RCS file: /cvsroot/mplayer/main/libao2/ao_sun.c,v
retrieving revision 1.2
diff -u -B -r1.2 ao_sun.c
--- libao2/ao_sun.c	2001/06/08 23:31:06	1.2
+++ libao2/ao_sun.c	2001/06/21 10:51:14
@@ -1,12 +1,14 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
-#include <sys/ioctl.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>
 #include <sys/audioio.h>
 #ifdef	__svr4__
 #include <stropts.h>
@@ -20,10 +22,10 @@
 
 static ao_info_t info = 
 {
-	"Sun audio output",
-	"sun",
-	"jk at tools.de",
-	""
+    "Sun audio output",
+    "sun",
+    "jk at tools.de",
+    ""
 };
 
 LIBAO_EXTERN(sun)
@@ -43,9 +46,11 @@
 // ao_outburst
 // ao_buffersize
 
-static char *dsp="/dev/audio";
+static char *audio_dev = "/dev/audio";
 static int queued_bursts = 0;
-static int audio_fd=-1;
+static int queued_samples = 0;
+static int bytes_per_sample = 0;
+static int audio_fd = -1;
 
 // convert an OSS audio format specification into a sun audio encoding
 static int oss2sunfmt(int oss_format)
@@ -70,14 +75,14 @@
 
 // to set/get/query special features/parameters
 static int control(int cmd,int arg){
-    switch(cmd){
-	case AOCONTROL_SET_DEVICE:
-	    dsp=(char*)arg;
-	    return CONTROL_OK;
-	case AOCONTROL_QUERY_FORMAT:
-	    return CONTROL_TRUE;
-    }
-    return CONTROL_UNKNOWN;
+  switch(cmd){
+    case AOCONTROL_SET_DEVICE:
+      audio_dev=(char*)arg;
+      return CONTROL_OK;
+    case AOCONTROL_QUERY_FORMAT:
+      return CONTROL_TRUE;
+  }
+  return CONTROL_UNKNOWN;
 }
 
 // open & setup audio device
@@ -87,11 +92,12 @@
   audio_info_t info;
   int byte_per_sec;
 
-  printf("ao2: %d Hz  %d chans  0x%X\n",rate,channels,format);
+  printf("ao2: %d Hz  %d chans  %s [0x%X]\n",
+	 rate,channels,audio_out_format_name(format),format);
 
-  audio_fd=open(dsp, O_WRONLY);
+  audio_fd=open(audio_dev, O_WRONLY);
   if(audio_fd<0){
-    printf("Can't open audio device %s  -> nosound\n",dsp);
+    printf("Can't open audio device %s, %s  -> nosound\n", audio_dev, strerror(errno));
     return 0;
   }
 
@@ -101,15 +107,12 @@
   info.play.encoding = oss2sunfmt(ao_format = format);
   info.play.precision = (format==AFMT_S16_LE? AUDIO_PRECISION_16:AUDIO_PRECISION_8);
   info.play.channels = ao_channels = channels;
-  --ao_channels;
   info.play.sample_rate = ao_samplerate = rate;
-  info.play.samples = 0;
-  info.play.eof = 0;
   if(ioctl (audio_fd, AUDIO_SETINFO, &info)<0)
     printf("audio_setup: your card doesn't support %d channel, %s, %d Hz samplerate\n",channels,audio_out_format_name(format),rate);
-  byte_per_sec = (channels * info.play.precision * rate);
-  ao_outburst=byte_per_sec > 100000 ? 16384 : 8192;
-  queued_bursts = 0;
+  bytes_per_sample = channels * info.play.precision / 8;
+  byte_per_sec = bytes_per_sample * rate;
+  ao_outburst = byte_per_sec > 100000 ? 16384 : 8192;
 
   if(ao_buffersize==-1){
     // Measuring buffer size:
@@ -141,11 +144,24 @@
 #endif
   }
 
-    return 1;
+  AUDIO_INITINFO(&info);
+  info.play.samples = 0;
+  info.play.eof = 0;
+  info.play.error = 0;
+  ioctl (audio_fd, AUDIO_SETINFO, &info);
+
+  queued_bursts = 0;
+  queued_samples = 0;
+
+  return 1;
 }
 
 // close audio device
 static void uninit(){
+#ifdef	__svr4__
+    // throw away buffered data in the audio driver's STREAMS queue
+    ioctl(audio_fd, I_FLUSH, FLUSHW);
+#endif
     close(audio_fd);
 }
 
@@ -153,14 +169,10 @@
 static void reset(){
     audio_info_t info;
 
-#ifdef	__svr4__
-    // throw away buffered data in the audio driver's STREAMS queue
-    ioctl(audio_fd, I_FLUSH, FLUSHW);
-#endif
     uninit();
-    audio_fd=open(dsp, O_WRONLY);
+    audio_fd=open(audio_dev, O_WRONLY);
     if(audio_fd<0){
-	printf("\nFatal error: *** CANNOT RE-OPEN / RESET AUDIO DEVICE ***\n");
+	printf("\nFatal error: *** CANNOT RE-OPEN / RESET AUDIO DEVICE (%s) ***\n", strerror(errno));
 	return;
     }
 
@@ -169,12 +181,14 @@
     AUDIO_INITINFO(&info);
     info.play.encoding = oss2sunfmt(ao_format);
     info.play.precision = (ao_format==AFMT_S16_LE? AUDIO_PRECISION_16:AUDIO_PRECISION_8);
-    info.play.channels = ao_channels+1;
+    info.play.channels = ao_channels;
     info.play.sample_rate = ao_samplerate;
     info.play.samples = 0;
     info.play.eof = 0;
+    info.play.error = 0;
     ioctl (audio_fd, AUDIO_SETINFO, &info);
     queued_bursts = 0;
+    queued_samples = 0;
 }
 
 // stop playing, keep buffers (for pause)
@@ -198,49 +212,57 @@
 
 // return: how many bytes can be played without blocking
 static int get_space(){
-  int playsize=ao_outburst;
+    int playsize = ao_outburst;
+    audio_info_t info;
 
     // check buffer
 #ifdef HAVE_AUDIO_SELECT
-    {  fd_set rfds;
-       struct timeval tv;
-       FD_ZERO(&rfds);
-       FD_SET(audio_fd, &rfds);
-       tv.tv_sec = 0;
-       tv.tv_usec = 0;
-       if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) return 0; // not block!
+    {
+	fd_set rfds;
+	struct timeval tv;
+	FD_ZERO(&rfds);
+	FD_SET(audio_fd, &rfds);
+	tv.tv_sec = 0;
+	tv.tv_usec = 0;
+	if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) return 0; // not block!
     }
 #endif
 
-  {
-    audio_info_t info;
     ioctl(audio_fd, AUDIO_GETINFO, &info);
-    if(queued_bursts - info.play.eof > 2)
-      return 0;
-  }
-  return ao_outburst;
+    if (queued_bursts - info.play.eof > 2)
+	return 0;
+
+    return ao_outburst;
 }
 
 // plays 'len' bytes of 'data'
 // it should round it down to outburst*n
 // return: number of bytes played
 static int play(void* data,int len,int flags){
-    len/=ao_outburst;
-    len=write(audio_fd,data,len*ao_outburst);
-    if(len>0) {
-      queued_bursts ++;
-      write(audio_fd,data,0);
+    if (len < ao_outburst) return 0;
+    len /= ao_outburst;
+    len = write(audio_fd, data, len*ao_outburst);
+    if(len > 0) {
+      queued_samples += len / bytes_per_sample;
+      if (write(audio_fd,data,0) < 0)
+	  perror("ao_sun: send EOF audio record");
+      else
+	  queued_bursts ++;
     }
     return len;
 }
 
-static int audio_delay_method=2;
+#undef	USE_BURST_TIMING	/* use precise sample counter based timing */
+//#define USE_BURST_TIMING  1
 
 // return: how many unplayed bytes are in the buffer
 static int get_delay(){
-    int q;
     audio_info_t info;
     ioctl(audio_fd, AUDIO_GETINFO, &info);
+#if	USE_BURST_TIMING
     return (queued_bursts - info.play.eof) * ao_outburst;
+#else
+    return (queued_samples - info.play.samples) * bytes_per_sample;
+#endif
 }
 


More information about the MPlayer-dev-eng mailing list