diff libaf/af_extrastereo.c @ 13550:81e62cbe57d9

reimplementation of the pl_extrastereo and pl_volnorm plugins
author alex
date Mon, 04 Oct 2004 19:11:05 +0000
parents
children 14090f7300a8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libaf/af_extrastereo.c	Mon Oct 04 19:11:05 2004 +0000
@@ -0,0 +1,120 @@
+/*=============================================================================
+//	
+//  This software has been released under the terms of the GNU Public
+//  license. See http://www.gnu.org/copyleft/gpl.html for details.
+//
+//  Copyright 2004 Alex Beregszaszi & Pierre Lombard
+//
+//=============================================================================
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> 
+
+#include <unistd.h>
+#include <inttypes.h>
+#include <math.h>
+#include <limits.h>
+
+#include "af.h"
+
+// Data for specific instances of this filter
+typedef struct af_extrastereo_s
+{
+    float mul;
+}af_extrastereo_t;
+
+// Initialization and runtime control
+static int control(struct af_instance_s* af, int cmd, void* arg)
+{
+  af_extrastereo_t* s   = (af_extrastereo_t*)af->setup; 
+
+  switch(cmd){
+  case AF_CONTROL_REINIT:
+    // Sanity check
+    if(!arg) return AF_ERROR;
+    
+    if(((af_data_t*)arg)->format != (AF_FORMAT_SI | AF_FORMAT_NE) ||
+       (((af_data_t*)arg)->nch != 2))
+       return AF_ERROR;
+
+    af->data->rate   = ((af_data_t*)arg)->rate;
+    af->data->nch    = 2;
+    af->data->format = AF_FORMAT_SI | AF_FORMAT_NE;
+    af->data->bps    = 2;
+
+    return af_test_output(af,(af_data_t*)arg);
+  case AF_CONTROL_COMMAND_LINE:{
+    float f;
+    sscanf((char*)arg,"%f", &f);
+    s->mul = f;
+    return AF_OK;
+  }
+  case AF_CONTROL_ES_MUL | AF_CONTROL_SET:
+    s->mul = *(float*)arg;
+    return AF_OK;
+  case AF_CONTROL_ES_MUL | AF_CONTROL_GET:
+    *(float*)arg = s->mul;
+    return AF_OK;
+  }
+  return AF_UNKNOWN;
+}
+
+// Deallocate memory 
+static void uninit(struct af_instance_s* af)
+{
+  if(af->data)
+    free(af->data);
+  if(af->setup)
+    free(af->setup);
+}
+
+// Filter data through filter
+static af_data_t* play(struct af_instance_s* af, af_data_t* data)
+{
+  af_extrastereo_t *s = af->setup;
+  register int i = 0;
+  int16_t *a = (int16_t*)data->audio;	// Audio data
+  int len = data->len/2;		// Number of samples
+  int avg, l, r;
+  
+  for (i = 0; i < len; i+=2)
+  {
+    avg = (a[i] + a[i + 1]) / 2;
+    
+    l = avg + (int)(s->mul * (a[i] - avg));
+    r = avg + (int)(s->mul * (a[i + 1] - avg));
+
+    a[i] = clamp(l, SHRT_MIN, SHRT_MAX);
+    a[i + 1] = clamp(r, SHRT_MIN, SHRT_MAX);
+  }
+
+  return data;
+}
+
+// Allocate memory and set function pointers
+static int open(af_instance_t* af){
+  af->control=control;
+  af->uninit=uninit;
+  af->play=play;
+  af->mul.n=1;
+  af->mul.d=1;
+  af->data=calloc(1,sizeof(af_data_t));
+  af->setup=calloc(1,sizeof(af_extrastereo_t));
+  if(af->data == NULL || af->setup == NULL)
+    return AF_ERROR;
+
+  ((af_extrastereo_t*)af->setup)->mul = 2.5;
+  return AF_OK;
+}
+
+// Description of this filter
+af_info_t af_info_extrastereo = {
+    "Extra stereo",
+    "extrastereo",
+    "Alex Beregszaszi & Pierre Lombard",
+    "",
+    AF_FLAGS_NOT_REENTRANT,
+    open
+};