summaryrefslogtreecommitdiffstats
path: root/libao2
diff options
context:
space:
mode:
authoratmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-11-08 21:51:28 +0000
committeratmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-11-08 21:51:28 +0000
commit2f2350320a4a8039e9148ee772b10a451bfb08dd (patch)
treed3b777b29ad948b2287888d945a391f9a415c36b /libao2
parent63ecd0455c348a40e7a49ca7c2ee0b46c1c4a070 (diff)
downloadmpv-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.c171
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;
}