2 * DXR2 audio output driver
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <sys/ioctl.h>
26 #include <dxr2ioctl.h>
29 #include "libavutil/common.h"
32 #include "audio_out.h"
33 #include "audio_out_internal.h"
34 #include "libaf/af_format.h"
35 #include "libmpdemux/mpeg_packetizer.h"
38 static const ao_info_t info
=
42 "Tobias Diedrich <ranma+mplayer@tdiedrich.de>",
49 static int last_freq_id
= -1;
52 // to set/get/query special features/parameters
53 static int control(int cmd
,void *arg
){
55 case AOCONTROL_GET_VOLUME
:
57 ao_control_vol_t
* vol
= (ao_control_vol_t
*)arg
;
58 vol
->left
= vol
->right
= volume
* 19.0 / 100.0;
62 case AOCONTROL_SET_VOLUME
:
66 ao_control_vol_t
* vol
= (ao_control_vol_t
*)arg
;
67 // We need this trick because the volume stepping is often too small
68 diff
= ((vol
->left
+vol
->right
) / 2 - (volume
*19.0/100.0)) * 19.0 / 100.0;
69 v
.arg
= volume
+ (diff
> 0 ? ceil(diff
) : floor(diff
));
70 if(v
.arg
> 19) v
.arg
= 19;
71 if(v
.arg
< 0) v
.arg
= 0;
74 if( ioctl(dxr2_fd
,DXR2_IOC_SET_AUDIO_VOLUME
,&v
) < 0) {
75 mp_tmsg(MSGT_AO
,MSGL_ERR
,"[AO DXR2] Setting volume to %d failed.\n",volume
);
83 return CONTROL_UNKNOWN
;
89 // open & setup audio device
90 // return: 1=success 0=fail
91 static int init(int rate
,int channels
,int format
,int flags
){
98 ao_data
.outburst
=2048;
99 ao_data
.samplerate
=rate
;
100 ao_data
.channels
=channels
;
101 ao_data
.buffersize
=2048;
103 ao_data
.format
=format
;
108 freq_id
=DXR2_AUDIO_FREQ_48
;
111 freq_id
=DXR2_AUDIO_FREQ_96
;
114 freq_id
=DXR2_AUDIO_FREQ_441
;
117 freq_id
=DXR2_AUDIO_FREQ_32
;
120 freq_id
=DXR2_AUDIO_FREQ_2205
;
122 #ifdef DXR2_AUDIO_FREQ_24
123 // This is not yet in the dxr2 driver CVS
124 // you can get the patch at
125 // http://www.tdiedrich.de/~ranma/patches/dxr2.pcm1723.20020513
127 freq_id
=DXR2_AUDIO_FREQ_24
;
130 freq_id
=DXR2_AUDIO_FREQ_64
;
133 freq_id
=DXR2_AUDIO_FREQ_882
;
137 mp_tmsg(MSGT_AO
,MSGL_ERR
,"[AO DXR2] %d Hz not supported, try to resample.\n",rate
);
144 // close audio device
145 static void uninit(int immed
){
149 // stop playing and empty buffers (for seeking/pause)
150 static void reset(void){
154 // stop playing, keep buffers (for pause)
155 static void audio_pause(void)
157 // for now, just call reset();
161 // resume playing, after audio_pause()
162 static void audio_resume(void)
167 // return: how many bytes can be played without blocking
168 static int get_space(void){
169 float x
=(float)(vo_pts
-ao_data
.pts
)/90000.0;
172 y
=freq
*4*x
;y
/=ao_data
.outburst
;y
*=ao_data
.outburst
;
177 static void dxr2_send_lpcm_packet(unsigned char* data
,int len
,int id
,unsigned int timestamp
,int freq_id
)
179 int write_dxr2(const unsigned char *data
, int len
);
182 mp_msg(MSGT_AO
,MSGL_ERR
,"DXR2 fd is not valid\n");
186 if(last_freq_id
!= freq_id
) {
187 ioctl(dxr2_fd
, DXR2_IOC_SET_AUDIO_SAMPLE_FREQUENCY
, &freq_id
);
188 last_freq_id
= freq_id
;
191 send_mpeg_lpcm_packet (data
, len
, id
, timestamp
, freq_id
, write_dxr2
);
194 // plays 'len' bytes of 'data'
195 // it should round it down to outburst*n
196 // return: number of bytes played
197 static int play(void* data
,int len
,int flags
){
198 int write_dxr2(const unsigned char *data
, int len
);
200 // MPEG and AC3 don't work :-(
201 if(ao_data
.format
==AF_FORMAT_MPEG2
)
202 send_mpeg_ps_packet (data
, len
, 0xC0, ao_data
.pts
, 2, write_dxr2
);
203 else if(AF_FORMAT_IS_AC3(ao_data
.format
))
204 send_mpeg_ps_packet (data
, len
, 0x80, ao_data
.pts
, 2, write_dxr2
);
207 //unsigned short *s=data;
210 for(i
=0;i
<len
/2;i
++) s
[i
] = bswap_16(s
[i
]);
212 dxr2_send_lpcm_packet(data
,len
,0xA0,ao_data
.pts
-10000,freq_id
);
217 // return: delay in seconds between first and last sample in buffer
218 static float get_delay(void){