Mercurial > mplayer.hg
annotate libao2/ao_alsa9.c @ 9593:e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
Syntax is we decided, so you can give the nomes or not with both
vop and vf. vf take precedence over vop.
author | albeu |
---|---|
date | Sat, 15 Mar 2003 18:01:02 +0000 |
parents | f023b30c80e5 |
children | 12b1790038b0 |
rev | line source |
---|---|
1050 | 1 /* |
2 ao_alsa9 - ALSA-0.9.x output plugin for MPlayer | |
3 | |
4 (C) Alex Beregszaszi <alex@naxine.org> | |
6193
2fd9ec444098
AC3 passthrough support by Andy Lo A Foe <andy at alsaplayer dot org>
alex
parents:
5857
diff
changeset
|
5 |
7077 | 6 modified for real alsa-0.9.0-support by Joy Winter <joy@pingfm.org> |
7 additional AC3 passthrough support by Andy Lo A Foe <andy@alsaplayer.org> | |
8 08/22/2002 iec958-init rewritten and merged with common init, joy | |
6193
2fd9ec444098
AC3 passthrough support by Andy Lo A Foe <andy at alsaplayer dot org>
alex
parents:
5857
diff
changeset
|
9 |
7077 | 10 Any bugreports regarding to this driver are welcome. |
1050 | 11 */ |
12 | |
13 #include <errno.h> | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
14 #include <sys/time.h> |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
15 #include <stdlib.h> |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
16 #include <math.h> |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
17 #include <string.h> |
6749 | 18 #include <sys/poll.h> |
5855
c21948cd027d
fix for latest alsa (sys/asoundlib.h has been moved to alsa/asoundlib.h)
pl
parents:
5790
diff
changeset
|
19 |
5857 | 20 #include "../config.h" |
21 | |
5855
c21948cd027d
fix for latest alsa (sys/asoundlib.h has been moved to alsa/asoundlib.h)
pl
parents:
5790
diff
changeset
|
22 #if HAVE_SYS_ASOUNDLIB_H |
1050 | 23 #include <sys/asoundlib.h> |
5855
c21948cd027d
fix for latest alsa (sys/asoundlib.h has been moved to alsa/asoundlib.h)
pl
parents:
5790
diff
changeset
|
24 #elif HAVE_ALSA_ASOUNDLIB_H |
c21948cd027d
fix for latest alsa (sys/asoundlib.h has been moved to alsa/asoundlib.h)
pl
parents:
5790
diff
changeset
|
25 #include <alsa/asoundlib.h> |
c21948cd027d
fix for latest alsa (sys/asoundlib.h has been moved to alsa/asoundlib.h)
pl
parents:
5790
diff
changeset
|
26 #else |
c21948cd027d
fix for latest alsa (sys/asoundlib.h has been moved to alsa/asoundlib.h)
pl
parents:
5790
diff
changeset
|
27 #error "asoundlib.h is not in sys/ or alsa/ - please bugreport" |
c21948cd027d
fix for latest alsa (sys/asoundlib.h has been moved to alsa/asoundlib.h)
pl
parents:
5790
diff
changeset
|
28 #endif |
1050 | 29 |
30 #include "audio_out.h" | |
31 #include "audio_out_internal.h" | |
1058 | 32 #include "afmt.h" |
1050 | 33 |
34 extern int verbose; | |
35 | |
36 static ao_info_t info = | |
37 { | |
38 "ALSA-0.9.x audio output", | |
39 "alsa9", | |
2209 | 40 "Alex Beregszaszi <alex@naxine.org>, Joy Winter <joy@pingfm.org>", |
1050 | 41 "under developement" |
42 }; | |
43 | |
44 LIBAO_EXTERN(alsa9) | |
45 | |
46 | |
47 static snd_pcm_t *alsa_handler; | |
48 static snd_pcm_format_t alsa_format; | |
49 static snd_pcm_hw_params_t *alsa_hwparams; | |
50 static snd_pcm_sw_params_t *alsa_swparams; | |
8036 | 51 static char *alsa_device; |
1050 | 52 |
6749 | 53 /* possible 4096, original 8192 |
54 * was only needed for calculating chunksize? */ | |
55 static int alsa_fragsize = 4096; | |
56 /* 16 sets buffersize to 16 * chunksize is as default 1024 | |
57 * which seems to be good avarge for most situations | |
58 * so buffersize is 16384 frames by default */ | |
59 static int alsa_fragcount = 16; | |
60 static int chunk_size = 1024; //is alsa_fragsize / 4 | |
2209 | 61 |
8874 | 62 #define MIN_CHUNK_SIZE 1024 |
63 | |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
64 static size_t bits_per_sample, bytes_per_sample, bits_per_frame; |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
65 static size_t chunk_bytes; |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
66 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
67 int ao_mmap = 0; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
68 int ao_noblock = 0; |
6749 | 69 int first = 1; |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
70 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
71 static int open_mode; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
72 static int set_block_mode; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
73 |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
74 #define ALSA_DEVICE_SIZE 48 |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
75 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
76 #undef BUFFERTIME |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
77 #define SET_CHUNKSIZE |
6749 | 78 #undef USE_POLL |
1128 | 79 |
6193
2fd9ec444098
AC3 passthrough support by Andy Lo A Foe <andy at alsaplayer dot org>
alex
parents:
5857
diff
changeset
|
80 |
1050 | 81 /* to set/get/query special features/parameters */ |
82 static int control(int cmd, int arg) | |
83 { | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
84 switch(cmd) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
85 case AOCONTROL_QUERY_FORMAT: |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
86 return CONTROL_TRUE; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
87 case AOCONTROL_GET_VOLUME: |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
88 case AOCONTROL_SET_VOLUME: |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
89 #ifndef WORDS_BIGENDIAN |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
90 { //seems to be a problem on macs? |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
91 { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
92 ao_control_vol_t *vol = (ao_control_vol_t *)arg; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
93 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
94 int err; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
95 snd_mixer_t *handle; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
96 snd_mixer_elem_t *elem; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
97 snd_mixer_selem_id_t *sid; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
98 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
99 const char *mix_name = "PCM"; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
100 char *card = "default"; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
101 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
102 long pmin, pmax; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
103 long get_vol, set_vol; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
104 float calc_vol, diff, f_multi; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
105 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
106 if(ao_data.format == AFMT_AC3) |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
107 return CONTROL_TRUE; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
108 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
109 //allocate simple id |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
110 snd_mixer_selem_id_alloca(&sid); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
111 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
112 //sets simple-mixer index and name |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
113 snd_mixer_selem_id_set_index(sid, 0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
114 snd_mixer_selem_id_set_name(sid, mix_name); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
115 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
116 if ((err = snd_mixer_open(&handle, 0)) < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
117 printf("alsa-control: mixer open error: %s\n", snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
118 return CONTROL_ERROR; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
119 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
120 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
121 if ((err = snd_mixer_attach(handle, card)) < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
122 printf("alsa-control: mixer attach %s error: %s", card, snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
123 snd_mixer_close(handle); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
124 return CONTROL_ERROR; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
125 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
126 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
127 if ((err = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
128 printf("alsa-control: mixer register error: %s", snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
129 snd_mixer_close(handle); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
130 return CONTROL_ERROR; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
131 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
132 err = snd_mixer_load(handle); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
133 if (err < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
134 printf("alsa-control: mixer load error: %s", snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
135 snd_mixer_close(handle); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
136 return CONTROL_ERROR; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
137 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
138 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
139 elem = snd_mixer_find_selem(handle, sid); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
140 if (!elem) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
141 printf("alsa-control: unable to find simple control '%s',%i\n", snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
142 snd_mixer_close(handle); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
143 return CONTROL_ERROR; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
144 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
145 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
146 snd_mixer_selem_get_playback_volume_range(elem,&pmin,&pmax); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
147 f_multi = (100 / (float)pmax); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
148 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
149 if (cmd == AOCONTROL_SET_VOLUME) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
150 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
151 diff = (vol->left+vol->right) / 2; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
152 set_vol = rint(diff / f_multi); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
153 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
154 if (set_vol < 0) |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
155 set_vol = 0; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
156 else if (set_vol > pmax) |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
157 set_vol = pmax; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
158 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
159 //setting channels |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
160 if ((err = snd_mixer_selem_set_playback_volume(elem, 0, set_vol)) < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
161 printf("alsa-control: error setting left channel, %s",snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
162 return CONTROL_ERROR; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
163 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
164 if ((err = snd_mixer_selem_set_playback_volume(elem, 1, set_vol)) < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
165 printf("alsa-control: error setting right channel, %s",snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
166 return CONTROL_ERROR; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
167 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
168 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
169 //printf("diff=%f, set_vol=%i, pmax=%i, mult=%f\n", diff, set_vol, pmax, f_multi); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
170 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
171 else { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
172 snd_mixer_selem_get_playback_volume(elem, 0, &get_vol); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
173 calc_vol = get_vol; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
174 calc_vol = rintf(calc_vol * f_multi); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
175 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
176 vol->left = vol->right = (int)calc_vol; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
177 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
178 //printf("get_vol = %i, calc=%i\n",get_vol, calc_vol); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
179 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
180 snd_mixer_close(handle); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
181 return CONTROL_OK; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
182 } |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
183 }// end big-endian |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
184 #endif |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
185 #ifdef WORDS_BIGENDIAN |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
186 { |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
187 { |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
188 return (CONTROL_UNKNOWN); |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
189 } |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
190 } |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
191 #endif |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
192 |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
193 } //end witch |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
194 return(CONTROL_UNKNOWN); |
1050 | 195 } |
196 | |
1128 | 197 |
1050 | 198 /* |
199 open & setup audio device | |
200 return: 1=success 0=fail | |
201 */ | |
202 static int init(int rate_hz, int channels, int format, int flags) | |
203 { | |
204 int err; | |
205 int cards = -1; | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
206 int period_val; |
1050 | 207 snd_pcm_info_t *alsa_info; |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
208 char *str_block_mode; |
6702 | 209 int device_set = 0; |
1180 | 210 |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
211 printf("alsa-init: testing and bugreports are welcome.\n"); |
1050 | 212 printf("alsa-init: requested format: %d Hz, %d channels, %s\n", rate_hz, |
213 channels, audio_out_format_name(format)); | |
214 | |
215 alsa_handler = NULL; | |
216 | |
8027 | 217 if (verbose>0) |
2059 | 218 printf("alsa-init: compiled for ALSA-%s\n", SND_LIB_VERSION_STR); |
1050 | 219 |
220 if ((err = snd_card_next(&cards)) < 0 || cards < 0) | |
221 { | |
222 printf("alsa-init: no soundcards found: %s\n", snd_strerror(err)); | |
223 return(0); | |
224 } | |
225 | |
3095 | 226 ao_data.samplerate = rate_hz; |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
227 ao_data.bps = channels * rate_hz; |
3095 | 228 ao_data.format = format; |
229 ao_data.channels = channels; | |
230 ao_data.outburst = OUTBURST; | |
6749 | 231 //ao_data.buffersize = MAX_OUTBURST; // was 16384 |
1050 | 232 |
233 switch (format) | |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
234 { |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
235 case AFMT_S8: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
236 alsa_format = SND_PCM_FORMAT_S8; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
237 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
238 case AFMT_U8: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
239 alsa_format = SND_PCM_FORMAT_U8; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
240 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
241 case AFMT_U16_LE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
242 alsa_format = SND_PCM_FORMAT_U16_LE; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
243 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
244 case AFMT_U16_BE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
245 alsa_format = SND_PCM_FORMAT_U16_BE; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
246 break; |
5790 | 247 #ifndef WORDS_BIGENDIAN |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
248 case AFMT_AC3: |
5790 | 249 #endif |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
250 case AFMT_S16_LE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
251 alsa_format = SND_PCM_FORMAT_S16_LE; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
252 break; |
5790 | 253 #ifdef WORDS_BIGENDIAN |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
254 case AFMT_AC3: |
5790 | 255 #endif |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
256 case AFMT_S16_BE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
257 alsa_format = SND_PCM_FORMAT_S16_BE; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
258 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
259 case AFMT_S32_LE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
260 alsa_format = SND_PCM_FORMAT_S32_LE; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
261 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
262 case AFMT_S32_BE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
263 alsa_format = SND_PCM_FORMAT_S32_BE; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
264 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
265 |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
266 default: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
267 alsa_format = SND_PCM_FORMAT_MPEG; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
268 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
269 } |
1050 | 270 |
271 switch(alsa_format) | |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
272 { |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
273 case SND_PCM_FORMAT_S16_LE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
274 case SND_PCM_FORMAT_U16_LE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
275 ao_data.bps *= 2; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
276 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
277 case SND_PCM_FORMAT_S32_LE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
278 case SND_PCM_FORMAT_S32_BE: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
279 ao_data.bps *= 4; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
280 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
281 case -1: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
282 printf("alsa-init: invalid format (%s) requested - output disabled\n", |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
283 audio_out_format_name(format)); |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
284 return(0); |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
285 default: |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
286 break; |
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
287 } |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
288 bytes_per_sample = ao_data.bps / ao_data.samplerate; |
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
289 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
290 if (ao_subdevice) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
291 //start parsing ao_subdevice, ugly and not thread safe! |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
292 //maybe there's a better way? |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
293 int i2 = 1; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
294 int i3 = 0; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
295 char *sub_str; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
296 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
297 char *token_str[3]; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
298 char* test_str = strdup(ao_subdevice); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
299 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
300 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
301 if ((strcspn(ao_subdevice, ":")) > 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
302 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
303 sub_str = strtok(test_str, ":"); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
304 *(token_str) = sub_str; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
305 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
306 while (((sub_str = strtok(NULL, ":")) != NULL) && (i2 <= 3)) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
307 *(token_str+i2) = sub_str; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
308 i2 += 1; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
309 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
310 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
311 for (i3=0; i3 <= i2-1; i3++) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
312 if (strcmp(*(token_str + i3), "mmap") == 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
313 ao_mmap = 1; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
314 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
315 else if (strcmp(*(token_str+i3), "noblock") == 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
316 ao_noblock = 1; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
317 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
318 else if (strcmp(*(token_str+i3), "hw") == 0) { |
6702 | 319 if ((i3 < i2-1) && (strcmp(*(token_str+i3+1), "noblock") != 0) && (strcmp(*(token_str+i3+1), "mmap") != 0)) { |
320 alsa_device = alloca(ALSA_DEVICE_SIZE); | |
321 snprintf(alsa_device, ALSA_DEVICE_SIZE, "hw:%s", *(token_str+(i3+1))); | |
322 device_set = 1; | |
323 } | |
324 else { | |
325 alsa_device = *(token_str+i3); | |
326 device_set = 1; | |
327 } | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
328 } |
6702 | 329 else if (device_set == 0 && (!ao_mmap || !ao_noblock)) { |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
330 alsa_device = *(token_str+i3); |
6702 | 331 device_set = 1; |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
332 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
333 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
334 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
335 } //end parsing ao_subdevice |
1207 | 336 |
7077 | 337 /* switch for spdif |
338 * sets opening sequence for SPDIF | |
339 * sets also the playback and other switches 'on the fly' | |
340 * while opening the abstract alias for the spdif subdevice | |
341 * 'iec958' | |
342 */ | |
343 if (format == AFMT_AC3) { | |
344 char devstr[128]; | |
345 unsigned char s[4]; | |
346 int err, c; | |
347 | |
348 switch (channels) { | |
349 case 1: | |
350 case 2: | |
351 | |
352 s[0] = IEC958_AES0_NONAUDIO | | |
353 IEC958_AES0_CON_EMPHASIS_NONE; | |
354 s[1] = IEC958_AES1_CON_ORIGINAL | | |
355 IEC958_AES1_CON_PCM_CODER; | |
356 s[2] = 0; | |
357 s[3] = IEC958_AES3_CON_FS_48000; | |
358 | |
359 sprintf(devstr, "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x", | |
360 s[0], s[1], s[2], s[3]); | |
361 | |
8027 | 362 if (verbose>0) |
7077 | 363 printf("alsa-spdif-init: playing AC3, %i channels\n", channels); |
364 break; | |
365 case 4: | |
366 strcpy(devstr, "surround40"); | |
367 break; | |
368 | |
369 case 6: | |
370 strcpy(devstr, "surround51"); | |
371 break; | |
372 | |
373 default: | |
374 fprintf(stderr, "%d channels are not supported\n", channels); | |
375 exit (0); | |
376 } | |
377 | |
378 alsa_device = devstr; | |
379 } | |
380 | |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
381 if (alsa_device == NULL) |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
382 { |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
383 int tmp_device, tmp_subdevice, err; |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
384 |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
385 if ((err = snd_pcm_info_malloc(&alsa_info)) < 0) |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
386 { |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
387 printf("alsa-init: memory allocation error: %s\n", snd_strerror(err)); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
388 return(0); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
389 } |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
390 |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
391 if ((alsa_device = alloca(ALSA_DEVICE_SIZE)) == NULL) |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
392 { |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
393 printf("alsa-init: memory allocation error: %s\n", strerror(errno)); |
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
394 return(0); |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
395 } |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
396 |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
397 if ((tmp_device = snd_pcm_info_get_device(alsa_info)) < 0) |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
398 { |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
399 printf("alsa-init: cant get device\n"); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
400 return(0); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
401 } |
1050 | 402 |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
403 if ((tmp_subdevice = snd_pcm_info_get_subdevice(alsa_info)) < 0) |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
404 { |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
405 printf("alsa-init: cant get subdevice\n"); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
406 return(0); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
407 } |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
408 |
8027 | 409 if (verbose>0) |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
410 printf("alsa-init: got device=%i, subdevice=%i\n", tmp_device, tmp_subdevice); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
411 |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
412 if ((err = snprintf(alsa_device, ALSA_DEVICE_SIZE, "hw:%1d,%1d", tmp_device, tmp_subdevice)) <= 0) |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
413 { |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
414 printf("alsa-init: cant wrote device-id\n"); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
415 } |
1050 | 416 |
1146
a84610bb5476
hacked aocontrol_set_device working, and cleaned up a bit
al3x
parents:
1129
diff
changeset
|
417 snd_pcm_info_free(alsa_info); |
6702 | 418 printf("alsa-init: %d soundcard%s found, using: %s\n", cards+1, |
419 (cards >= 0) ? "" : "s", alsa_device); | |
420 } else if (strcmp(alsa_device, "help") == 0) { | |
421 printf("alsa-help: available options are:\n"); | |
422 printf(" mmap: sets mmap-mode\n"); | |
423 printf(" noblock: sets noblock-mode\n"); | |
424 printf(" device-name: sets device name\n"); | |
425 printf(" example -ao alsa9:mmap:noblock:hw:0,3 sets noblock-mode,\n"); | |
426 printf(" mmap-mode and the device-name as first card third device\n"); | |
427 return(0); | |
428 } else { | |
429 printf("alsa-init: soundcard set to %s\n", alsa_device); | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
430 } |
1050 | 431 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
432 //setting modes for block or nonblock-mode |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
433 if (ao_noblock) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
434 open_mode = SND_PCM_NONBLOCK; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
435 set_block_mode = 1; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
436 str_block_mode = "nonblock-mode"; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
437 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
438 else { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
439 open_mode = 0; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
440 set_block_mode = 0; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
441 str_block_mode = "block-mode"; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
442 } |
7050
a5b2b377ab50
changed spdif default from "hw:0,2" to general alias "iec958"
joyping
parents:
6749
diff
changeset
|
443 |
6749 | 444 //sets buff/chunksize if its set manually |
445 if (ao_data.buffersize) { | |
446 switch (ao_data.buffersize) | |
447 { | |
448 case 1: | |
449 alsa_fragcount = 16; | |
450 chunk_size = 512; | |
8027 | 451 if (verbose>0) { |
6749 | 452 printf("alsa-init: buffersize set manually to 8192\n"); |
453 printf("alsa-init: chunksize set manually to 512\n"); | |
454 } | |
455 break; | |
456 case 2: | |
457 alsa_fragcount = 8; | |
458 chunk_size = 1024; | |
8027 | 459 if (verbose>0) { |
6749 | 460 printf("alsa-init: buffersize set manually to 8192\n"); |
461 printf("alsa-init: chunksize set manually to 1024\n"); | |
462 } | |
463 break; | |
464 case 3: | |
465 alsa_fragcount = 32; | |
466 chunk_size = 512; | |
8027 | 467 if (verbose>0) { |
6749 | 468 printf("alsa-init: buffersize set manually to 16384\n"); |
469 printf("alsa-init: chunksize set manually to 512\n"); | |
470 } | |
471 break; | |
472 case 4: | |
473 alsa_fragcount = 16; | |
474 chunk_size = 1024; | |
8027 | 475 if (verbose>0) { |
6749 | 476 printf("alsa-init: buffersize set manually to 16384\n"); |
477 printf("alsa-init: chunksize set manually to 1024\n"); | |
478 } | |
479 break; | |
480 default: | |
481 alsa_fragcount = 16; | |
482 if (ao_mmap) | |
483 chunk_size = 512; | |
484 else | |
485 chunk_size = 1024; | |
486 break; | |
487 } | |
488 } | |
489 | |
6193
2fd9ec444098
AC3 passthrough support by Andy Lo A Foe <andy at alsaplayer dot org>
alex
parents:
5857
diff
changeset
|
490 if (!alsa_handler) { |
6702 | 491 //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
492 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, open_mode)) < 0) |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
493 { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
494 if (ao_noblock) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
495 printf("alsa-init: open in nonblock-mode failed, trying to open in block-mode\n"); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
496 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
497 printf("alsa-init: playback open error: %s\n", snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
498 return(0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
499 } else { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
500 set_block_mode = 0; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
501 str_block_mode = "block-mode"; |
6193
2fd9ec444098
AC3 passthrough support by Andy Lo A Foe <andy at alsaplayer dot org>
alex
parents:
5857
diff
changeset
|
502 } |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
503 } else { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
504 printf("alsa-init: playback open error: %s\n", snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
505 return(0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
506 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
507 } |
1050 | 508 |
6702 | 509 if ((err = snd_pcm_nonblock(alsa_handler, set_block_mode)) < 0) { |
510 printf("alsa-init: error set block-mode %s\n", snd_strerror(err)); | |
511 } | |
8027 | 512 else if (verbose>0) { |
6702 | 513 printf("alsa-init: pcm opend in %s\n", str_block_mode); |
514 } | |
515 | |
516 snd_pcm_hw_params_alloca(&alsa_hwparams); | |
517 snd_pcm_sw_params_alloca(&alsa_swparams); | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
518 |
6702 | 519 // setting hw-parameters |
520 if ((err = snd_pcm_hw_params_any(alsa_handler, alsa_hwparams)) < 0) | |
521 { | |
522 printf("alsa-init: unable to get initial parameters: %s\n", | |
523 snd_strerror(err)); | |
524 return(0); | |
525 } | |
1050 | 526 |
6702 | 527 if (ao_mmap) { |
528 snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof()); | |
529 snd_pcm_access_mask_none(mask); | |
530 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED); | |
531 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); | |
532 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX); | |
533 err = snd_pcm_hw_params_set_access_mask(alsa_handler, alsa_hwparams, mask); | |
534 printf("alsa-init: mmap set\n"); | |
535 } else { | |
536 err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams,SND_PCM_ACCESS_RW_INTERLEAVED); | |
537 } | |
538 if (err < 0) { | |
539 printf("alsa-init: unable to set access type: %s\n", snd_strerror(err)); | |
540 return (0); | |
541 } | |
1050 | 542 |
6702 | 543 if ((err = snd_pcm_hw_params_set_format(alsa_handler, alsa_hwparams, |
544 alsa_format)) < 0) | |
545 { | |
546 printf("alsa-init: unable to set format: %s\n", | |
547 snd_strerror(err)); | |
548 return(0); | |
549 } | |
1050 | 550 |
6702 | 551 if ((err = snd_pcm_hw_params_set_channels(alsa_handler, alsa_hwparams, |
552 ao_data.channels)) < 0) | |
553 { | |
554 printf("alsa-init: unable to set channels: %s\n", | |
555 snd_strerror(err)); | |
556 return(0); | |
557 } | |
1050 | 558 |
6702 | 559 if ((err = snd_pcm_hw_params_set_rate_near(alsa_handler, alsa_hwparams, ao_data.samplerate, 0)) < 0) |
2059 | 560 { |
6702 | 561 printf("alsa-init: unable to set samplerate-2: %s\n", |
562 snd_strerror(err)); | |
563 return(0); | |
2059 | 564 } |
1050 | 565 |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
566 #ifdef BUFFERTIME |
6702 | 567 { |
568 int alsa_buffer_time = 500000; /* original 60 */ | |
1050 | 569 |
2059 | 570 if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time, 0)) < 0) |
6702 | 571 { |
1050 | 572 printf("alsa-init: unable to set buffer time near: %s\n", |
6702 | 573 snd_strerror(err)); |
1050 | 574 return(0); |
6702 | 575 } else |
1050 | 576 alsa_buffer_time = err; |
577 | |
2209 | 578 if ((err = snd_pcm_hw_params_set_period_time_near(alsa_handler, alsa_hwparams, alsa_buffer_time/4, 0)) < 0) |
3095 | 579 /* original: alsa_buffer_time/ao_data.bps */ |
6702 | 580 { |
1050 | 581 printf("alsa-init: unable to set period time: %s\n", |
6702 | 582 snd_strerror(err)); |
1050 | 583 return(0); |
6702 | 584 } |
8027 | 585 if (verbose>0) |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
586 printf("alsa-init: buffer_time: %d, period_time :%d\n",alsa_buffer_time, err); |
6702 | 587 } |
1050 | 588 #endif |
589 | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
590 #ifdef SET_CHUNKSIZE |
6702 | 591 { |
592 //set chunksize | |
593 if ((err = snd_pcm_hw_params_set_period_size(alsa_handler, alsa_hwparams, chunk_size, 0)) < 0) | |
594 { | |
595 printf("alsa-init: unable to set periodsize: %s\n", snd_strerror(err)); | |
596 return(0); | |
597 } | |
8027 | 598 else if (verbose>0) { |
6702 | 599 printf("alsa-init: chunksize set to %i\n", chunk_size); |
600 } | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
601 |
6702 | 602 //set period_count |
603 if ((period_val = snd_pcm_hw_params_get_periods_max(alsa_hwparams, 0)) < alsa_fragcount) { | |
604 alsa_fragcount = period_val; | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
605 } |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
606 |
8027 | 607 if (verbose>0) |
6702 | 608 printf("alsa-init: current val=%i, fragcount=%i\n", period_val, alsa_fragcount); |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
609 |
6702 | 610 if ((err = snd_pcm_hw_params_set_periods(alsa_handler, alsa_hwparams, alsa_fragcount, 0)) < 0) { |
611 printf("alsa-init: unable to set periods: %s\n", snd_strerror(err)); | |
612 } | |
613 } | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
614 #endif |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
615 |
6702 | 616 /* finally install hardware parameters */ |
617 if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0) | |
618 { | |
619 printf("alsa-init: unable to set hw-parameters: %s\n", | |
620 snd_strerror(err)); | |
621 return(0); | |
622 } | |
623 // end setting hw-params | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
624 |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
625 |
6702 | 626 // gets buffersize for control |
627 if ((err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams)) < 0) | |
628 { | |
629 printf("alsa-init: unable to get buffersize: %s\n", snd_strerror(err)); | |
630 return(0); | |
631 } | |
632 else { | |
8350
9e045c59ffb8
OK, I think I found why the alsa9 driver was breaking surround sound.
arpi
parents:
8346
diff
changeset
|
633 ao_data.buffersize = err * bytes_per_sample; |
8027 | 634 if (verbose>0) |
6702 | 635 printf("alsa-init: got buffersize=%i\n", ao_data.buffersize); |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
636 } |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
637 |
6702 | 638 // setting sw-params (only avail-min) if noblocking mode was choosed |
639 if (ao_noblock) | |
640 { | |
1050 | 641 |
6702 | 642 if ((err = snd_pcm_sw_params_current(alsa_handler, alsa_swparams)) < 0) |
643 { | |
644 printf("alsa-init: unable to get parameters: %s\n",snd_strerror(err)); | |
645 return(0); | |
646 } | |
647 | |
648 //set min available frames to consider pcm ready (4) | |
649 //increased for nonblock-mode should be set dynamically later | |
6749 | 650 if ((err = snd_pcm_sw_params_set_avail_min(alsa_handler, alsa_swparams, 4)) < 0) |
6702 | 651 { |
652 printf("alsa-init: unable to set avail_min %s\n",snd_strerror(err)); | |
653 return(0); | |
654 } | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
655 |
6702 | 656 if ((err = snd_pcm_sw_params(alsa_handler, alsa_swparams)) < 0) |
657 { | |
658 printf("alsa-init: unable to install sw-params\n"); | |
659 return(0); | |
660 } | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
661 |
6702 | 662 bits_per_sample = snd_pcm_format_physical_width(alsa_format); |
663 bits_per_frame = bits_per_sample * channels; | |
664 chunk_bytes = chunk_size * bits_per_frame / 8; | |
1050 | 665 |
8027 | 666 if (verbose>0) { |
6702 | 667 printf("alsa-init: bits per sample (bps)=%i, bits per frame (bpf)=%i, chunk_bytes=%i\n",bits_per_sample,bits_per_frame,chunk_bytes);} |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
668 |
6702 | 669 }//end swparams |
1050 | 670 |
6702 | 671 if ((err = snd_pcm_prepare(alsa_handler)) < 0) |
672 { | |
673 printf("alsa-init: pcm prepare error: %s\n", snd_strerror(err)); | |
674 return(0); | |
675 } | |
676 | |
677 printf("alsa9: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n", | |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
678 ao_data.samplerate, ao_data.channels, bytes_per_sample, ao_data.buffersize, |
6702 | 679 snd_pcm_format_description(alsa_format)); |
680 | |
681 } // end switch alsa_handler (spdif) | |
1050 | 682 return(1); |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
683 } // end init |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
684 |
1050 | 685 |
686 /* close audio device */ | |
687 static void uninit() | |
688 { | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
689 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
690 if (alsa_handler) { |
1050 | 691 int err; |
692 | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
693 if (!ao_noblock) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
694 if ((err = snd_pcm_drain(alsa_handler)) < 0) |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
695 { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
696 printf("alsa-uninit: pcm drain error: %s\n", snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
697 return; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
698 } |
1050 | 699 } |
700 | |
701 if ((err = snd_pcm_close(alsa_handler)) < 0) | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
702 { |
1050 | 703 printf("alsa-uninit: pcm close error: %s\n", snd_strerror(err)); |
704 return; | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
705 } |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
706 else { |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
707 alsa_handler = NULL; |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
708 alsa_device = NULL; |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
709 printf("alsa-uninit: pcm closed\n"); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
710 } |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
711 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
712 else { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
713 printf("alsa-uninit: no handler defined!\n"); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
714 } |
1050 | 715 } |
716 | |
717 static void audio_pause() | |
718 { | |
719 int err; | |
720 | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
721 if (!ao_noblock) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
722 //drain causes error in nonblock-mode! |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
723 if ((err = snd_pcm_drain(alsa_handler)) < 0) |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
724 { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
725 printf("alsa-pause: pcm drain error: %s\n", snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
726 return; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
727 } |
1050 | 728 } |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
729 else { |
8027 | 730 if (verbose>0) |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
731 printf("alsa-pause: paused nonblock\n"); |
1050 | 732 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
733 return; |
1050 | 734 } |
735 } | |
736 | |
737 static void audio_resume() | |
738 { | |
739 int err; | |
740 | |
741 if ((err = snd_pcm_prepare(alsa_handler)) < 0) | |
742 { | |
743 printf("alsa-resume: pcm prepare error: %s\n", snd_strerror(err)); | |
744 return; | |
745 } | |
746 } | |
747 | |
748 /* stop playing and empty buffers (for seeking/pause) */ | |
749 static void reset() | |
750 { | |
751 int err; | |
752 | |
9587 | 753 if ((err = snd_pcm_drop(alsa_handler)) < 0) |
754 { | |
755 printf("alsa-reset: pcm drop error: %s\n", snd_strerror(err)); | |
756 return; | |
1050 | 757 } |
9587 | 758 if ((err = snd_pcm_prepare(alsa_handler)) < 0) |
759 { | |
760 printf("alsa-reset: pcm prepare error: %s\n", snd_strerror(err)); | |
761 return; | |
762 } | |
763 return; | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
764 } |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
765 |
6749 | 766 #ifdef USE_POLL |
767 static int wait_for_poll(snd_pcm_t *handle, struct pollfd *ufds, unsigned int count) | |
768 { | |
769 unsigned short revents; | |
770 | |
771 while (1) { | |
772 poll(ufds, count, -1); | |
773 snd_pcm_poll_descriptors_revents(handle, ufds, count, &revents); | |
774 if (revents & POLLERR) | |
775 return -EIO; | |
776 if (revents & POLLOUT) | |
777 return 0; | |
778 } | |
779 } | |
780 #endif | |
781 | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
782 #ifndef timersub |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
783 #define timersub(a, b, result) \ |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
784 do { \ |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
785 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
786 (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
787 if ((result)->tv_usec < 0) { \ |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
788 --(result)->tv_sec; \ |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
789 (result)->tv_usec += 1000000; \ |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
790 } \ |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
791 } while (0) |
1129 | 792 #endif |
1050 | 793 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
794 /* I/O error handler */ |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
795 static int xrun(u_char *str_mode) |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
796 { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
797 int err; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
798 snd_pcm_status_t *status; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
799 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
800 snd_pcm_status_alloca(&status); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
801 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
802 if ((err = snd_pcm_status(alsa_handler, status))<0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
803 printf("status error: %s", snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
804 return(0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
805 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
806 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
807 if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
808 struct timeval now, diff, tstamp; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
809 gettimeofday(&now, 0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
810 snd_pcm_status_get_trigger_tstamp(status, &tstamp); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
811 timersub(&now, &tstamp, &diff); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
812 printf("alsa-%s: xrun of at least %.3f msecs. resetting stream\n", |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
813 str_mode, |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
814 diff.tv_sec * 1000 + diff.tv_usec / 1000.0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
815 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
816 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
817 if ((err = snd_pcm_prepare(alsa_handler))<0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
818 printf("xrun: prepare error: %s", snd_strerror(err)); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
819 return(0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
820 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
821 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
822 return(1); /* ok, data should be accepted again */ |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
823 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
824 |
8036 | 825 static int play_normal(void* data, int len); |
826 static int play_mmap(void* data, int len); | |
827 | |
6749 | 828 static int play(void* data, int len, int flags) |
829 { | |
830 int result; | |
831 if (ao_mmap) | |
832 result = play_mmap(data, len); | |
833 else | |
834 result = play_normal(data, len); | |
835 | |
836 return result; | |
837 } | |
838 | |
1050 | 839 /* |
840 plays 'len' bytes of 'data' | |
841 returns: number of bytes played | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
842 modified last at 29.06.02 by jp |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
843 thanxs for marius <marius@rospot.com> for giving us the light ;) |
1050 | 844 */ |
6193
2fd9ec444098
AC3 passthrough support by Andy Lo A Foe <andy at alsaplayer dot org>
alex
parents:
5857
diff
changeset
|
845 |
6749 | 846 static int play_normal(void* data, int len) |
1050 | 847 { |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
848 |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
849 //bytes_per_sample is always 4 for 2 chn S16_LE |
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
850 int num_frames = len / bytes_per_sample; |
8346
368019e0153a
The enclosed patch should fix problems associated with playing 8-bit wide
arpi
parents:
8036
diff
changeset
|
851 char *output_samples = (char *)data; |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
852 snd_pcm_sframes_t res = 0; |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
853 |
8346
368019e0153a
The enclosed patch should fix problems associated with playing 8-bit wide
arpi
parents:
8036
diff
changeset
|
854 //fprintf(stderr,"alsa-play: frames=%i, len=%i\n",num_frames,len); |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
855 |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
856 if (!alsa_handler) { |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
857 printf("alsa-play: device configuration error"); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
858 return 0; |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
859 } |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
860 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
861 while (num_frames > 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
862 |
6749 | 863 res = snd_pcm_writei(alsa_handler, (void *)output_samples, num_frames); |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
864 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
865 if (res == -EAGAIN) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
866 snd_pcm_wait(alsa_handler, 1000); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
867 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
868 else if (res == -EPIPE) { /* underrun */ |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
869 if (xrun("play") <= 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
870 printf("alsa-play: xrun reset error"); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
871 return(0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
872 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
873 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
874 else if (res == -ESTRPIPE) { /* suspend */ |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
875 printf("alsa-play: pcm in suspend mode. trying to resume\n"); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
876 while ((res = snd_pcm_resume(alsa_handler)) == -EAGAIN) |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
877 sleep(1); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
878 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
879 else if (res < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
880 printf("alsa-play: unknown status, trying to reset soundcard\n"); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
881 if ((res = snd_pcm_prepare(alsa_handler)) < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
882 printf("alsa-play: snd prepare error"); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
883 return(0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
884 break; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
885 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
886 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
887 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
888 if (res > 0) { |
8346
368019e0153a
The enclosed patch should fix problems associated with playing 8-bit wide
arpi
parents:
8036
diff
changeset
|
889 |
368019e0153a
The enclosed patch should fix problems associated with playing 8-bit wide
arpi
parents:
8036
diff
changeset
|
890 /* output_samples += ao_data.channels * res; */ |
368019e0153a
The enclosed patch should fix problems associated with playing 8-bit wide
arpi
parents:
8036
diff
changeset
|
891 output_samples += res * bytes_per_sample; |
368019e0153a
The enclosed patch should fix problems associated with playing 8-bit wide
arpi
parents:
8036
diff
changeset
|
892 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
893 num_frames -= res; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
894 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
895 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
896 } //end while |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
897 |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
898 if (res < 0) { |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
899 printf("alsa-play: write error %s", snd_strerror(res)); |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
900 return 0; |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
901 } |
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
902 return res < 0 ? (int)res : len; |
1050 | 903 } |
904 | |
6749 | 905 /* mmap-mode mainly based on descriptions by Joshua Haberman <joshua@haberman.com> |
906 * 'An overview of the ALSA API' http://people.debian.org/~joshua/x66.html | |
907 * and some help by Paul Davis <pbd@op.net> */ | |
908 | |
909 static int play_mmap(void* data, int len) | |
910 { | |
911 snd_pcm_sframes_t commitres, frames_available; | |
912 snd_pcm_uframes_t frames_transmit, size, offset; | |
913 const snd_pcm_channel_area_t *area; | |
914 void *outbuffer; | |
915 int err, result; | |
916 | |
917 #ifdef USE_POLL //seems not really be needed | |
918 struct pollfd *ufds; | |
919 int count; | |
920 | |
921 count = snd_pcm_poll_descriptors_count (alsa_handler); | |
922 ufds = malloc(sizeof(struct pollfd) * count); | |
923 snd_pcm_poll_descriptors(alsa_handler, ufds, count); | |
924 | |
925 //first wait_for_poll | |
926 if (err = (wait_for_poll(alsa_handler, ufds, count) < 0)) { | |
927 if (snd_pcm_state(alsa_handler) == SND_PCM_STATE_XRUN || | |
928 snd_pcm_state(alsa_handler) == SND_PCM_STATE_SUSPENDED) { | |
929 xrun("play"); | |
930 } | |
931 } | |
932 #endif | |
933 | |
934 outbuffer = alloca(ao_data.buffersize); | |
935 | |
936 //don't trust get_space() ;) | |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
937 frames_available = snd_pcm_avail_update(alsa_handler) * bytes_per_sample; |
6749 | 938 if (frames_available < 0) |
939 xrun("play"); | |
940 | |
941 if (frames_available < 4) { | |
942 if (first) { | |
943 first = 0; | |
944 snd_pcm_start(alsa_handler); | |
945 } | |
946 else { //FIXME should break and return 0? | |
947 snd_pcm_wait(alsa_handler, -1); | |
948 first = 1; | |
949 } | |
950 } | |
951 | |
952 /* len is simply the available bufferspace got by get_space() | |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
953 * but real avail_buffer in frames is ab/bytes_per_sample */ |
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
954 size = len / bytes_per_sample; |
6749 | 955 |
956 //if (verbose) | |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
957 //printf("len: %i size %i, f_avail %i, bps %i ...\n", len, size, frames_available, bytes_per_sample); |
6749 | 958 |
959 frames_transmit = size; | |
960 | |
961 /* prepare areas and set sw-pointers | |
962 * frames_transmit returns the real available buffer-size | |
963 * sometimes != frames_available cause of ringbuffer 'emulation' */ | |
964 snd_pcm_mmap_begin(alsa_handler, &area, &offset, &frames_transmit); | |
965 | |
966 /* this is specific to interleaved streams (or non-interleaved | |
967 * streams with only one channel) */ | |
968 outbuffer = ((char *) area->addr + (area->first + area->step * offset) / 8); //8 | |
969 | |
970 //write data | |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
971 memcpy(outbuffer, data, (frames_transmit * bytes_per_sample)); |
6749 | 972 |
973 commitres = snd_pcm_mmap_commit(alsa_handler, offset, frames_transmit); | |
974 | |
975 if (commitres < 0 || commitres != frames_transmit) { | |
976 if (snd_pcm_state(alsa_handler) == SND_PCM_STATE_XRUN || | |
977 snd_pcm_state(alsa_handler) == SND_PCM_STATE_SUSPENDED) { | |
978 xrun("play"); | |
979 } | |
980 } | |
981 | |
982 //if (verbose) | |
983 //printf("mmap ft: %i, cres: %i\n", frames_transmit, commitres); | |
984 | |
985 /* err = snd_pcm_area_copy(&area, offset, &data, offset, len, alsa_format); */ | |
986 /* if (err < 0) { */ | |
987 /* printf("area-copy-error\n"); */ | |
988 /* return 0; */ | |
989 /* } */ | |
990 | |
991 | |
992 //calculate written frames! | |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
993 result = commitres * bytes_per_sample; |
6749 | 994 |
995 | |
996 /* if (verbose) { */ | |
997 /* if (len == result) */ | |
998 /* printf("result: %i, frames written: %i ...\n", result, frames_transmit); */ | |
999 /* else */ | |
1000 /* printf("result: %i, frames written: %i, result != len ...\n", result, frames_transmit); */ | |
1001 /* } */ | |
1002 | |
1003 //mplayer doesn't like -result | |
1004 if (result < 0) | |
1005 result = 0; | |
1006 | |
1007 #ifdef USE_POLL | |
1008 free(ufds); | |
1009 #endif | |
1010 | |
1011 return result; | |
1012 } | |
1013 | |
1050 | 1014 /* how many byes are free in the buffer */ |
1015 static int get_space() | |
1016 { | |
1017 snd_pcm_status_t *status; | |
1018 int ret; | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1019 char *str_status; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1020 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1021 //snd_pcm_sframes_t avail_frames = 0; |
1050 | 1022 |
1023 if ((ret = snd_pcm_status_malloc(&status)) < 0) | |
1024 { | |
1025 printf("alsa-space: memory allocation error: %s\n", snd_strerror(ret)); | |
1026 return(0); | |
1027 } | |
1028 | |
1029 if ((ret = snd_pcm_status(alsa_handler, status)) < 0) | |
1030 { | |
1031 printf("alsa-space: cannot get pcm status: %s\n", snd_strerror(ret)); | |
1032 return(0); | |
1033 } | |
1034 | |
1035 switch(snd_pcm_status_get_state(status)) | |
1036 { | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1037 case SND_PCM_STATE_OPEN: |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1038 str_status = "open"; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1039 case SND_PCM_STATE_PREPARED: |
6749 | 1040 if (str_status != "open") { |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1041 str_status = "prepared"; |
6749 | 1042 first = 1; |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
1043 ret = snd_pcm_status_get_avail(status) * bytes_per_sample; |
6749 | 1044 if (ret == 0) //ugly workaround for hang in mmap-mode |
1045 ret = 10; | |
1046 break; | |
1047 } | |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1048 case SND_PCM_STATE_RUNNING: |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
1049 ret = snd_pcm_status_get_avail(status) * bytes_per_sample; |
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
1050 //avail_frames = snd_pcm_avail_update(alsa_handler) * bytes_per_sample; |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1051 if (str_status != "open" && str_status != "prepared") |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1052 str_status = "running"; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1053 break; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1054 case SND_PCM_STATE_PAUSED: |
8027 | 1055 if (verbose>0) printf("alsa-space: paused"); |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1056 str_status = "paused"; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1057 ret = 0; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1058 break; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1059 case SND_PCM_STATE_XRUN: |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1060 xrun("space"); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1061 str_status = "xrun"; |
6749 | 1062 first = 1; |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1063 ret = 0; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1064 break; |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1065 default: |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1066 str_status = "undefined"; |
7657
dda97c5190d7
fixed ao_data.bps - patch by Tobias Diedrich <td@sim.uni-hannover.de>
arpi
parents:
7077
diff
changeset
|
1067 ret = snd_pcm_status_get_avail(status) * bytes_per_sample; |
6749 | 1068 if (ret <= 0) { |
1069 xrun("space"); | |
1070 } | |
1050 | 1071 } |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1072 |
8027 | 1073 if (verbose>0 && str_status != "running") |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1074 printf("alsa-space: free space = %i, status=%i, %s --\n", ret, status, str_status); |
1050 | 1075 snd_pcm_status_free(status); |
1129 | 1076 |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1077 if (ret < 0) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1078 printf("negative value!!\n"); |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
1079 ret = 0; |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1080 } |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1081 |
8874 | 1082 // workaround for too small value returned |
1083 if (ret < MIN_CHUNK_SIZE) | |
1084 ret = 0; | |
1085 | |
1050 | 1086 return(ret); |
1087 } | |
1088 | |
3095 | 1089 /* delay in seconds between first and last sample in buffer */ |
1090 static float get_delay() | |
1050 | 1091 { |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1092 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1093 if (alsa_handler) { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1094 |
1050 | 1095 snd_pcm_status_t *status; |
3095 | 1096 float ret; |
1050 | 1097 |
1098 if ((ret = snd_pcm_status_malloc(&status)) < 0) | |
1099 { | |
1100 printf("alsa-delay: memory allocation error: %s\n", snd_strerror(ret)); | |
1101 return(0); | |
1102 } | |
1103 | |
1104 if ((ret = snd_pcm_status(alsa_handler, status)) < 0) | |
1105 { | |
1106 printf("alsa-delay: cannot get pcm status: %s\n", snd_strerror(ret)); | |
1107 return(0); | |
1108 } | |
1109 | |
1110 switch(snd_pcm_status_get_state(status)) | |
1111 { | |
1112 case SND_PCM_STATE_OPEN: | |
1113 case SND_PCM_STATE_PREPARED: | |
1114 case SND_PCM_STATE_RUNNING: | |
3095 | 1115 ret = (float)snd_pcm_status_get_delay(status)/(float)ao_data.samplerate; |
1050 | 1116 break; |
1117 default: | |
1118 ret = 0; | |
1119 } | |
1120 | |
1121 snd_pcm_status_free(status); | |
1129 | 1122 |
1123 if (ret < 0) | |
6589
1595ca898d3b
cleanup and bufferhandling fix by Joy Ping <joy at pingfm.org>. Bufferhandling fix based on idea by Marius David <marius at rohost.com>
alex
parents:
6194
diff
changeset
|
1124 ret = 0; |
1050 | 1125 return(ret); |
6633
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1126 |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1127 } else { |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1128 return(0); |
769246a4eb41
cVS: ---------------------------------------------------------------------
joyping
parents:
6589
diff
changeset
|
1129 } |
1050 | 1130 } |