[MEncoder-users] Re: Negatively delay audio?
James Lee
jlee23 at umbc.edu
Fri Mar 4 09:10:21 CET 2005
Well after learning that there was NO way to get negative delays, I hacked up
the delay af into a new af called advance. It works for my needs, but it
doesn't allow separate values for each channel like the delay af (but I think a
good lot of the code for seperate channels is there for some other more
experienced dev if they want to fix it) and for some reason it only works with
"-mc 0". It's a good start I think.
af_advance.c:
/* This audio filter advances the output signal for the different
channels and can be used for simple position panning. Extension for
this filter would be a reverb.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "af.h"
// Data for specific instances of this filter
typedef struct af_advance_s
{
int sa[AF_NCH]; // Advance [samples]
int d[AF_NCH]; // Amount disposed
float a[AF_NCH]; // Advance [ms]
}af_advance_t;
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
af_advance_t* s = af->setup;
switch(cmd){
case AF_CONTROL_REINIT:{
af->data->rate = ((af_data_t*)arg)->rate;
af->data->nch = ((af_data_t*)arg)->nch;
af->data->format = ((af_data_t*)arg)->format;
af->data->bps = ((af_data_t*)arg)->bps;
return control(af,AF_CONTROL_DELAY_LEN | AF_CONTROL_SET,s->a);
}
case AF_CONTROL_COMMAND_LINE:{
int i = 0;
char* cl = arg;
float a;
sscanf(cl,"%f",&a);
while(i < AF_NCH){
s->d[i] = 0;
s->a[i] = a;
i++;
}
return AF_OK;
}
case AF_CONTROL_DELAY_LEN | AF_CONTROL_SET:{
int i;
if(AF_OK != af_from_ms(AF_NCH, arg, s->sa, af->data->rate, 0.0, 1000.0))
return AF_ERROR;
for(i=0;i<AF_NCH;i++){
af_msg(AF_MSG_DEBUG0,"[advance] Channel %i advanced by %0.3fms\n",
i,clamp(s->a[i],0.0,1000.0));
af_msg(AF_MSG_DEBUG1,"[advance] Channel %i advanced by %i samples\n",
i,s->sa[i]);
}
return AF_OK;
}
case AF_CONTROL_DELAY_LEN | AF_CONTROL_GET:{
return af_to_ms(AF_NCH, s->sa, arg, af->data->rate);
}
}
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_data_t* c = data; // Current working data
af_advance_t* s = af->setup; // Setup for this instance
int nch = c->nch; // Number of channels
int len = c->len/c->bps; // Number of sample in data chunk
int ch,i,iorig;
int size = 0;
for(ch=0;ch<nch;ch++){
switch(c->bps){
case 1:{
int8_t* a = c->audio;
int sa = s->sa[ch];
for (i=ch;i<len&&s->d[ch]<sa;i+=nch,s->d[ch]++);
for(iorig=ch;i<len;iorig+=nch,i+=nch){
a[iorig] = a[i];
size++;
}
break;
}
case 2:{
int16_t* a = c->audio;
int sa = s->sa[ch];
for (i=ch;i<len&&s->d[ch]<sa;i+=nch,s->d[ch]++);
for(iorig=ch;i<len;iorig+=nch,i+=nch){
a[iorig] = a[i];
size++;
}
break;
}
case 4:{
int32_t* a = c->audio;
int sa = s->sa[ch];
for (i=ch;i<len&&s->d[ch]<sa;i+=nch,s->d[ch]++);
for(iorig=ch;i<len;iorig+=nch,i+=nch){
a[iorig] = a[i];
size++;
}
break;
}
}
}
c->len = size*c->bps;
return c;
}
// 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_advance_t));
if(af->data == NULL || af->setup == NULL)
return AF_ERROR;
return AF_OK;
}
// Description of this filter
af_info_t af_info_advance = {
"Advance audio filter",
"advance",
"Anders",
"",
AF_FLAGS_REENTRANT,
open
};
More information about the MEncoder-users
mailing list