[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