Mercurial > mplayer.hg
annotate libao2/ao_dxr3.c @ 3219:2998f74ad64e
fixed
author | alex |
---|---|
date | Fri, 30 Nov 2001 16:50:37 +0000 |
parents | 8ba06b63f873 |
children | 4bc4354ec88e |
rev | line source |
---|---|
2645 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
2770 | 3 |
2921 | 4 #include <linux/em8300.h> |
2770 | 5 #include <sys/ioctl.h> |
2645 | 6 #include <unistd.h> |
2770 | 7 #include <sys/time.h> |
2645 | 8 #include <sys/types.h> |
2770 | 9 #include <sys/stat.h> |
10 #include <fcntl.h> | |
2645 | 11 |
12 #include "../config.h" | |
13 | |
14 #include "afmt.h" | |
15 | |
16 #include "audio_out.h" | |
17 #include "audio_out_internal.h" | |
18 | |
3186 | 19 void perror( const char *s ); |
20 #include <errno.h> | |
21 int sys_nerr; | |
2770 | 22 extern int verbose; |
2645 | 23 |
24 static ao_info_t info = | |
25 { | |
26 "DXR3/H+ audio out", | |
27 "dxr3", | |
28 "David Holm <dholm@iname.com>", | |
29 "" | |
30 }; | |
31 | |
32 LIBAO_EXTERN(dxr3) | |
33 | |
2770 | 34 static audio_buf_info dxr3_buf_info; |
2921 | 35 static int fd_control = 0, fd_audio = 0; |
2770 | 36 |
2645 | 37 // to set/get/query special features/parameters |
38 static int control(int cmd,int arg) | |
39 { | |
40 switch(cmd) | |
41 { | |
42 case AOCONTROL_QUERY_FORMAT: | |
43 return CONTROL_TRUE; | |
44 case AOCONTROL_GET_VOLUME: | |
45 case AOCONTROL_SET_VOLUME: | |
2770 | 46 return CONTROL_OK; |
47 return CONTROL_ERROR; | |
2645 | 48 } |
2770 | 49 return CONTROL_UNKNOWN; |
2645 | 50 } |
51 | |
52 // open & setup audio device | |
53 // return: 1=success 0=fail | |
54 static int init(int rate,int channels,int format,int flags) | |
55 { | |
2921 | 56 int ioval; |
57 fd_audio = open( "/dev/em8300_ma", O_WRONLY ); | |
58 if( fd_audio < 0 ) | |
59 { | |
2968 | 60 printf("AO: [dxr3] Can't open audio device /dev/em8300_ma -> nosound\n"); |
2921 | 61 return 0; |
62 } | |
2770 | 63 |
2921 | 64 fd_control = open( "/dev/em8300", O_WRONLY ); |
65 if( fd_control < 0 ) | |
2770 | 66 { |
2968 | 67 printf("AO: [dxr3] Can't open em8300 control /dev/em8300\n"); |
2770 | 68 return 0; |
69 } | |
3186 | 70 |
71 ioctl(fd_audio, SNDCTL_DSP_RESET, NULL); | |
72 ao_data.format = format; | |
73 if( ioctl (fd_audio, SNDCTL_DSP_SETFMT, &ao_data.format) < 0 ) | |
2968 | 74 printf( "AO: [dxr3] Unable to set audio format\n" ); |
3186 | 75 if(format == AFMT_AC3 && ao_data.format != AFMT_AC3) |
2770 | 76 { |
2968 | 77 printf("AO: [dxr3] Can't set audio device /dev/em8300_ma to AC3 output\n"); |
2770 | 78 return 0; |
79 } | |
2968 | 80 printf("AO: [dxr3] Sample format: %s (requested: %s)\n", |
3186 | 81 audio_out_format_name(ao_data.format), audio_out_format_name(format)); |
2770 | 82 |
83 if(format != AFMT_AC3) | |
84 { | |
3186 | 85 ao_data.channels=channels-1; |
86 if( ioctl (fd_audio, SNDCTL_DSP_STEREO, &ao_data.channels) < 0 ) | |
2968 | 87 printf( "AO: [dxr3] Unable to set number of channels\n" ); |
2770 | 88 |
89 // set rate | |
3186 | 90 ao_data.bps = (channels+1)*rate; |
91 ao_data.samplerate=rate; | |
92 if( ioctl (fd_audio, SNDCTL_DSP_SPEED, &ao_data.samplerate) < 0 ) | |
2968 | 93 printf( "AO: [dxr3] Unable to set samplerate\n" ); |
3186 | 94 printf("AO: [dxr3] Using %d Hz samplerate (requested: %d)\n",ao_data.samplerate,rate); |
2770 | 95 } |
3186 | 96 else ao_data.bps *= 2; |
2770 | 97 |
2968 | 98 if( ioctl(fd_audio, SNDCTL_DSP_GETOSPACE, &dxr3_buf_info)==-1 ) |
99 { | |
2770 | 100 int r=0; |
2968 | 101 printf("AO: [dxr3] Driver doesn't support SNDCTL_DSP_GETOSPACE :-(\n"); |
102 if( ioctl( fd_audio, SNDCTL_DSP_GETBLKSIZE, &r) ==-1 ) | |
103 { | |
3186 | 104 printf( "AO: [dxr3] %d bytes/frag (config.h)\n", ao_data.outburst ); |
2968 | 105 } |
106 else | |
107 { | |
3186 | 108 ao_data.outburst=r; |
109 printf( "AO: [dxr3] %d bytes/frag (GETBLKSIZE)\n",ao_data.outburst); | |
2770 | 110 } |
2968 | 111 } |
112 else | |
113 { | |
114 printf("AO: [dxr3] frags: %3d/%d (%d bytes/frag) free: %6d\n", | |
115 dxr3_buf_info.fragments+1, dxr3_buf_info.fragstotal, dxr3_buf_info.fragsize, dxr3_buf_info.bytes); | |
3218
8ba06b63f873
Fix green borders -> black borders, patch from D. Holm, also small fix to dxr3 ao.
atmos4
parents:
3201
diff
changeset
|
116 ao_data.buffersize=(dxr3_buf_info.bytes/2); |
3186 | 117 ao_data.outburst=dxr3_buf_info.fragsize; |
2770 | 118 } |
2645 | 119 |
2921 | 120 ioval = EM8300_PLAYMODE_PLAY; |
2968 | 121 if( ioctl( fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval ) < 0 ) |
122 printf( "AO: [dxr3] Unable to set playmode\n" ); | |
2921 | 123 close( fd_control ); |
2770 | 124 |
125 return 1; | |
2645 | 126 } |
127 | |
128 // close audio device | |
129 static void uninit() | |
130 { | |
2968 | 131 printf( "AO: [dxr3] Uninitializing\n" ); |
132 if( ioctl(fd_audio, SNDCTL_DSP_RESET, NULL) < 0 ) | |
133 printf( "AO: [dxr3] Unable to reset device\n" ); | |
2921 | 134 close( fd_audio ); |
3186 | 135 close( fd_control ); /* Just in case */ |
2645 | 136 } |
137 | |
138 // stop playing and empty buffers (for seeking/pause) | |
139 static void reset() | |
140 { | |
2968 | 141 if( ioctl(fd_audio, SNDCTL_DSP_RESET, NULL) < 0 ) |
142 printf( "AO: [dxr3] Unable to reset device\n" ); | |
2645 | 143 } |
144 | |
145 // stop playing, keep buffers (for pause) | |
146 static void audio_pause() | |
147 { | |
2968 | 148 int ioval; |
3201 | 149 reset(); |
2968 | 150 fd_control = open( "/dev/em8300", O_WRONLY ); |
151 if( fd_control < 0 ) | |
152 printf( "AO: [dxr3] Oops, unable to pause playback\n" ); | |
153 else | |
154 { | |
155 ioval = EM8300_PLAYMODE_PAUSED; | |
156 if( ioctl( fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval ) < 0 ) | |
157 printf( "AO: [dxr3] Unable to pause playback\n" ); | |
158 close( fd_control ); | |
159 } | |
2645 | 160 } |
161 | |
162 // resume playing, after audio_pause() | |
163 static void audio_resume() | |
164 { | |
2968 | 165 int ioval; |
166 fd_control = open( "/dev/em8300", O_WRONLY ); | |
167 if( fd_control < 0 ) | |
168 printf( "AO: [dxr3] Oops, unable to resume playback\n" ); | |
169 else | |
170 { | |
171 ioval = EM8300_PLAYMODE_PLAY; | |
172 if( ioctl( fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval ) < 0 ) | |
173 printf( "AO: [dxr3] Unable to resume playback\n" ); | |
174 close( fd_control ); | |
175 } | |
2645 | 176 } |
177 | |
178 // return: how many bytes can be played without blocking | |
179 static int get_space() | |
180 { | |
2968 | 181 int space = 0; |
3186 | 182 if( ioctl(fd_audio, SNDCTL_DSP_GETODELAY, &space) < 0 ) |
2968 | 183 { |
3186 | 184 printf( "AO: [dxr3] Unable to get unplayed bytes in buffer\n" ); |
185 return ao_data.outburst; | |
2968 | 186 } |
3186 | 187 space = ao_data.buffersize - space; |
3201 | 188 space /= ao_data.outburst; /* This is a smart way of doing a fast modulo reduction */ |
189 space *= ao_data.outburst; /* fetched from ao_mpegpes.c */ | |
2968 | 190 return space; |
2645 | 191 } |
192 | |
193 static int play(void* data,int len,int flags) | |
194 { | |
3186 | 195 if( ioctl( fd_audio, EM8300_IOCTL_AUDIO_SETPTS, &ao_data.pts ) < 0 ) |
3201 | 196 printf( "AO: [dxr3] Unable to set PTS\n" ); |
2921 | 197 return write(fd_audio,data,len); |
2645 | 198 } |
199 | |
200 // return: how many unplayed bytes are in the buffer | |
3186 | 201 static float get_delay() |
2645 | 202 { |
3201 | 203 /* int r=0; |
3186 | 204 if( ioctl(fd_audio, SNDCTL_DSP_GETODELAY, &r) < 0 ) |
205 { | |
2968 | 206 printf( "AO: [dxr3] Unable to get unplayed bytes in buffer\n" ); |
3186 | 207 return ((float)ao_data.buffersize)/(float)ao_data.bps; |
208 } | |
3201 | 209 return (((float)r)/(float)ao_data.bps);*/ |
210 return 0.0; | |
2645 | 211 } |
212 |