ao_dxr2.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 204 行
C
204 行
#include <math.h>#include <mplaylib.h>#include "mplaylib.h"#include <sys/ioctl.h>#include <inttypes.h>#include <dxr2ioctl.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "libavutil/common.h"#include "mpbswap.h"#include "audio_out.h"#include "audio_out_internal.h"#include "libaf/af_format.h"#include "libmpdemux/mpeg_packetizer.h"static ao_info_t info ={ "DXR2 audio output", "dxr2", "Tobias Diedrich <ranma+mplayer@tdiedrich.de>", ""};LIBAO_EXTERN(dxr2)static int volume=19;static int last_freq_id = -1;extern int dxr2_fd;// to set/get/query special features/parametersstatic int control(int cmd,void *arg){ switch(cmd){ case AOCONTROL_GET_VOLUME: if(dxr2_fd > 0) { ao_control_vol_t* vol = (ao_control_vol_t*)arg; vol->left = vol->right = volume * 19.0 / 100.0; return CONTROL_OK; } return CONTROL_ERROR; case AOCONTROL_SET_VOLUME: if(dxr2_fd > 0) { dxr2_oneArg_t v; float diff; ao_control_vol_t* vol = (ao_control_vol_t*)arg; // We need this trick because the volume stepping is often too small diff = ((vol->left+vol->right) / 2 - (volume*19.0/100.0)) * 19.0 / 100.0; v.arg = volume + (diff > 0 ? ceil(diff) : floor(diff)); if(v.arg > 19) v.arg = 19; if(v.arg < 0) v.arg = 0; if(v.arg != volume) { volume = v.arg; if( ioctl(dxr2_fd,DXR2_IOC_SET_AUDIO_VOLUME,&v) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_DXR2_SetVolFailed,volume); return CONTROL_ERROR; } } return CONTROL_OK; } return CONTROL_ERROR; } return CONTROL_UNKNOWN;}static int freq=0;static int freq_id=0;// open & setup audio device// return: 1=success 0=failstatic int init(int rate,int channels,int format,int flags){ if(dxr2_fd <= 0) return 0; last_freq_id = -1; ao_data.outburst=2048; ao_data.samplerate=rate; ao_data.channels=channels; ao_data.buffersize=2048; ao_data.bps=rate*4; ao_data.format=format; freq=rate; switch(rate){ case 48000: freq_id=DXR2_AUDIO_FREQ_48; break; case 96000: freq_id=DXR2_AUDIO_FREQ_96; break; case 44100: freq_id=DXR2_AUDIO_FREQ_441; break; case 32000: freq_id=DXR2_AUDIO_FREQ_32; break; case 22050: freq_id=DXR2_AUDIO_FREQ_2205; break;#ifdef DXR2_AUDIO_FREQ_24 // This is not yet in the dxr2 driver CVS // you can get the patch at // http://www.tdiedrich.de/~ranma/patches/dxr2.pcm1723.20020513 case 24000: freq_id=DXR2_AUDIO_FREQ_24; break; case 64000: freq_id=DXR2_AUDIO_FREQ_64; break; case 88200: freq_id=DXR2_AUDIO_FREQ_882; break;#endif default: mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_DXR2_UnsupSamplerate,rate); return 0; } return 1;}// close audio devicestatic void uninit(int immed){}// stop playing and empty buffers (for seeking/pause)static void reset(void){}// stop playing, keep buffers (for pause)static void audio_pause(void){ // for now, just call reset(); reset();}// resume playing, after audio_pause()static void audio_resume(void){}extern int vo_pts;// return: how many bytes can be played without blockingstatic int get_space(void){ float x=(float)(vo_pts-ao_data.pts)/90000.0; int y; if(x<=0) return 0; y=freq*4*x;y/=ao_data.outburst;y*=ao_data.outburst; if(y>32768) y=32768; return y;}static void dxr2_send_lpcm_packet(unsigned char* data,int len,int id,unsigned int timestamp,int freq_id){ extern int write_dxr2(unsigned char *data, int len); if(dxr2_fd < 0) { mp_msg(MSGT_AO,MSGL_ERR,"DXR2 fd is not valid\n"); return; } if(last_freq_id != freq_id) { ioctl(dxr2_fd, DXR2_IOC_SET_AUDIO_SAMPLE_FREQUENCY, &freq_id); last_freq_id = freq_id; } send_mpeg_lpcm_packet (data, len, id, timestamp, freq_id, write_dxr2);}// plays 'len' bytes of 'data'// it should round it down to outburst*n// return: number of bytes playedstatic int play(void* data,int len,int flags){ extern int write_dxr2(unsigned char *data, int len); // MPEG and AC3 don't work :-( if(ao_data.format==AF_FORMAT_MPEG2) send_mpeg_ps_packet (data, len, 0xC0, ao_data.pts, 2, write_dxr2); else if(ao_data.format==AF_FORMAT_AC3) send_mpeg_ps_packet (data, len, 0x80, ao_data.pts, 2, write_dxr2); else { int i; //unsigned short *s=data; uint16_t *s=data;#ifndef WORDS_BIGENDIAN for(i=0;i<len/2;i++) s[i] = bswap_16(s[i]);#endif dxr2_send_lpcm_packet(data,len,0xA0,ao_data.pts-10000,freq_id); } return len;}// return: delay in seconds between first and last sample in bufferstatic float get_delay(void){ return 0.0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?