[Mplayer-advusers] endian bug in ao ? (Fw: [MPlayer-users] audio output is broken on powerpc)

Attila Kinali kinali at gmx.net
Wed Feb 13 22:58:29 CET 2002


Begin forwarded message:

Date: Tue, 12 Feb 2002 05:55:42 +0100 (MET)
From: past-in at stud.tu-ilmenau.de
To: mplayer-users at mplayerhq.hu
Subject: [MPlayer-users] audio output is broken on powerpc


[Automatic answer: RTFM (read DOCS, FAQ), also read DOCS/bugreports.html]
Hello.

My powerpc system:
Linux manelan061.rz.tu-ilmenau.de 2.4.18-pre9 #1 Sun Feb 10 03:58:18 UTC 2002 ppc unknown

My test stream (5mb prefix of movie):
http://www.tu-ilmenau.de/~past-in/movie.avi

I've modified libao2/ao_oss.c so that it doesn't touch /dev/dsp,
but instead it writes to /usr/log/sound what it would otherwise write
to /dev/dsp.  (Patch included below for completeness.)

On an i386 box, this gives me correct pcm data that I can listen to thus:
	$ sox -t raw -r 44100 -c 2 -w -s /usr/log/sound -t ossdsp /dev/dsp
(And because the patch makes `-ao oss' behave essentially like `-ao pcm'
(only very much faster (on my powerpc at least (bug in `-ao pcm'?))),
it should give correct pcm on any machine.)

But on my powerpc, this produces
http://www.tu-ilmenau.de/~past-in/sound.bz2
which i've listened to as
	16-bit little-endian signed
and	16-bit big-endian    signed
and	16-bit little-endian unsigned
and	16-bit big-endian    unsigned,
but it never sounds right.

Hope this helps.  Keep up the good work.

-paul





-------------------------------------------------------------------------------
      fake-dsp-patch against current CVS tree:
-------------------------------------------------------------------------------
--- ../mplayer-cvs-download/main/libao2/ao_oss.c	Tue Jan 15 22:55:28 2002
+++ libao2/ao_oss.c	Tue Feb 12 03:09:18 2002
@@ -16,6 +16,18 @@
 #include "audio_out.h"
 #include "audio_out_internal.h"
 
+#undef HAVE_AUDIO_SELECT
+static void fill_zz(audio_buf_info *zz)
+{
+	static int once=1;
+	zz->fragments=once?2:1;
+	zz->fragstotal=2;
+	zz->fragsize=32768;
+	zz->bytes=once?65536:32768;
+	if (once)
+		once=0;
+}
+
 extern int verbose;
 
 static ao_info_t info = 
@@ -106,11 +118,13 @@
   if (verbose)
     printf("audio_setup: using '%s' dsp device\n", dsp);
 
+#if 0 //@@@
   audio_fd=open(dsp, O_WRONLY);
   if(audio_fd<0){
     printf("Can't open audio device %s  -> nosound\n",dsp);
     return 0;
   }
+#endif
 
   ao_data.bps=channels*rate;
   if(format != AFMT_U8 && format != AFMT_S8)
@@ -120,9 +134,9 @@
     ao_data.samplerate=rate;
     ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate);
   }
-  
+
   ao_data.format=format;
-  ioctl (audio_fd, SNDCTL_DSP_SETFMT, &ao_data.format);
+//  ioctl (audio_fd, SNDCTL_DSP_SETFMT, &ao_data.format);//@@@
   if(format == AFMT_AC3 && ao_data.format != AFMT_AC3) {
       printf("Can't set audio device %s to AC3 output\n", dsp);
       return 0;
@@ -134,27 +148,34 @@
     // We only use SNDCTL_DSP_CHANNELS for >2 channels, in case some drivers don't have it
     ao_data.channels = channels;
     if (ao_data.channels > 2) {
+exit(23);
+//freebsd 4.0 doesn't know SNDCTL_DSP_CHANNELS
+#if 0
       if ( ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &ao_data.channels) == -1 ||
 	   ao_data.channels != channels ) {
 	printf("audio_setup: Failed to set audio device to %d channels\n", channels);
 	return 0;
       }
+#endif
     }
-    else {
+    else { //@@@
+#if 0
       int c = ao_data.channels-1;
       if (ioctl (audio_fd, SNDCTL_DSP_STEREO, &c) == -1) {
 	printf("audio_setup: Failed to set audio device to %d channels\n", ao_data.channels);
 	return 0;
       }
+#endif
     }
     printf("audio_setup: using %d channels (requested: %d)\n", ao_data.channels, channels);
     // set rate
     ao_data.samplerate=rate;
-    ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate);
+//    ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); //@@@
+ao_data.samplerate=44100; //@@@ SAMPLERATE
     printf("audio_setup: using %d Hz samplerate (requested: %d)\n",ao_data.samplerate,rate);
   }
 
-  if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)==-1){
+  if(0&&ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)==-1){
       int r=0;
       printf("audio_setup: driver doesn't support SNDCTL_DSP_GETOSPACE :-(\n");
       if(ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &r)==-1){
@@ -164,6 +185,9 @@
           printf("audio_setup: %d bytes/frag (GETBLKSIZE)\n",ao_data.outburst);
       }
   } else {
+//@@@
+//fprintf(stderr, "init(): fragments=%d fragstotal=%d fragsize=%d bytes=%d\n", zz.fragments,zz.fragstotal,zz.fragsize,zz.bytes);fflush(stderr);
+fill_zz(&zz);
       printf("audio_setup: frags: %3d/%d  (%d bytes/frag)  free: %6d\n",
           zz.fragments, zz.fragstotal, zz.fragsize, zz.bytes);
       if(ao_data.buffersize==-1) ao_data.buffersize=zz.bytes;
@@ -207,6 +231,7 @@
 
 // stop playing and empty buffers (for seeking/pause)
 static void reset(){
+exit(23);
     uninit();
     audio_fd=open(dsp, O_WRONLY);
     if(audio_fd<0){
@@ -217,7 +242,9 @@
   ioctl (audio_fd, SNDCTL_DSP_SETFMT, &ao_data.format);
   if(ao_data.format != AFMT_AC3) {
     if (ao_data.channels > 2)
-      ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &ao_data.channels);
+//freebsd 4.0 doesn't know SNDCTL_DSP_CHANNELS
+exit(23);
+//      ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &ao_data.channels);
     else {
       int c = ao_data.channels-1;
       ioctl (audio_fd, SNDCTL_DSP_STEREO, &c);
@@ -244,7 +271,10 @@
   int playsize=ao_data.outburst;
 
 #ifdef SNDCTL_DSP_GETOSPACE
-  if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1){
+  if(1||ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1){
+//@@@
+//fprintf(stderr, "get_space(): fragments=%d fragstotal=%d fragsize=%d bytes=%d\n", zz.fragments,zz.fragstotal,zz.fragsize,zz.bytes);fflush(stderr);
+fill_zz(&zz);
       // calculate exact buffer space:
       playsize = zz.fragments*zz.fragsize;
       if (playsize > MAX_OUTBURST)
@@ -273,7 +303,20 @@
 // return: number of bytes played
 static int play(void* data,int len,int flags){
     len/=ao_data.outburst;
-    len=write(audio_fd,data,len*ao_data.outburst);
+//    len=write(audio_fd,data,len*ao_data.outburst);
+len=len*ao_data.outburst;
+{//@@@ sound logging
+	static int once = 1;
+	static fd = -1;
+	if (once) {
+		once = 0;
+		fd = open("/usr/log/sound", O_CREAT|O_TRUNC|O_WRONLY, 0644);
+		if (fd < 0)
+			exit(23);
+	}
+	if (write(fd, data,len)!=len)
+		exit(23);
+}
     return len;
 }
 
@@ -284,15 +327,23 @@
   /* Calculate how many bytes/second is sent out */
   if(audio_delay_method==2){
       int r=0;
-      if(ioctl(audio_fd, SNDCTL_DSP_GETODELAY, &r)!=-1)
+      if(ioctl(audio_fd, SNDCTL_DSP_GETODELAY, &r)!=-1) {
+exit(23);
          return ((float)r)/(float)ao_data.bps;
+      }
       audio_delay_method=1; // fallback if not supported
   }
   if(audio_delay_method==1){
       // SNDCTL_DSP_GETOSPACE
-      if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1)
+      if(1||ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1) {
+//@@@
+//fprintf(stderr, "get_delay(): fragments=%d fragstotal=%d fragsize=%d bytes=%d\n", zz.fragments,zz.fragstotal,zz.fragsize,zz.bytes);fflush(stderr);
+fill_zz(&zz);
          return ((float)(ao_data.buffersize-zz.bytes))/(float)ao_data.bps;
+      }
+exit(23);
       audio_delay_method=0; // fallback if not supported
   }
+exit(23);
   return ((float)ao_data.buffersize)/(float)ao_data.bps;
 }

_______________________________________________
RTFM!!!  http://www.MPlayerHQ.hu/DOCS
Search:  http://www.MPlayerHQ.hu/cgi-bin/htsearch
http://mplayerhq.hu/mailman/listinfo/mplayer-users



-- 
I am a moslem, i am a terrorist.



More information about the MPlayer-advusers mailing list