1
mirror of https://github.com/mpv-player/mpv synced 2024-07-31 16:29:58 +02:00

commandline configuration of audio plugins now through struct, format conversion plugin added

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3195 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
anders 2001-11-29 12:44:06 +00:00
parent d94057426a
commit 41881ebf85
7 changed files with 262 additions and 51 deletions

View File

@ -68,9 +68,6 @@ extern char * skinName;
extern int use_old_pp;
#endif
// From audio plugins
extern int pl_delay_len;
/* from libvo/aspect.c */
extern float monitor_aspect;
@ -100,8 +97,8 @@ struct config conf[]={
{"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},
{"aop", &ao_plugin_cfg.plugin_list, CONF_TYPE_STRING, 0, 0, 0},
{"aop_delay", &ao_plugin_cfg.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},

View File

@ -4,7 +4,7 @@ include config.mak
LIBNAME = libao2.a
# TODO: moveout ao_sdl.c so it's only used when SDL is detected
SRCS=afmt.c audio_out.c ao_mpegpes.c ao_null.c ao_pcm.c ao_plugin.c pl_delay.c $(OPTIONAL_SRCS)
SRCS=afmt.c audio_out.c ao_mpegpes.c ao_null.c ao_pcm.c ao_plugin.c pl_delay.c pl_format.c $(OPTIONAL_SRCS)
OBJS=$(SRCS:.c=.o)
CFLAGS = $(OPTFLAGS) -I. -I.. $(SDL_INC) $(EXTRA_INC)

View File

@ -3,6 +3,7 @@
#include "../config.h"
#include "afmt.h"
#include "audio_out.h"
#include "audio_out_internal.h"
@ -21,32 +22,19 @@ LIBAO_EXTERN(plugin)
#define plugin(i) (ao_plugin_local_data.plugins[i])
#define driver() (ao_plugin_local_data.driver)
#define NPL 2 //Number of PLugins
extern ao_plugin_functions_t audio_plugin_delay;
// local data
typedef struct ao_plugin_local_data_s
{
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_functions_t* available_plugins[NPL]; // List of available plugins
} ao_plugin_local_data_t;
ao_plugin_local_data_t ao_plugin_local_data={
NULL,
NULL,
NULL,
{
&audio_plugin_delay,
NULL
}
};
ao_plugin_local_data_t ao_plugin_local_data={NULL,NULL,AO_PLUGINS};
// gloabal data
ao_plugin_data_t ao_plugin_data;
ao_plugin_data_t ao_plugin_data; // data used by the plugins
ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // cfg data set in cfg-mplayer.h
// to set/get/query special features/parameters
static int control(int cmd,int arg){
@ -54,9 +42,6 @@ static int control(int cmd,int arg){
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);
}
@ -119,8 +104,8 @@ static int init(int rate,int channels,int format,int flags){
/* Create list of plugins from cfg option */
int i=0;
if(ao_plugin_local_data.cfg_plugins){
if(!add_plugin(i,ao_plugin_local_data.cfg_plugins))
if(ao_plugin_cfg.plugin_list){
if(!add_plugin(i,ao_plugin_cfg.plugin_list))
return 0;
}
@ -153,7 +138,7 @@ static int init(int rate,int channels,int format,int flags){
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);
ok=plugin(--i)->control(AOCONTROL_PLUGIN_SET_LEN,0);
if(!ok) return 0;

View File

@ -1,4 +1,7 @@
/* functions supplied by plugins */
#ifndef __audio_plugin_h__
#define __audio_plugin_h__
// Functions supplied by plugins
typedef struct ao_plugin_functions_s
{
ao_info_t *info;
@ -9,7 +12,7 @@ typedef struct ao_plugin_functions_s
int (*play)();
} ao_plugin_functions_t;
/* Global data for all audio plugins */
// Global data for all audio plugins
typedef struct ao_plugin_data_s
{
void* data; /* current data block read only ok to change */
@ -25,7 +28,41 @@ typedef struct ao_plugin_data_s
extern ao_plugin_data_t ao_plugin_data;
//List of plugins
// Plugin confuguration data set by cmd-line parameters
typedef struct ao_plugin_cfg_s
{
char* plugin_list; // List of used plugins read from cfg
int pl_format_type; // Output format
int pl_delay_len; // Number of samples to delay sound output
} ao_plugin_cfg_t;
extern ao_plugin_cfg_t ao_plugin_cfg;
// Configuration defaults
#define CFG_DEFAULTS { \
NULL, \
AFMT_S16_LE, \
0 \
};
// This block should not be available in the pl_xxxx files
// due to compilation issues
#ifndef PLUGIN
#define NPL 2+1 // Number of PLugins ( +1 list ends with NULL )
// List of plugins
extern ao_plugin_functions_t audio_plugin_delay;
extern ao_plugin_functions_t audio_plugin_format;
#define AO_PLUGINS { \
&audio_plugin_delay, \
&audio_plugin_format, \
NULL \
}
#endif /* PLUGIN */
#define AOCONTROL_PLUGIN_SET_LEN 1
// Control parameters used by the plugins
#define AOCONTROL_PLUGIN_SET_LEN 1 // All plugins must respond to this parameter
#endif

View File

@ -3,6 +3,7 @@
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>
@ -14,7 +15,7 @@
static ao_info_t info =
{
"Null audio plugin",
"Delay audio plugin",
"delay",
"Anders",
""
@ -36,17 +37,14 @@ typedef struct pl_delay_s
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);
pl_delay.len = ao_plugin_data.len;
pl_delay.data=(void*)malloc(ao_plugin_data.len);
return CONTROL_OK;
}
return -1;
@ -64,17 +62,17 @@ static int init(){
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);
time_delay=-1*(float)ao_plugin_cfg.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);
pl_delay.delay=(void*)malloc(ao_plugin_cfg.pl_delay_len);
if(!pl_delay.delay)
return 0;
for(i=0;i<pl_delay_len;i++)
for(i=0;i<ao_plugin_cfg.pl_delay_len;i++)
((char*)pl_delay.delay)[i]=0;
printf("[pl_delay] Output sound delayed by %i bytes\n",pl_delay_len);
printf("[pl_delay] Output sound delayed by %i bytes\n",ao_plugin_cfg.pl_delay_len);
return 1;
}
@ -84,7 +82,7 @@ static void uninit(){
free(pl_delay.delay);
if(pl_delay.data)
free(pl_delay.data);
pl_delay_len=0;
ao_plugin_cfg.pl_delay_len=0;
}
// empty buffers
@ -92,7 +90,7 @@ 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++)
for(i=0;i<ao_plugin_cfg.pl_delay_len;i++)
((char*)pl_delay.delay)[i]=0;
}
@ -103,13 +101,13 @@ static int play(){
int j=0;
int k=0;
// Copy end of prev block to begining of buffer
for(i=0;i<pl_delay_len;i++,j++)
for(i=0;i<ao_plugin_cfg.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++)
for(i=0;i<ao_plugin_data.len-ao_plugin_cfg.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++)
for(i=0;i<ao_plugin_cfg.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;

195
libao2/pl_format.c Normal file
View File

@ -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;
}

View File

@ -46,6 +46,7 @@ extern void* mDisplay; // Display* mDisplay;
#endif
#include "libao2/audio_out.h"
#include "libao2/audio_plugin.h"
#include "libmpeg2/mpeg2.h"
#include "libmpeg2/mpeg2_internal.h"
@ -218,7 +219,6 @@ static int play_n_frames=-1;
// 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;
@ -763,12 +763,11 @@ play_next_file:
exit_player(MSGTR_Exit_error);
}
/* Initailize audio plugin interface if used */
if(audio_plugins){
if(ao_plugin_cfg.plugin_list){
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;
}