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>
30 #include "libavutil/common.h"
33 #include "audio_out.h"
34 #include "audio_out_internal.h"
35 #include "libaf/af_format.h"
36 #include "libmpdemux/mpeg_packetizer.h"
39 static const ao_info_t info
=
43 "Tobias Diedrich <ranma+mplayer@tdiedrich.de>",
50 static int last_freq_id
= -1;
53 // to set/get/query special features/parameters
54 static int control(int cmd
,void *arg
){
56 case AOCONTROL_GET_VOLUME
:
58 ao_control_vol_t
* vol
= (ao_control_vol_t
*)arg
;
59 vol
->left
= vol
->right
= volume
* 19.0 / 100.0;
63 case AOCONTROL_SET_VOLUME
:
67 ao_control_vol_t
* vol
= (ao_control_vol_t
*)arg
;
68 // We need this trick because the volume stepping is often too small
69 diff
= ((vol
->left
+vol
->right
) / 2 - (volume
*19.0/100.0)) * 19.0 / 100.0;
70 v
.arg
= volume
+ (diff
> 0 ? ceil(diff
) : floor(diff
));
71 if(v
.arg
> 19) v
.arg
= 19;
72 if(v
.arg
< 0) v
.arg
= 0;
75 if( ioctl(dxr2_fd
,DXR2_IOC_SET_AUDIO_VOLUME
,&v
) < 0) {
76 mp_tmsg(MSGT_AO
,MSGL_ERR
,"[AO DXR2] Setting volume to %d failed.\n",volume
);
84 return CONTROL_UNKNOWN
;
90 // open & setup audio device
91 // return: 1=success 0=fail
92 static int init(int rate
,int channels
,int format
,int flags
){
99 ao_data
.outburst
=2048;
100 ao_data
.samplerate
=rate
;
101 ao_data
.channels
=channels
;
102 ao_data
.buffersize
=2048;
104 ao_data
.format
=format
;
109 freq_id
=DXR2_AUDIO_FREQ_48
;
112 freq_id
=DXR2_AUDIO_FREQ_96
;
115 freq_id
=DXR2_AUDIO_FREQ_441
;
118 freq_id
=DXR2_AUDIO_FREQ_32
;
121 freq_id
=DXR2_AUDIO_FREQ_2205
;
123 #ifdef DXR2_AUDIO_FREQ_24
124 // This is not yet in the dxr2 driver CVS
125 // you can get the patch at
126 // http://www.tdiedrich.de/~ranma/patches/dxr2.pcm1723.20020513
128 freq_id
=DXR2_AUDIO_FREQ_24
;
131 freq_id
=DXR2_AUDIO_FREQ_64
;
134 freq_id
=DXR2_AUDIO_FREQ_882
;
138 mp_tmsg(MSGT_AO
,MSGL_ERR
,"[AO DXR2] %d Hz not supported, try to resample.\n",rate
);
145 // close audio device
146 static void uninit(int immed
){
150 // stop playing and empty buffers (for seeking/pause)
151 static void reset(void){
155 // stop playing, keep buffers (for pause)
156 static void audio_pause(void)
158 // for now, just call reset();
162 // resume playing, after audio_pause()
163 static void audio_resume(void)
168 // return: how many bytes can be played without blocking
169 static int get_space(void){
170 float x
=(float)(vo_pts
-ao_data
.pts
)/90000.0;
173 y
=freq
*4*x
;y
/=ao_data
.outburst
;y
*=ao_data
.outburst
;
178 static void dxr2_send_lpcm_packet(unsigned char* data
,int len
,int id
,unsigned int timestamp
,int freq_id
)
180 int write_dxr2(const unsigned char *data
, int len
);
183 mp_msg(MSGT_AO
,MSGL_ERR
,"DXR2 fd is not valid\n");
187 if(last_freq_id
!= freq_id
) {
188 ioctl(dxr2_fd
, DXR2_IOC_SET_AUDIO_SAMPLE_FREQUENCY
, &freq_id
);
189 last_freq_id
= freq_id
;
192 send_mpeg_lpcm_packet (data
, len
, id
, timestamp
, freq_id
, write_dxr2
);
195 // plays 'len' bytes of 'data'
196 // it should round it down to outburst*n
197 // return: number of bytes played
198 static int play(void* data
,int len
,int flags
){
199 int write_dxr2(const unsigned char *data
, int len
);
201 // MPEG and AC3 don't work :-(
202 if(ao_data
.format
==AF_FORMAT_MPEG2
)
203 send_mpeg_ps_packet (data
, len
, 0xC0, ao_data
.pts
, 2, write_dxr2
);
204 else if(AF_FORMAT_IS_AC3(ao_data
.format
))
205 send_mpeg_ps_packet (data
, len
, 0x80, ao_data
.pts
, 2, write_dxr2
);
208 //unsigned short *s=data;
211 for(i
=0;i
<len
/2;i
++) s
[i
] = bswap_16(s
[i
]);
213 dxr2_send_lpcm_packet(data
,len
,0xA0,ao_data
.pts
-10000,freq_id
);
218 // return: delay in seconds between first and last sample in buffer
219 static float get_delay(void){