diff --git a/libaf/af.c b/libaf/af.c index 05f271f668..2165eb3baf 100644 --- a/libaf/af.c +++ b/libaf/af.c @@ -270,8 +270,8 @@ int af_reinit(af_stream_t* s, af_instance_t* af) if(NULL == (new = af_prepend(s,af,"format"))) return AF_ERROR; // Set output bits per sample - if(AF_OK != (rv = new->control(new,AF_CONTROL_FORMAT_BPS,&in.bps)) || - AF_OK != (rv = new->control(new,AF_CONTROL_FORMAT_FMT,&in.format))) + in.format |= af_bits2fmt(in.bps*8); + if(AF_OK != (rv = new->control(new,AF_CONTROL_FORMAT_FMT,&in.format))) return rv; // Initialize format filter if(!new->prev) @@ -444,8 +444,8 @@ int af_init(af_stream_t* s, int force_output) else af = s->last; // Init the new filter - if(!af ||(AF_OK != af->control(af,AF_CONTROL_FORMAT_BPS,&(s->output.bps))) - || (AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT,&(s->output.format)))) + s->output.format |= af_bits2fmt(s->output.bps*8); + if(!af || (AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT,&(s->output.format)))) return -1; if(AF_OK != af_reinit(s,af)) return -1; diff --git a/libaf/af_format.c b/libaf/af_format.c index 0d08cc0c38..6351928d55 100644 --- a/libaf/af_format.c +++ b/libaf/af_format.c @@ -110,6 +110,11 @@ inline int af_fmt2bits(int format) return -1; } +inline int af_bits2fmt(int bits) +{ + return (bits/8 - 1) << 3; +} + /* Convert format to str input str is a buffer for the converted string, size is the size of the buffer */ char* af_fmt2str(int format, char* str, int size) @@ -194,6 +199,53 @@ char *af_fmt2str_short(int format) return "??"; } +int af_str2fmt_short(char* str) +{ + int i; + static struct { + const char *name; + const int format; + } table[] = { + { "mulaw", AF_FORMAT_MU_LAW }, + { "alaw", AF_FORMAT_A_LAW }, + { "mpeg2", AF_FORMAT_MPEG2 }, + { "ac3", AF_FORMAT_AC3 }, + { "imaadpcm", AF_FORMAT_IMA_ADPCM }, + + { "u8", AF_FORMAT_U8 }, + { "s8", AF_FORMAT_S8 }, + { "u16le", AF_FORMAT_U16_LE }, + { "u16be", AF_FORMAT_U16_BE }, + { "u16ne", AF_FORMAT_U16_NE }, + { "s16le", AF_FORMAT_S16_LE }, + { "s16be", AF_FORMAT_S16_BE }, + { "s16ne", AF_FORMAT_S16_NE }, + { "u24le", AF_FORMAT_U24_LE }, + { "u24be", AF_FORMAT_U24_BE }, + { "u24ne", AF_FORMAT_U24_NE }, + { "s24le", AF_FORMAT_S24_LE }, + { "s24be", AF_FORMAT_S24_BE }, + { "s24ne", AF_FORMAT_S24_NE }, + { "u32le", AF_FORMAT_U32_LE }, + { "u32be", AF_FORMAT_U32_BE }, + { "u32ne", AF_FORMAT_U32_NE }, + { "s32le", AF_FORMAT_S32_LE }, + { "s32be", AF_FORMAT_S32_BE }, + { "s32ne", AF_FORMAT_S32_NE }, + { "floatle", AF_FORMAT_FLOAT_LE }, + { "floatbe", AF_FORMAT_FLOAT_BE }, + { "floatne", AF_FORMAT_FLOAT_NE }, + + { NULL, 0 } + }; + + for (i = 0; table[i].name; i++) + if (!strcasecmp(str, table[i].name)) + return table[i].format; + + return -1; +} + // Helper functions to check sanity for input arguments // Sanity check for bytes per sample @@ -212,6 +264,7 @@ static int check_format(int format) { char buf[256]; switch(format & AF_FORMAT_SPECIAL_MASK){ + case(AF_FORMAT_IMA_ADPCM): case(AF_FORMAT_MPEG2): case(AF_FORMAT_AC3): af_msg(AF_MSG_ERROR,"[format] Sample format %s not yet supported \n", @@ -279,52 +332,22 @@ static int control(struct af_instance_s* af, int cmd, void* arg) return AF_OK; } case AF_CONTROL_COMMAND_LINE:{ - int bps = 2; - int format = AF_FORMAT_NE; - char str[256]; - str[0] = '\0'; - sscanf((char*)arg,"%i:%s",&bps,str); - // Convert string to format - format = af_str2fmt(str); - - // Automatic correction of errors - switch(format & AF_FORMAT_SPECIAL_MASK){ - case(AF_FORMAT_A_LAW): - case(AF_FORMAT_MU_LAW): - bps=1; break; - case(AF_FORMAT_AC3): - bps=4; break; // I think - } - 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))) + int format = af_str2fmt_short(arg); + if(AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET,&format)) return AF_ERROR; return AF_OK; } - case AF_CONTROL_FORMAT_BPS | AF_CONTROL_SET: - // Reinit must be called after this function has been called - - // Check for errors in configuraton - if(AF_OK != check_bps(*(int*)arg)) - return AF_ERROR; - - af->data->bps = *(int*)arg; - return AF_OK; - case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET: - // Reinit must be called after this function has been called - + case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET:{ // Check for errors in configuraton if(AF_OK != check_format(*(int*)arg)) return AF_ERROR; af->data->format = *(int*)arg; + af->data->bps = af_fmt2bits(af->data->format)/8; + return AF_OK; } + } return AF_UNKNOWN; } diff --git a/libaf/af_format.h b/libaf/af_format.h index 3fa2bcf140..0f55b500a3 100644 --- a/libaf/af_format.h +++ b/libaf/af_format.h @@ -81,7 +81,9 @@ #endif extern int af_str2fmt(char *str); +extern int af_str2fmt_short(char *str); extern int af_fmt2bits(int format); +extern int af_bits2fmt(int bits); extern char* af_fmt2str(int format, char* str, int size); extern char* af_fmt2str_short(int format); diff --git a/libaf/control.h b/libaf/control.h index 31ad012b0b..aa51046dbd 100644 --- a/libaf/control.h +++ b/libaf/control.h @@ -113,13 +113,9 @@ typedef struct af_control_ext_s{ // Set resampling accuracy #define AF_CONTROL_RESAMPLE_ACCURACY 0x00000300 | AF_CONTROL_FILTER_SPECIFIC -// Format +// Format -// Set output format bits per sample -#define AF_CONTROL_FORMAT_BPS 0x00000400 | AF_CONTROL_FILTER_SPECIFIC - -// Set output format sample format -#define AF_CONTROL_FORMAT_FMT 0x00000500 | AF_CONTROL_FILTER_SPECIFIC +#define AF_CONTROL_FORMAT_FMT 0x00000400 | AF_CONTROL_FILTER_SPECIFIC // Channels