changeset 14272:5a2473f37499

accelerated conversions
author alex
date Wed, 29 Dec 2004 19:05:29 +0000
parents 1cc5c037e28a
children dcdbe7055e62
files libaf/af_format.c
diffstat 1 files changed, 98 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libaf/af_format.c	Wed Dec 29 16:22:21 2004 +0000
+++ b/libaf/af_format.c	Wed Dec 29 19:05:29 2004 +0000
@@ -12,6 +12,7 @@
 
 #include "af.h"
 #include "../bswap.h"
+#include "../libvo/fastmemcpy.h"
 
 // Integer to float conversion through lrintf()
 #ifdef HAVE_LRINTF
@@ -42,6 +43,11 @@
 // From signed int to float
 static void int2float(void* in, void* out, int len, int bps);
 
+static af_data_t* play(struct af_instance_s* af, af_data_t* data);
+static af_data_t* play_swapendian(struct af_instance_s* af, af_data_t* data);
+static af_data_t* play_float_s16(struct af_instance_s* af, af_data_t* data);
+static af_data_t* play_s16_float(struct af_instance_s* af, af_data_t* data);
+
 // Convert from string to format
 int af_str2fmt(char* str)
 {
@@ -116,22 +122,22 @@
 
   // Endianess
   if(AF_FORMAT_LE == (format & AF_FORMAT_END_MASK))
-    i+=snprintf(str,size-i,"little endian ");
+    i+=snprintf(str,size-i,"little-endian ");
   else
-    i+=snprintf(str,size-i,"big endian ");
+    i+=snprintf(str,size-i,"big-endian ");
   
   if(format & AF_FORMAT_SPECIAL_MASK){
     switch(format & AF_FORMAT_SPECIAL_MASK){
     case(AF_FORMAT_MU_LAW): 
-      i+=snprintf(&str[i],size-i,"mu law "); break;
+      i+=snprintf(&str[i],size-i,"mu-law "); break;
     case(AF_FORMAT_A_LAW): 
-      i+=snprintf(&str[i],size-i,"A law "); break;
+      i+=snprintf(&str[i],size-i,"A-law "); break;
     case(AF_FORMAT_MPEG2): 
-      i+=snprintf(&str[i],size-i,"MPEG 2 "); break;
+      i+=snprintf(&str[i],size-i,"MPEG-2 "); break;
     case(AF_FORMAT_AC3): 
       i+=snprintf(&str[i],size-i,"AC3 "); break;
     case(AF_FORMAT_IMA_ADPCM): 
-      i+=snprintf(&str[i],size-i,"IMA ADPCM "); break;
+      i+=snprintf(&str[i],size-i,"IMA-ADPCM "); break;
     default:
       printf("Unknown special\n");
     }
@@ -222,6 +228,8 @@
   case AF_CONTROL_REINIT:{
     char buf1[256];
     char buf2[256];
+    af_data_t *data = arg;
+    
     // Make sure this filter isn't redundant 
     if(af->data->format == ((af_data_t*)arg)->format && 
        af->data->bps == ((af_data_t*)arg)->bps)
@@ -242,6 +250,32 @@
     af->data->nch  = ((af_data_t*)arg)->nch;
     af->mul.n      = af->data->bps;
     af->mul.d      = ((af_data_t*)arg)->bps;
+    
+    af->play = play; // set default
+    
+    // look whether only endianess differences are there
+    if ((af->data->format & ~AF_FORMAT_END_MASK) ==
+	(data->format & ~AF_FORMAT_END_MASK))
+    {
+	af_msg(AF_MSG_VERBOSE,"[format] Accelerated endianess conversion only\n");
+	af->play = play_swapendian;
+    }
+    if ((data->format == AF_FORMAT_FLOAT_NE) &&
+	(af->data->format == AF_FORMAT_S16_NE))
+    {
+	af_msg(AF_MSG_VERBOSE,"[format] Accelerated %sto %sconversion\n",
+	   af_fmt2str(((af_data_t*)arg)->format,buf1,255),
+	   af_fmt2str(af->data->format,buf2,255));
+	af->play = play_float_s16;
+    }
+    if ((data->format == AF_FORMAT_S16_NE) &&
+	(af->data->format == AF_FORMAT_FLOAT_NE))
+    {
+	af_msg(AF_MSG_VERBOSE,"[format] Accelerated %sto %sconversion\n",
+	   af_fmt2str(((af_data_t*)arg)->format,buf1,255),
+	   af_fmt2str(af->data->format,buf2,255));
+	af->play = play_s16_float;
+    }
     return AF_OK;
   }
   case AF_CONTROL_COMMAND_LINE:{
@@ -263,6 +297,9 @@
     }
     if(AF_FORMAT_F == (format & AF_FORMAT_POINT_MASK))
       bps=4;
+
+    // set appropriate AF_FORMAT_BITS
+    format |= (bps-1)<<3; // hack
     
     if((AF_OK != af->control(af,AF_CONTROL_FORMAT_BPS | AF_CONTROL_SET,&bps)) ||
        (AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET,&format)))
@@ -299,6 +336,61 @@
   af->setup = 0;  
 }
 
+static af_data_t* play_swapendian(struct af_instance_s* af, af_data_t* data)
+{
+  af_data_t*   l   = af->data;	// Local data
+  af_data_t*   c   = data;	// Current working data
+  int 	       len = c->len/c->bps; // Lenght in samples of current audio block
+
+  if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
+    return NULL;
+
+  endian(c->audio,l->audio,len,c->bps);
+
+  c->audio = l->audio;
+  c->format = l->format;
+
+  return c;
+}
+
+static af_data_t* play_float_s16(struct af_instance_s* af, af_data_t* data)
+{
+  af_data_t*   l   = af->data;	// Local data
+  af_data_t*   c   = data;	// Current working data
+  int 	       len = c->len/4; // Lenght in samples of current audio block
+
+  if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
+    return NULL;
+
+  float2int(c->audio, l->audio, len, 2);
+
+  c->audio = l->audio;
+  c->len = len*2;
+  c->bps = 2;
+  c->format = l->format;
+
+  return c;
+}
+
+static af_data_t* play_s16_float(struct af_instance_s* af, af_data_t* data)
+{
+  af_data_t*   l   = af->data;	// Local data
+  af_data_t*   c   = data;	// Current working data
+  int 	       len = c->len/2; // Lenght in samples of current audio block
+
+  if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
+    return NULL;
+
+  int2float(c->audio, l->audio, len, 2);
+
+  c->audio = l->audio;
+  c->len = len*4;
+  c->bps = 4;
+  c->format = l->format;
+
+  return c;
+}
+
 // Filter data through filter
 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
 {