From e1718bed1926f2056fa77d6b15aa74a823b32fa0 Mon Sep 17 00:00:00 2001 From: anders Date: Fri, 10 Jan 2003 01:01:38 +0000 Subject: New auto config for volume and resample and added support for float flag in configuration git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@8868 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libaf/af.h | 4 ++ libaf/af_resample.c | 152 ++++++++++++++++++++++++++++++++-------------------- libaf/af_volume.c | 5 +- 3 files changed, 100 insertions(+), 61 deletions(-) (limited to 'libaf') diff --git a/libaf/af.h b/libaf/af.h index 79a14a7c13..3ac9d4cacf 100644 --- a/libaf/af.h +++ b/libaf/af.h @@ -69,6 +69,10 @@ extern int* af_cpu_speed; #define AF_INIT_FORCE 0x00000003 #define AF_INIT_TYPE_MASK 0x00000003 +#define AF_INIT_INT 0x00000000 +#define AF_INIT_FLOAT 0x00000010 +#define AF_INIT_FORMAT_MASK 0x00000010 + // Default init type #ifndef AF_INIT_TYPE #if defined(HAVE_SSE) || defined(HAVE_3DNOW) diff --git a/libaf/af_resample.c b/libaf/af_resample.c index 612445d8cc..5c932fb3b3 100644 --- a/libaf/af_resample.c +++ b/libaf/af_resample.c @@ -34,9 +34,15 @@ #include "af_resample.h" // Filtering types -#define TYPE_LIN 0 // Linear interpolation -#define TYPE_INT 1 // 16 bit integer -#define TYPE_FLOAT 2 // 32 bit floating point +#define RSMP_LIN (0<<0) // Linear interpolation +#define RSMP_INT (1<<0) // 16 bit integer +#define RSMP_FLOAT (2<<0) // 32 bit floating point +#define RSMP_MASK (3<<0) + +// Defines for sloppy or exact resampling +#define FREQ_SLOPPY (0<<2) +#define FREQ_EXACT (1<<2) +#define FREQ_MASK (1<<2) // Accuracy for linear interpolation #define STEPACCURACY 32 @@ -53,8 +59,7 @@ typedef struct af_resample_s uint32_t up; // Up sampling factor uint64_t step; // Step size for linear interpolation uint64_t pt; // Pointer remainder for linear interpolation - int sloppy; // Enable sloppy resampling to reduce memory usage - int type; // Filter type + int setup; // Setup parameters cmdline or through postcreate } af_resample_t; // Euclids algorithm for calculating Greatest Common Divisor GCD(a,b) @@ -120,6 +125,55 @@ static int linint(af_data_t* c,af_data_t* l, af_resample_t* s) return len; } +/* Determine resampling type and format */ +static int set_types(struct af_instance_s* af, af_data_t* data) +{ + af_resample_t* s = af->setup; + int rv = AF_OK; + float rd = 0; + + // Make sure this filter isn't redundant + if((af->data->rate == data->rate) || (af->data->rate == 0)) + return AF_DETACH; + + /* If sloppy and small resampling difference (2%) */ + rd = abs((float)af->data->rate - (float)data->rate)/(float)data->rate; + if((((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (rd < 0.02) && + (data->format != (AF_FORMAT_NE | AF_FORMAT_F))) || + ((s->setup & RSMP_MASK) == RSMP_LIN)){ + s->setup = (s->setup & ~RSMP_MASK) | RSMP_LIN; + af->data->format = AF_FORMAT_NE | AF_FORMAT_SI; + af->data->bps = 2; + af_msg(AF_MSG_VERBOSE,"[resample] Using linear interpolation. \n"); + } + else{ + /* If the input format is float or if float is explicitly selected + use float, otherwise use int */ + if((data->format == (AF_FORMAT_NE | AF_FORMAT_F)) || + ((s->setup & RSMP_MASK) == RSMP_FLOAT)){ + s->setup = (s->setup & ~RSMP_MASK) | RSMP_FLOAT; + af->data->format = AF_FORMAT_NE | AF_FORMAT_F; + af->data->bps = 4; + } + else{ + s->setup = (s->setup & ~RSMP_MASK) | RSMP_INT; + af->data->format = AF_FORMAT_NE | AF_FORMAT_SI; + af->data->bps = 2; + } + af_msg(AF_MSG_VERBOSE,"[resample] Using %s processing and %s frequecy" + " conversion.\n", + ((s->setup & RSMP_MASK) == RSMP_FLOAT)?"floating point":"integer", + ((s->setup & FREQ_MASK) == FREQ_SLOPPY)?"inexact":"exact"); + } + + if(af->data->format != data->format || af->data->bps != data->bps) + rv = AF_FALSE; + data->format = af->data->format; + data->bps = af->data->bps; + af->data->nch = data->nch; + return rv; +} + // Initialization and runtime control static int control(struct af_instance_s* af, int cmd, void* arg) { @@ -129,62 +183,34 @@ static int control(struct af_instance_s* af, int cmd, void* arg) af_data_t* n = (af_data_t*)arg; // New configureation int i,d = 0; int rv = AF_OK; - size_t tsz = (s->type==TYPE_INT) ? sizeof(int16_t) : sizeof(float); - // Make sure this filter isn't redundant - if((af->data->rate == n->rate) || (af->data->rate == 0)) - return AF_DETACH; + // Free space for circular bufers + if(s->xq){ + for(i=1;idata->nch;i++) + if(s->xq[i]) + free(s->xq[i]); + free(s->xq); + } + if(AF_DETACH == (rv = set_types(af,n))) + return AF_DETACH; + // If linear interpolation - if(s->type == TYPE_LIN){ + if((s->setup & RSMP_MASK) == RSMP_LIN){ s->pt=0LL; s->step=((uint64_t)n->rate<data->rate+1LL; - af_msg(AF_MSG_VERBOSE,"[resample] Linear interpolation step: 0x%016X.\n", + af_msg(AF_MSG_DEBUG0,"[resample] Linear interpolation step: 0x%016X.\n", s->step); af->mul.n = af->data->rate; af->mul.d = n->rate; + return AF_OK; } - // Create space for circular bufers (if nesessary) - if((af->data->nch != n->nch) && (s->type != TYPE_LIN)){ - // First free the old ones - if(s->xq){ - for(i=1;idata->nch;i++) - if(s->xq[i]) - free(s->xq[i]); - free(s->xq); - } - // ... then create new - s->xq = malloc(n->nch*sizeof(void*)); - for(i=0;inch;i++) - s->xq[i] = malloc(2*L*tsz); - s->xi = 0; - } - - // Set parameters - af->data->nch = n->nch; - if(s->type == TYPE_INT || s->type == TYPE_LIN){ - af->data->format = AF_FORMAT_NE | AF_FORMAT_SI; - af->data->bps = 2; - } - else{ - af->data->format = AF_FORMAT_NE | AF_FORMAT_F; - af->data->bps = 4; - } - if(af->data->format != n->format || af->data->bps != n->bps) - rv = AF_FALSE; - n->format = af->data->format; - n->bps = af->data->bps; - - // If linear interpolation is used the setup is done. - if(s->type == TYPE_LIN) - return rv; - // Calculate up and down sampling factors d=gcd(af->data->rate,n->rate); // If sloppy resampling is enabled limit the upsampling factor - if(s->sloppy && (af->data->rate/d > 5000)){ + if(((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (af->data->rate/d > 5000)){ int up=af->data->rate/2; int dn=n->rate/2; int m=2; @@ -195,6 +221,12 @@ static int control(struct af_instance_s* af, int cmd, void* arg) d*=m; } + // Create space for circular bufers + s->xq = malloc(n->nch*sizeof(void*)); + for(i=0;inch;i++) + s->xq[i] = malloc(2*L*af->data->bps); + s->xi = 0; + // Check if the the design needs to be redone if(s->up != af->data->rate/d || s->dn != n->rate/d){ float* w; @@ -210,7 +242,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg) w = malloc(sizeof(float) * s->up *L); if(NULL != s->w) free(s->w); - s->w = malloc(L*s->up*tsz); + s->w = malloc(L*s->up*af->data->bps); // Design prototype filter type using Kaiser window with beta = 10 if(NULL == w || NULL == s->w || @@ -222,7 +254,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg) wt=w; for(j=0;jup;i++){//Rows - if(s->type == TYPE_INT){ + if((s->setup & RSMP_MASK) == RSMP_INT){ float t=(float)s->up*32767.0*(*wt); ((int16_t*)s->w)[i*L+j] = (int16_t)((t>=0.0)?(t+0.5):(t-0.5)); } @@ -245,15 +277,16 @@ static int control(struct af_instance_s* af, int cmd, void* arg) case AF_CONTROL_COMMAND_LINE:{ af_resample_t* s = (af_resample_t*)af->setup; int rate=0; - int lin=0; - sscanf((char*)arg,"%i:%i:%i", &rate, &(s->sloppy), &lin); - if(lin) - s->type = TYPE_LIN; + int type=RSMP_INT; + int sloppy=1; + sscanf((char*)arg,"%i:%i:%i", &rate, &type, &sloppy); + s->setup = (sloppy?FREQ_SLOPPY:FREQ_EXACT) | + (clamp(type,RSMP_LIN,RSMP_FLOAT)); return af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET, &rate); } case AF_CONTROL_POST_CREATE: - ((af_resample_t*)af->setup)->type = - ((af_cfg_t*)arg)->force == AF_INIT_SLOW ? TYPE_INT : TYPE_FLOAT; + if((((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) == AF_INIT_FLOAT) + ((af_resample_t*)af->setup)->setup |= RSMP_FLOAT; return AF_OK; case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET: // Reinit must be called after this function has been called @@ -293,8 +326,8 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data) return NULL; // Run resampling - switch(s->type){ - case(TYPE_INT): + switch(s->setup & RSMP_MASK){ + case(RSMP_INT): # define FORMAT_I 1 if(s->up>s->dn){ # define UP @@ -307,7 +340,7 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data) # undef DN } break; - case(TYPE_FLOAT): + case(RSMP_FLOAT): # undef FORMAT_I # define FORMAT_F 1 if(s->up>s->dn){ @@ -321,7 +354,7 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data) # undef DN } break; - case(TYPE_LIN): + case(RSMP_LIN): len = linint(c, l, s); break; } @@ -345,6 +378,7 @@ static int open(af_instance_t* af){ af->setup=calloc(1,sizeof(af_resample_t)); if(af->data == NULL || af->setup == NULL) return AF_ERROR; + ((af_resample_t*)af->setup)->setup = RSMP_INT | FREQ_SLOPPY; return AF_OK; } diff --git a/libaf/af_volume.c b/libaf/af_volume.c index 620a66bfa2..4fc6905f4e 100644 --- a/libaf/af_volume.c +++ b/libaf/af_volume.c @@ -60,7 +60,7 @@ static int control(struct af_instance_s* af, int cmd, void* arg) af->data->rate = ((af_data_t*)arg)->rate; af->data->nch = ((af_data_t*)arg)->nch; - if(s->fast){ + if(s->fast && (((af_data_t*)arg)->format != (AF_FORMAT_F | AF_FORMAT_NE))){ af->data->format = AF_FORMAT_SI | AF_FORMAT_NE; af->data->bps = 2; } @@ -83,7 +83,8 @@ static int control(struct af_instance_s* af, int cmd, void* arg) return control(af,AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, vol); } case AF_CONTROL_POST_CREATE: - s->fast = ((af_cfg_t*)arg)->force == AF_INIT_SLOW ? 1 : 0; + s->fast = (((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) == + AF_INIT_FLOAT ? 1 : 0; return AF_OK; case AF_CONTROL_VOLUME_ON_OFF | AF_CONTROL_SET: memcpy(s->enable,(int*)arg,AF_NCH*sizeof(int)); -- cgit v1.2.3