changeset 3279:d6ea11bed983

Commandline interface to ao_plugin updated according to mplayers complex parameter format and plugin pl_format finished (alpha code needs testing)
author anders
date Mon, 03 Dec 2001 14:05:02 +0000
parents 404cfc1a0942
children 542f7c228e38
files cfg-mplayer.h libao2/ao_plugin.c libao2/pl_format.c
diffstat 3 files changed, 203 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/cfg-mplayer.h	Mon Dec 03 10:10:19 2001 +0000
+++ b/cfg-mplayer.h	Mon Dec 03 14:05:02 2001 +0000
@@ -78,6 +78,14 @@
 /* from dec_audio, currently used for ac3surround decoder only */
 extern int audio_output_channels;
 
+/* Options related to audio out plugins */
+struct config ao_plugin_conf[]={
+	{"list", &ao_plugin_cfg.plugin_list, CONF_TYPE_STRING, 0, 0, 0},
+	{"delay", &ao_plugin_cfg.pl_delay_len, CONF_TYPE_INT, CONF_MIN, 0, 0},
+	{"format", &ao_plugin_cfg.pl_format_type, CONF_TYPE_INT, CONF_MIN, 0, 0},
+	{NULL, NULL, 0, 0, 0, 0}
+};
+
 extern int sws_flags;
 
 /*
@@ -101,10 +109,8 @@
 	{"o", "Option -o has been renamed to -vo (video-out), use -vo !\n",
             CONF_TYPE_PRINT, CONF_NOCFG, 0, 0},
 	{"vo", &video_driver, CONF_TYPE_STRING, 0, 0, 0},
-	// -----options related to audio and audio plugins-------
 	{"ao", &audio_driver, CONF_TYPE_STRING, 0, 0, 0},
-	{"aop", &ao_plugin_cfg.plugin_list, CONF_TYPE_STRING, 0, 0, 0},
-	{"aop_delay", &ao_plugin_cfg.pl_delay_len, CONF_TYPE_INT, CONF_MIN, 0, 0},
+	{"aop", ao_plugin_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0},
 //	{"dsp", &dsp, CONF_TYPE_STRING, CONF_NOCFG, 0, 0},
 	{"dsp", "Use -ao oss:dsp_path!\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0},
         {"mixer", &mixer_device, CONF_TYPE_STRING, 0, 0, 0},
--- a/libao2/ao_plugin.c	Mon Dec 03 10:10:19 2001 +0000
+++ b/libao2/ao_plugin.c	Mon Dec 03 14:05:02 2001 +0000
@@ -197,7 +197,7 @@
   len=driver()->play(ao_plugin_data.data,ao_plugin_data.len,flags);
 
   if(len!=ao_plugin_data.len)
-    printf("Buffer over flow in sound plugin ");
+    fprintf(stderr,"[ao_plugin] Warning under or over flow in sound plugin");
   
   return ret_len;
 }
@@ -211,3 +211,5 @@
 }
 
 
+
+
--- a/libao2/pl_format.c	Mon Dec 03 10:10:19 2001 +0000
+++ b/libao2/pl_format.c	Mon Dec 03 14:05:02 2001 +0000
@@ -1,13 +1,16 @@
-/* This is a null audio out plugin it doesnt't really do anything
-   useful but serves an example of how audio plugins work. It delays
-   the output signal by the nuber of samples set by aop_delay n
-   where n is the number of bytes.
- */
+/* This audio output plugin changes the format of a data block. Valid
+   output formats are: AFMT_U8, AFMT_S8, AFMT_S16_LE, AFMT_S16_BE
+   AFMT_U16_LE, AFMT_U16_BE, AFMT_S32_LE and AFMT_S32_BE. The output
+   format is spedified using the cfg switch 'format=NR' where NR is
+   the number as given in libao2/afmt.h
+*/
+
 #define PLUGIN
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <inttypes.h>
 
 #include "audio_out.h"
 #include "audio_plugin.h"
@@ -29,28 +32,28 @@
 {
   void*  data;       // local audio data block
   int    len;        // local buffer length
-  int 	 in;  	     // Input fomat
-  int    out;        // Output fomat
+  int 	 in;  	     // input fomat
+  int    out;        // output fomat
   double sz_mult;    // data size multiplier
 } pl_format_t;
 
 static pl_format_t pl_format={NULL,0,0,0,1};
 
 // Number of bits
-#define B08		0 
-#define B16  		1	
-#define B32  		2
-#define NBITS_MASK	3
+#define B08		(0<<0) 
+#define B16  		(1<<0)	
+#define B32  		(2<<0)
+#define NBITS_MASK	(3<<0)
 
 // Endianess
-#define BE 		(0<<3) // Big endian
-#define LE 		(1<<3) // Little endian
-#define END_MASK	(1<<3)
+#define BE 		(0<<2) // Big Endian
+#define LE 		(1<<2) // Little Endian
+#define END_MASK	(1<<2)
 
 // Signed
-#define US		(0<<4)
-#define SI		(1<<4)
-#define SIGN_MASK	(1<<4)
+#define US		(0<<3) // Un Signed
+#define SI		(1<<3) // SIgned
+#define SIGN_MASK	(1<<3)
 
 // to set/get/query special features/parameters
 static int control(int cmd,int arg){
@@ -59,8 +62,10 @@
     if(pl_format.data) 
       uninit();
     pl_format.len = ao_plugin_data.len;
+    if(ao_plugin_data.data)
+      free(ao_plugin_data.data);
     pl_format.data=(void*)malloc(ao_plugin_data.len);
-    ao_plugin_data.len=(int)((double)ao_plugin_data.len*pl_format.sz_mult);
+    ao_plugin_data.len=(int)(((double)ao_plugin_data.len)*pl_format.sz_mult);
     return CONTROL_OK;
   }
   return -1;
@@ -69,11 +74,6 @@
 // open & setup audio device
 // return: 1=success 0=fail
 static int init(){
-  int i=0;
-  int sign=0;
-  int nbits=8;
-  int be_le=BE;
-
   // Sheck input format
   switch(ao_plugin_data.format){
   case(AFMT_U8):
@@ -81,7 +81,7 @@
   case(AFMT_S8):
     pl_format.in=LE|B08|SI; break;
   case(AFMT_S16_LE):
-    pl_format.in=LE|B16|US; break;
+    pl_format.in=LE|B16|SI; break;
   case(AFMT_S16_BE):
     pl_format.in=BE|B16|SI; break;
   case(AFMT_U16_LE):	
@@ -100,27 +100,27 @@
     printf("[pl_format] Audio format not yet suported \n");
     return 0;
   default: 
-    printf("[pl_format] Unsupported audio format\n"); // Should never happen...
+    printf("[pl_format] Unrecognised input audio format\n"); //This can not happen .... 
     return 0;
   }
   // Sheck output format
   switch(ao_plugin_cfg.pl_format_type){
   case(AFMT_U8):
-    pl_format.in=LE|B08|US; break;
+    pl_format.out=LE|B08|US; break;
   case(AFMT_S8):
-    pl_format.in=LE|B08|SI; break;
+    pl_format.out=LE|B08|SI; break;
   case(AFMT_S16_LE):
-    pl_format.in=LE|B16|US; break;
+    pl_format.out=LE|B16|SI; break;
   case(AFMT_S16_BE):
-    pl_format.in=BE|B16|SI; break;
+    pl_format.out=BE|B16|SI; break;
   case(AFMT_U16_LE):	
-    pl_format.in=LE|B16|US; break;
+    pl_format.out=LE|B16|US; break;
   case(AFMT_U16_BE):	
-    pl_format.in=BE|B16|US; break;
+    pl_format.out=BE|B16|US; break;
   case(AFMT_S32_LE):
-    pl_format.in=LE|B32|SI; break;
+    pl_format.out=LE|B32|SI; break;
   case(AFMT_S32_BE):	
-    pl_format.in=BE|B32|SI; break;
+    pl_format.out=BE|B32|SI; break;
   case(AFMT_IMA_ADPCM):		
   case(AFMT_MU_LAW):
   case(AFMT_A_LAW):
@@ -129,19 +129,26 @@
     printf("[pl_format] Audio format not yet suported \n");
     return 0;
   default:
-    printf("[pl_format] Unsupported audio format\n"); // Should never happen...
+    printf("[pl_format] Unrecognised audio output format\n");
     return 0;
   }
+
+  // Tell the world what we are up to
+  printf("[pl_format] Input format: %s, output format: %s \n",
+	 audio_out_format_name(ao_plugin_data.format),
+	 audio_out_format_name(ao_plugin_cfg.pl_format_type));
+
   // We are changing the format
   ao_plugin_data.format=ao_plugin_cfg.pl_format_type;
-  
-  // And perhaps the buffer size
+
+  // Perhaps the buffer size
   pl_format.sz_mult=1;
+  if((pl_format.in&NBITS_MASK) > (pl_format.out&NBITS_MASK))
+    pl_format.sz_mult/=(double)(1<<((pl_format.in&NBITS_MASK)-(pl_format.out&NBITS_MASK)));
   if((pl_format.in&NBITS_MASK) < (pl_format.out&NBITS_MASK))
-    pl_format.sz_mult/=(double)(1<<(pl_format.out-pl_format.in));
-  if((pl_format.in&NBITS_MASK) > (pl_format.out&NBITS_MASK))
-    pl_format.sz_mult*=(double)(1<<(pl_format.out-pl_format.in));
-  ao_plugin_data.sz_mult*=pl_format.sz_mult;
+    pl_format.sz_mult*=(double)(1<<((pl_format.out&NBITS_MASK)-(pl_format.in&NBITS_MASK)));
+  ao_plugin_data.sz_mult/=pl_format.sz_mult;
+
   return 1;
 }
 
@@ -149,6 +156,7 @@
 static void uninit(){
   if(pl_format.data) 
     free(pl_format.data);
+  pl_format.data=NULL;
 }
 
 // empty buffers
@@ -160,37 +168,168 @@
 
 // processes 'ao_plugin_data.len' bytes of 'data'
 // called for every block of data
+// FIXME: this routine needs to be optimized (it is probably possible to do a lot here)
 static int play(){
   register int i=0;
   void* in_data=ao_plugin_data.data;
   void* out_data=pl_format.data;
-  int in_len=((int)(double)pl_format.len*pl_format.sz_mult);
-  in_len>>=pl_format.in&NBITS_MASK;
+  int len=(ao_plugin_data.len)>>(pl_format.in&NBITS_MASK);
+  ao_plugin_data.len=(int)(((double)ao_plugin_data.len)*=pl_format.sz_mult);
+  ao_plugin_data.len;
 
-  if((pl_format.in&END_MASK)!=(pl_format.out&END_MASK)){
+  // Change to little endian (Is this true for sun ?)
+  if((pl_format.in&END_MASK)!=LE){
     switch(pl_format.in&NBITS_MASK){
     case(B16):{
-      register int16_t s;
-      for(i=1;i<in_len;i++){
-	s=((int16_t*)in_data)[i];
-	((int16_t*)in_data)[i]=(int16_t)(((s&0x00FF)<<8) | (s&0xFF00)>>8);
+      register uint16_t s;
+      for(i=1;i<len;i++){
+	s=((uint16_t*)in_data)[i];
+	((uint16_t*)in_data)[i]=(uint16_t)(((s&0x00FF)<<8) | (s&0xFF00)>>8);
       }
       break;
     }
     case(B32):{
-      register int32_t s;
-      for(i=1;i<in_len;i++){
-	s=((int32_t*)in_data)[i];
-	((int32_t*)in_data)[i]=(int32_t)(((s&0x000000FF)<<24) | ((s&0x0000FF00)<<8) |
-	                                 ((s&0x00FF0000)>>8)  | ((s&0xFF000000)>>24));
+      register uint32_t s;
+      for(i=1;i<len;i++){
+	s=((uint32_t*)in_data)[i];
+	((uint32_t*)in_data)[i]=(uint32_t)(((s&0x000000FF)<<24) | ((s&0x0000FF00)<<8) |
+					   ((s&0x00FF0000)>>8)  | ((s&0xFF000000)>>24));
       }
       break;
     }
     }
   }
   
+  // Change signed/unsigned
+  if((pl_format.in&SIGN_MASK) != (pl_format.out&SIGN_MASK)){
+    switch(pl_format.in&NBITS_MASK){
+    case(B08):{
+      switch(pl_format.in&SIGN_MASK){
+      case(US):{
+	for(i=0;i<len;i++)
+	  ((int8_t*)in_data)[i]=(int8_t)(-127+((int)((uint8_t*)in_data)[i]));
+	break;
+      }
+      case(SI):{
+	for(i=0;i<len;i++)
+	  ((uint8_t*)in_data)[i]=(uint8_t)(+127+((int)((int8_t*)in_data)[i]));
+	break;
+      }
+      break;
+      }
+    }
+    case(B16):{
+      switch(pl_format.in&SIGN_MASK){
+      case(US):{
+	for(i=0;i<len;i++)
+	  ((int16_t*)in_data)[i]=(int16_t)(-32767+((int)((uint16_t*)in_data)[i]));
+	break;
+      }
+      case(SI):{
+	for(i=0;i<len;i++)
+	  ((uint16_t*)in_data)[i]=(uint16_t)(+32767+((int)((int16_t*)in_data)[i]));
+	break;
+      }
+      break;
+      }
+    }
+    case(B32):{
+      switch(pl_format.in&SIGN_MASK){
+      case(US):{
+	for(i=0;i<len;i++)
+	  ((int32_t*)in_data)[i]=(int32_t)(-(1<<31-1)+((uint32_t*)in_data)[i]);
+	break;
+      }
+      case(SI):{
+	for(i=0;i<len;i++)
+	  ((uint32_t*)in_data)[i]=(uint32_t)(+(1<<31-1)+((int32_t*)in_data)[i]);
+	break;
+      }
+      break;
+      }
+    }
+    }
+  }
+  // Change the number of bits
+  if((pl_format.in&NBITS_MASK) == (pl_format.out&NBITS_MASK)){
+    int sz=(int)((double)ao_plugin_data.len/pl_format.sz_mult);
+    for(i=0;i<sz;i++)
+      ((char*)out_data)[i]=((char*)in_data)[i];
+  } else {
+    switch(pl_format.in&NBITS_MASK){
+    case(B08):{
+      switch(pl_format.out&NBITS_MASK){
+      case(B16):{
+	for(i=1;i<len;i++)
+	  ((uint16_t*)out_data)[i]=((uint16_t)((uint8_t*)in_data)[i])<<8;
+	break;
+      }
+      case(B32):{
+	for(i=1;i<len;i++)
+	  ((uint32_t*)out_data)[i]=((uint32_t)((uint8_t*)in_data)[i])<<24;
+	break;
+      }
+      }
+    }
+    case(B16):{
+      switch(pl_format.out&NBITS_MASK){
+      case(B08):{
+	for(i=0;i<len;i++)
+	  ((uint8_t*)out_data)[i]=(uint8_t)((((uint16_t*)in_data)[i])>>8);
+	break;
+      }
+      case(B32):{
+	for(i=1;i<len;i++)
+	  ((uint32_t*)out_data)[i]=((uint32_t)((uint16_t*)in_data)[i])<<16;
+	break;
+      }
+      }
+    }	
+    case(B32):{
+      switch(pl_format.out&NBITS_MASK){
+      case(B08):{
+	for(i=0;i<len;i++)
+	  ((uint8_t*)out_data)[i]=(uint8_t)((((uint32_t*)in_data)[i])>>24);
+	break;
+      }
+      case(B16):{
+	for(i=1;i<len;i++)
+	  ((uint16_t*)out_data)[i]=(uint16_t)((((uint32_t*)in_data)[i])>>16);
+	break;
+      }
+      }
+    }
+    }
+  }
+
+  // Switch to the correct endainess (agiain the problem with sun?)
+  if((pl_format.out&END_MASK)!=LE){
+    switch(pl_format.in&NBITS_MASK){
+    case(B16):{
+      register uint16_t s;
+      for(i=1;i<len;i++){
+	s=((uint16_t*)out_data)[i];
+	((uint16_t*)out_data)[i]=(uint16_t)(((s&0x00FF)<<8) | (s&0xFF00)>>8);
+      }
+      break;
+    }
+    case(B32):{
+      register uint32_t s;
+      for(i=1;i<len;i++){
+	s=((uint32_t*)out_data)[i];
+	((uint32_t*)out_data)[i]=(uint32_t)(((s&0x000000FF)<<24) | ((s&0x0000FF00)<<8) |
+					    ((s&0x00FF0000)>>8)  | ((s&0xFF000000)>>24));
+      }
+      break;
+    }
+    }
+  }
+
+  ao_plugin_data.data=out_data;
   return 1;
 }
 
 
 
+
+