Mercurial > mplayer.hg
diff libao2/pl_format.c @ 3194:1648d11fc36c
commandline configuration of audio plugins now through struct, format conversion plugin added
author | anders |
---|---|
date | Thu, 29 Nov 2001 12:44:06 +0000 |
parents | |
children | 62d797a16f72 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libao2/pl_format.c Thu Nov 29 12:44:06 2001 +0000 @@ -0,0 +1,195 @@ +/* This is a null audio out plugin it doesnt't really do anything + useful but serves an example of how audio plugins work. It delays + the output signal by the nuber of samples set by aop_delay n + where n is the number of bytes. + */ +#define PLUGIN + +#include <stdio.h> +#include <stdlib.h> + +#include "audio_out.h" +#include "audio_plugin.h" +#include "audio_plugin_internal.h" +#include "afmt.h" + +static ao_info_t info = +{ + "Sample format conversion audio plugin", + "format", + "Anders", + "" +}; + +LIBAO_PLUGIN_EXTERN(format) + +// local data +typedef struct pl_format_s +{ + void* data; // local audio data block + int len; // local buffer length + int in; // Input fomat + int out; // Output fomat + double sz_mult; // data size multiplier +} pl_format_t; + +static pl_format_t pl_format={NULL,0,0,0,1}; + +// Number of bits +#define B08 0 +#define B16 1 +#define B32 2 +#define NBITS_MASK 3 + +// Endianess +#define BE (0<<3) // Big endian +#define LE (1<<3) // Little endian +#define END_MASK (1<<3) + +// Signed +#define US (0<<4) +#define SI (1<<4) +#define SIGN_MASK (1<<4) + +// to set/get/query special features/parameters +static int control(int cmd,int arg){ + switch(cmd){ + case AOCONTROL_PLUGIN_SET_LEN: + if(pl_format.data) + uninit(); + pl_format.len = ao_plugin_data.len; + pl_format.data=(void*)malloc(ao_plugin_data.len); + ao_plugin_data.len=(int)((double)ao_plugin_data.len*pl_format.sz_mult); + return CONTROL_OK; + } + return -1; +} + +// open & setup audio device +// return: 1=success 0=fail +static int init(){ + int i=0; + int sign=0; + int nbits=8; + int be_le=BE; + + // Sheck input format + switch(ao_plugin_data.format){ + case(AFMT_U8): + pl_format.in=LE|B08|US; break; + case(AFMT_S8): + pl_format.in=LE|B08|SI; break; + case(AFMT_S16_LE): + pl_format.in=LE|B16|US; break; + case(AFMT_S16_BE): + pl_format.in=BE|B16|SI; break; + case(AFMT_U16_LE): + pl_format.in=LE|B16|US; break; + case(AFMT_U16_BE): + pl_format.in=BE|B16|US; break; + case(AFMT_S32_LE): + pl_format.in=LE|B32|SI; break; + case(AFMT_S32_BE): + pl_format.in=BE|B32|SI; break; + case(AFMT_IMA_ADPCM): + case(AFMT_MU_LAW): + case(AFMT_A_LAW): + case(AFMT_MPEG): + case(AFMT_AC3): + printf("[pl_format] Audio format not yet suported \n"); + return 0; + default: + printf("[pl_format] Unsupported audio format\n"); // Should never happen... + return 0; + } + // Sheck output format + switch(ao_plugin_cfg.pl_format_type){ + case(AFMT_U8): + pl_format.in=LE|B08|US; break; + case(AFMT_S8): + pl_format.in=LE|B08|SI; break; + case(AFMT_S16_LE): + pl_format.in=LE|B16|US; break; + case(AFMT_S16_BE): + pl_format.in=BE|B16|SI; break; + case(AFMT_U16_LE): + pl_format.in=LE|B16|US; break; + case(AFMT_U16_BE): + pl_format.in=BE|B16|US; break; + case(AFMT_S32_LE): + pl_format.in=LE|B32|SI; break; + case(AFMT_S32_BE): + pl_format.in=BE|B32|SI; break; + case(AFMT_IMA_ADPCM): + case(AFMT_MU_LAW): + case(AFMT_A_LAW): + case(AFMT_MPEG): + case(AFMT_AC3): + printf("[pl_format] Audio format not yet suported \n"); + return 0; + default: + printf("[pl_format] Unsupported audio format\n"); // Should never happen... + return 0; + } + // We are changing the format + ao_plugin_data.format=ao_plugin_cfg.pl_format_type; + + // And perhaps the buffer size + pl_format.sz_mult=1; + if((pl_format.in&NBITS_MASK) < (pl_format.out&NBITS_MASK)) + pl_format.sz_mult/=(double)(1<<(pl_format.out-pl_format.in)); + if((pl_format.in&NBITS_MASK) > (pl_format.out&NBITS_MASK)) + pl_format.sz_mult*=(double)(1<<(pl_format.out-pl_format.in)); + ao_plugin_data.sz_mult*=pl_format.sz_mult; + return 1; +} + +// close plugin +static void uninit(){ + if(pl_format.data) + free(pl_format.data); +} + +// empty buffers +static void reset(){ + int i = 0; + for(i=0;i<pl_format.len;i++) + ((char*)pl_format.data)[i]=0; +} + +// processes 'ao_plugin_data.len' bytes of 'data' +// called for every block of data +static int play(){ + register int i=0; + void* in_data=ao_plugin_data.data; + void* out_data=pl_format.data; + int in_len=((int)(double)pl_format.len*pl_format.sz_mult); + in_len>>=pl_format.in&NBITS_MASK; + + if((pl_format.in&END_MASK)!=(pl_format.out&END_MASK)){ + switch(pl_format.in&NBITS_MASK){ + case(B16):{ + register int16_t s; + for(i=1;i<in_len;i++){ + s=((int16_t*)in_data)[i]; + ((int16_t*)in_data)[i]=(int16_t)(((s&0x00FF)<<8) | (s&0xFF00)>>8); + } + break; + } + case(B32):{ + register int32_t s; + for(i=1;i<in_len;i++){ + s=((int32_t*)in_data)[i]; + ((int32_t*)in_data)[i]=(int32_t)(((s&0x000000FF)<<24) | ((s&0x0000FF00)<<8) | + ((s&0x00FF0000)>>8) | ((s&0xFF000000)>>24)); + } + break; + } + } + } + + return 1; +} + + +