mirror of
https://github.com/mpv-player/mpv
synced 2024-12-27 09:32:40 +00:00
156cbec75f
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3196 b3059339-0415-0410-9bf9-f77b7e298cf2
197 lines
4.7 KiB
C
197 lines
4.7 KiB
C
/* 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 <unistd.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;
|
|
}
|
|
|
|
|
|
|