diff options
author | atmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-11-08 21:51:28 +0000 |
---|---|---|
committer | atmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-11-08 21:51:28 +0000 |
commit | 2f2350320a4a8039e9148ee772b10a451bfb08dd (patch) | |
tree | d3b777b29ad948b2287888d945a391f9a415c36b /libao2 | |
parent | 63ecd0455c348a40e7a49ca7c2ee0b46c1c4a070 (diff) | |
download | mpv-2f2350320a4a8039e9148ee772b10a451bfb08dd.tar.bz2 mpv-2f2350320a4a8039e9148ee772b10a451bfb08dd.tar.xz |
DXR3 beta2 patch by David Holm.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2771 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libao2')
-rw-r--r-- | libao2/ao_dxr3.c | 171 |
1 files changed, 102 insertions, 69 deletions
diff --git a/libao2/ao_dxr3.c b/libao2/ao_dxr3.c index 25ce523f96..7725c20868 100644 --- a/libao2/ao_dxr3.c +++ b/libao2/ao_dxr3.c @@ -1,10 +1,12 @@ #include <stdio.h> #include <stdlib.h> -#include <time.h> + +#include <sys/ioctl.h> #include <unistd.h> +#include <sys/time.h> #include <sys/types.h> -#include <sys/ioctl.h> - +#include <sys/stat.h> +#include <fcntl.h> #include <libdxr3/api.h> #include "../config.h" @@ -14,12 +16,7 @@ #include "audio_out.h" #include "audio_out_internal.h" -struct -{ - int ao_format; - int ao_rate; - int ao_channels; -} ao_device; +extern int verbose; static ao_info_t info = { @@ -39,86 +36,129 @@ LIBAO_EXTERN(dxr3) // ao_outburst // ao_buffersize +static char *em8300_ma="/dev/em8300_ma"; +static audio_buf_info dxr3_buf_info; + // to set/get/query special features/parameters static int control(int cmd,int arg) { switch(cmd) { - case AOCONTROL_SET_DEVICE: - return CONTROL_OK; case AOCONTROL_QUERY_FORMAT: return CONTROL_TRUE; case AOCONTROL_GET_VOLUME: case AOCONTROL_SET_VOLUME: - { - return CONTROL_OK; - } + return CONTROL_OK; + return CONTROL_ERROR; } - return CONTROL_TRUE; + return CONTROL_UNKNOWN; } // open & setup audio device // return: 1=success 0=fail static int init(int rate,int channels,int format,int flags) { - ao_device.ao_format = format; - ao_device.ao_rate = rate; - ao_device.ao_channels = channels; - - if( dxr3_get_status() == DXR3_STATUS_CLOSED ) + if( dxr3_get_status() == DXR3_STATUS_CLOSED ) + if( dxr3_open( "/dev/em8300" ) < 0 ) { - if( dxr3_open( "/dev/em8300", "/etc/dxr3.ux" ) != 0 ) printf( "Error loading /dev/em8300 with /etc/dxr3.ux microcode\n" ); - printf( "DXR3 status: &s\n", dxr3_get_status() ? "opened":"closed" ); + printf( "Failed to initialize the DXR3\n" ); + return 0; } - else - printf( "DXR3 already open\n" ); - - if( dxr3_set_playmode( DXR3_PLAYMODE_PLAY ) != 0 ) printf( "Error setting playmode of DXR3\n" ); - - if( format == AFMT_AC3 ) - { - if( dxr3_audio_set_mode( DXR3_AUDIOMODE_DIGITALAC3 ) != 0 ) - { - printf( "Cannot set DXR3 to AC3 playback!\n" ); - return -1; - } + + if( dxr3_audio_get_filedescriptor( ) < 0 ) + { + printf("Can't open audio device %s -> nosound\n",em8300_ma); + return 0; + } + + ao_format = format; + ioctl (dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_SETFMT, &ao_format); + if(format == AFMT_AC3 && ao_format != AFMT_AC3) + { + printf("Can't set audio device %s to AC3 output\n", em8300_ma); + return 0; + } + printf("audio_setup: sample format: %s (requested: %s)\n", + audio_out_format_name(ao_format), audio_out_format_name(format)); + + if(format != AFMT_AC3) + { + ao_channels=channels-1; + ioctl (dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_STEREO, &ao_channels); + + // set rate + ao_samplerate=rate; + ioctl (dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_SPEED, &ao_samplerate); + printf("audio_setup: using %d Hz samplerate (requested: %d)\n",ao_samplerate,rate); + } + + if(ioctl(dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_GETOSPACE, &dxr3_buf_info)==-1){ + int r=0; + printf("audio_setup: driver doesn't support SNDCTL_DSP_GETOSPACE :-(\n"); + if(ioctl(dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_GETBLKSIZE, &r)==-1){ + printf("audio_setup: %d bytes/frag (config.h)\n",ao_outburst); + } else { + ao_outburst=r; + printf("audio_setup: %d bytes/frag (GETBLKSIZE)\n",ao_outburst); + } + } else { + printf("audio_setup: frags: %3d/%d (%d bytes/frag) free: %6d\n", + dxr3_buf_info.fragments, dxr3_buf_info.fragstotal, dxr3_buf_info.fragsize, dxr3_buf_info.bytes); + if(ao_buffersize==-1) ao_buffersize=dxr3_buf_info.bytes; + ao_outburst=dxr3_buf_info.fragsize; + } + + if(ao_buffersize==-1){ + // Measuring buffer size: + void* data; + ao_buffersize=0; +#ifdef HAVE_AUDIO_SELECT + data=malloc(ao_outburst); memset(data,0,ao_outburst); + while(ao_buffersize<0x40000){ + fd_set rfds; + struct timeval tv; + FD_ZERO(&rfds); FD_SET(dxr3_audio_get_filedescriptor( ),&rfds); + tv.tv_sec=0; tv.tv_usec = 0; + if(!select(dxr3_audio_get_filedescriptor( )+1, NULL, &rfds, NULL, &tv)) break; + write(dxr3_audio_get_filedescriptor( ),data,ao_outburst); + ao_buffersize+=ao_outburst; } - else - { - if( dxr3_audio_set_mode( DXR3_AUDIOMODE_ANALOG ) != 0 ) - { - printf( "Cannot set DXR3 to analog playback!\n" ); - return -1; - } - if( format == AFMT_U8 ) - dxr3_audio_set_samplesize( 8 ); - else if( format == AFMT_S16_LE ) - dxr3_audio_set_samplesize( 16 ); - else - { - printf( "Unsupported audio format\n" ); - return -1; - } + free(data); + if(ao_buffersize==0){ + printf("\n *** Your audio driver DOES NOT support select() ***\n"); + printf("Recompile mplayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n"); + return 0; } - - dxr3_audio_set_stereo( (channels > 1) ? "true":"false" ); - dxr3_audio_set_rate( rate ); +#endif + } - return 1; + + return 1; } // close audio device static void uninit() { - dxr3_close(); + ioctl(dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_RESET, NULL); + dxr3_close( ); } // stop playing and empty buffers (for seeking/pause) static void reset() { uninit(); - if( !init( ao_device.ao_rate, ao_device.ao_channels, ao_device.ao_format, 0 ) ) + if(dxr3_audio_get_filedescriptor( )<0) + { printf("\nFatal error: *** CANNOT RE-OPEN / RESET AUDIO DEVICE ***\n"); + return; + } + + ioctl (dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_SETFMT, &ao_format); + if(ao_format != AFMT_AC3) + { + ioctl (dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_STEREO, &ao_channels); + ioctl (dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_SPEED, &ao_samplerate); + } } // stop playing, keep buffers (for pause) @@ -137,27 +177,20 @@ static void audio_resume() // return: how many bytes can be played without blocking static int get_space() { - return dxr3_audio_get_buffersize()-dxr3_audio_get_bytesleft(); + if(ioctl(dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_GETOSPACE, &dxr3_buf_info)!=-1) + return (dxr3_buf_info.fragments*dxr3_buf_info.fragsize); } -// plays 'len' bytes of 'data' -// it should round it down to outburst*n -// return: number of bytes played static int play(void* data,int len,int flags) { - if(len) - if( ao_device.ao_format == AFMT_AC3 ) - return dxr3_audio_write_ac3( data, len ); - else - return dxr3_audio_write_ac3( data, len ); - - printf( "Invalid audio data\n" ); - return 0; + return write(dxr3_audio_get_filedescriptor( ),data,len);; } // return: how many unplayed bytes are in the buffer static int get_delay() { - return dxr3_audio_get_bytesleft(); + int r=0; + if(ioctl(dxr3_audio_get_filedescriptor( ), SNDCTL_DSP_GETODELAY, &r)!=-1) + return r; } |