Mercurial > mplayer.hg
changeset 3107:ef2287ccc42b
Changes to audio out plugin, first plugin added
author | anders |
---|---|
date | Sun, 25 Nov 2001 14:29:54 +0000 |
parents | fd7651748dec |
children | 74bfcc3dd96b |
files | cfg-mplayer.h libao2/ao_plugin.c libao2/audio_out.h libao2/audio_plugin.h libao2/audio_plugin_internal.h libao2/pl_delay.c mplayer.c |
diffstat | 7 files changed, 252 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/cfg-mplayer.h Sun Nov 25 09:40:09 2001 +0000 +++ b/cfg-mplayer.h Sun Nov 25 14:29:54 2001 +0000 @@ -68,6 +68,8 @@ extern int use_old_pp; #endif +// From audio plugins +extern int pl_delay_len; /* from libvo/aspect.c */ extern float monitor_aspect; @@ -93,7 +95,10 @@ {"o", "Option -o has been renamed to -vo (video-out), use -vo !\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0}, {"vo", &video_driver, CONF_TYPE_STRING, 0, 0, 0}, + // -----options related to audio and audio plugins------- {"ao", &audio_driver, CONF_TYPE_STRING, 0, 0, 0}, + {"aop", &audio_plugins, CONF_TYPE_STRING, 0, 0, 0}, + {"aop_delay", &pl_delay_len, CONF_TYPE_INT, CONF_MIN, 0, 0}, // {"dsp", &dsp, CONF_TYPE_STRING, CONF_NOCFG, 0, 0}, {"dsp", "Use -ao oss:dsp_path!\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0}, {"mixer", &mixer_device, CONF_TYPE_STRING, 0, 0, 0},
--- a/libao2/ao_plugin.c Sun Nov 25 09:40:09 2001 +0000 +++ b/libao2/ao_plugin.c Sun Nov 25 14:29:54 2001 +0000 @@ -18,24 +18,98 @@ LIBAO_EXTERN(plugin) -#define plugin(i) (ao_plugin_local_data.ao_plugins[i]) -#define driver() (ao_plugin_local_data.ao_driver) +#define plugin(i) (ao_plugin_local_data.plugins[i]) +#define driver() (ao_plugin_local_data.driver) -/* local data */ +#define NPL 2 //Number of PLugins + +extern ao_plugin_functions_t audio_plugin_delay; + +// local data typedef struct ao_plugin_local_data_s { - ao_plugin_functions_t** ao_plugins; /* List of all plugins */ - ao_functions_t* ao_driver; /* ao driver used by ao_plugin */ + char* cfg_plugins; // List of plugins read from cfg-file + ao_functions_t* driver; // Output driver set in mplayer.c + ao_plugin_functions_t** plugins; // List of used plugins + ao_plugin_functions_t* available_plugins[NPL]; // List of abailabel plugins } ao_plugin_local_data_t; -ao_plugin_local_data_t ao_plugin_local_data; +ao_plugin_local_data_t ao_plugin_local_data={ + NULL, + NULL, + NULL, + { + &audio_plugin_delay, + NULL + } +}; -/* gloabal data */ +// gloabal data ao_plugin_data_t ao_plugin_data; + // to set/get/query special features/parameters static int control(int cmd,int arg){ - return driver()->control(cmd,arg); + switch(cmd){ + case AOCONTROL_SET_PLUGIN_DRIVER: + ao_plugin_local_data.driver=(ao_functions_t*)arg; + return CONTROL_OK; + case AOCONTROL_SET_PLUGIN_LIST: + ao_plugin_local_data.cfg_plugins=(char*)arg; + return CONTROL_OK; + default: + return driver()->control(cmd,arg); + } + return CONTROL_UNKNOWN; +} + +// Recursive function for adding plugins +// return 1 for success and 0 for error +int add_plugin(int i,char* cfg){ + int cnt=0; + // Find end of plugin name + while((cfg[cnt]!=',')&&(cfg[cnt]!='\0')&&(cnt<100)) cnt++; + if(cnt >= 100) + return 0; + + // Is this the last itteration or just another plugin + if(cfg[cnt]=='\0'){ + ao_plugin_local_data.plugins=malloc((i+1)*sizeof(ao_plugin_functions_t*)); + if(ao_plugin_local_data.plugins){ + ao_plugin_local_data.plugins[i+1]=NULL; + // Find the plugin matching the cfg string name + cnt=0; + while(ao_plugin_local_data.available_plugins[cnt] && cnt<20){ + if(0==strcmp(ao_plugin_local_data.available_plugins[cnt]->info->short_name,cfg)){ + ao_plugin_local_data.plugins[i]=ao_plugin_local_data.available_plugins[cnt]; + return 1; + } + cnt++; + } + printf("[plugin]: Invalid plugin: %s \n",cfg); + return 0; + } + else + return 0; + } else { + cfg[cnt]='\0'; + if(add_plugin(i+1,&cfg[cnt+1])){ + cnt=0; + // Find the plugin matching the cfg string name + while(ao_plugin_local_data.available_plugins[cnt] && cnt < 20){ + if(0==strcmp(ao_plugin_local_data.available_plugins[cnt]->info->short_name,cfg)){ + ao_plugin_local_data.plugins[i]=ao_plugin_local_data.available_plugins[cnt]; + return 1; + } + cnt++; + } + printf("[plugin]: Invalid plugin: %s \n",cfg); + return 0; + } + else + return 0; + } + return 0; // Will never happen... } // open & setup audio device and plugins @@ -43,11 +117,12 @@ static int init(int rate,int channels,int format,int flags){ int ok=1; - /* FIXME these are cfg file parameters */ + /* Create list of plugins from cfg option */ int i=0; - ao_plugin_local_data.ao_plugins=malloc((i+1)*sizeof(ao_plugin_functions_t*)); - plugin(i)=NULL; - ao_plugin_local_data.ao_driver=audio_out_drivers[1]; + if(ao_plugin_local_data.cfg_plugins){ + if(!add_plugin(i,ao_plugin_local_data.cfg_plugins)) + return 0; + } /* Set input parameters and itterate through plugins each plugin changes the parameters according to its output */ @@ -64,15 +139,23 @@ if(!ok) return 0; + // This should never happen but check anyway + if(NULL==ao_plugin_local_data.driver) + return 0; + ok = driver()->init(ao_plugin_data.rate, - ao_plugin_data.channels, - ao_plugin_data.format, - flags); + ao_plugin_data.channels, + ao_plugin_data.format, + flags); if(!ok) return 0; /* Now that the driver is initialized we can calculate and set the input and output buffers for each plugin */ ao_plugin_data.len=driver()->get_space(); + while((i>0) && ok) + ok=plugin(--i)->control(AOCONTROL_PLUGIN_SET_LEN,ao_plugin_data.len); + + if(!ok) return 0; return 1; } @@ -83,8 +166,8 @@ driver()->uninit(); while(plugin(i)) plugin(i++)->uninit(); - if(ao_plugin_local_data.ao_plugins) - free(ao_plugin_local_data.ao_plugins); + if(ao_plugin_local_data.plugins) + free(ao_plugin_local_data.plugins); } // stop playing and empty buffers (for seeking/pause)
--- a/libao2/audio_out.h Sun Nov 25 09:40:09 2001 +0000 +++ b/libao2/audio_out.h Sun Nov 25 14:29:54 2001 +0000 @@ -59,8 +59,12 @@ #define AOCONTROL_QUERY_FORMAT 3 /* test for availabilty of a format */ #define AOCONTROL_GET_VOLUME 4 #define AOCONTROL_SET_VOLUME 5 +#define AOCONTROL_SET_PLUGIN_DRIVER 6 +#define AOCONTROL_SET_PLUGIN_LIST 7 typedef struct ao_control_vol_s { float left; float right; } ao_control_vol_t; + +
--- a/libao2/audio_plugin.h Sun Nov 25 09:40:09 2001 +0000 +++ b/libao2/audio_plugin.h Sun Nov 25 14:29:54 2001 +0000 @@ -18,10 +18,14 @@ int channels; /* setup number of channels */ int format; /* setup format */ double sz_mult; /* Buffer size multiplier */ - double sz_fix; /* Fix extra buffer size */ + double sz_fix; /* Fix (as in static) extra buffer size */ float delay_mult; /* Delay multiplier */ float delay_fix; /* Fix delay */ }ao_plugin_data_t; extern ao_plugin_data_t ao_plugin_data; +//List of plugins + + +#define AOCONTROL_PLUGIN_SET_LEN 1
--- a/libao2/audio_plugin_internal.h Sun Nov 25 09:40:09 2001 +0000 +++ b/libao2/audio_plugin_internal.h Sun Nov 25 14:29:54 2001 +0000 @@ -1,11 +1,11 @@ // prototypes: static int control(int cmd,int arg); -static int init(float*); +static int init(); static void uninit(); static void reset(); -static int play(void* data,int len,int flags); +static int play(); -#define LIBAO_PLUGIN_EXTERN(x) ao_functions_t audio_out_##x =\ +#define LIBAO_PLUGIN_EXTERN(x) ao_functions_t audio_plugin_##x =\ {\ &info,\ control,\
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libao2/pl_delay.c Sun Nov 25 14:29:54 2001 +0000 @@ -0,0 +1,120 @@ +/* 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. + */ + +#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 = +{ + "Null audio plugin", + "delay", + "Anders", + "" +}; + +LIBAO_PLUGIN_EXTERN(delay) + +// local data +typedef struct pl_delay_s +{ + void* data; // local audio data block + void* delay; // data block used for delaying audio signal + int len; // local buffer length + int rate; // local data rate + int channels; // local number of channels + int format; // local format + +} pl_delay_t; + +static pl_delay_t pl_delay={NULL,NULL,0,0,0,0}; + +// global data +int pl_delay_len=0; // number of samples to delay sound output set from cmd line + +// to set/get/query special features/parameters +static int control(int cmd,int arg){ + switch(cmd){ + case AOCONTROL_PLUGIN_SET_LEN: + if(pl_delay.data) + uninit(); + pl_delay.len = arg; + pl_delay.data=(void*)malloc(arg); + return CONTROL_OK; + } + return -1; +} + +// open & setup audio device +// return: 1=success 0=fail +static int init(){ + int i=0; + float time_delay; // The number of tsamples this plugin delays the output data + /* if the output format of any of the below parameters differs from + what is give it should be changed. See ao_plugin init() */ + pl_delay.rate=ao_plugin_data.rate; + pl_delay.channels=ao_plugin_data.channels+1; //0=mono 1=stereo + pl_delay.format=ao_plugin_data.format; + + // Tell ao_plugin how much this plugin adds to the overall time delay + time_delay=-1*(float)pl_delay_len/((float)pl_delay.channels*(float)pl_delay.rate); + if(pl_delay.format != AFMT_U8 && pl_delay.format != AFMT_S8) + time_delay/=2; + ao_plugin_data.delay_fix+=time_delay; + + pl_delay.delay=(void*)malloc(pl_delay_len); + if(!pl_delay.delay) + return 0; + for(i=0;i<pl_delay_len;i++) + ((char*)pl_delay.delay)[i]=0; + printf("[pl_delay] Output sound delayed by %i bytes\n",pl_delay_len); + return 1; +} + +// close plugin +static void uninit(){ + if(pl_delay.delay) + free(pl_delay.delay); + if(pl_delay.data) + free(pl_delay.data); + pl_delay_len=0; +} + +// empty buffers +static void reset(){ + int i = 0; + for(i=0;i<pl_delay.len;i++) + ((char*)pl_delay.data)[i]=0; + for(i=0;i<pl_delay_len;i++) + ((char*)pl_delay.delay)[i]=0; +} + +// processes 'ao_plugin_data.len' bytes of 'data' +// called for every block of data +static int play(){ + int i=0; + int j=0; + int k=0; + // Copy end of prev block to begining of buffer + for(i=0;i<pl_delay_len;i++,j++) + ((char*)pl_delay.data)[j]=((char*)pl_delay.delay)[i]; + // Copy current block except end + for(i=0;i<ao_plugin_data.len-pl_delay_len;i++,j++,k++) + ((char*)pl_delay.data)[j]=((char*)ao_plugin_data.data)[k]; + // Save away end of current block for next call + for(i=0;i<pl_delay_len;i++,k++) + ((char*)pl_delay.delay)[i]=((char*)ao_plugin_data.data)[k]; + // Set output data block + ao_plugin_data.data=pl_delay.data; + return 1; +} + + +
--- a/mplayer.c Sun Nov 25 09:40:09 2001 +0000 +++ b/mplayer.c Sun Nov 25 14:29:54 2001 +0000 @@ -216,6 +216,7 @@ // screen info: char* video_driver=NULL; //"mga"; // default char* audio_driver=NULL; +char* audio_plugins=NULL; static int fullscreen=0; static int vidmode=0; static int softzoom=0; @@ -757,7 +758,20 @@ mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_InvalidAOdriver,audio_driver); exit_player(MSGTR_Exit_error); } -/*DSP!! if(dsp) audio_out->control(AOCONTROL_SET_DEVICE,(int)dsp);*/ + /* Initailize audio plugin interface if used */ + if(audio_plugins){ + for (i=0; audio_out_drivers[i] != NULL; i++){ + const ao_info_t *info = audio_out_drivers[i]->info; + if(strcmp(info->short_name,"plugin") == 0){ + audio_out_drivers[i]->control(AOCONTROL_SET_PLUGIN_DRIVER,(int)audio_out); + audio_out_drivers[i]->control(AOCONTROL_SET_PLUGIN_LIST,(int)audio_plugins); + audio_out = audio_out_drivers[i]; + break; + } + } + } + + current_module="spudec"; vo_spudec=spudec_new();