* snd_pcm_hw_rule_noresample
@ 2011-09-20 8:24 Raymond Yau
2011-09-20 8:48 ` snd_pcm_hw_rule_noresample Clemens Ladisch
0 siblings, 1 reply; 5+ messages in thread
From: Raymond Yau @ 2011-09-20 8:24 UTC (permalink / raw)
To: ALSA Development Mailing List, Takashi Iwai, Clemens Ladisch
[-- Attachment #1: Type: text/plain, Size: 6307 bytes --]
60fdc82f96bff2e3a31e9fcf8a9503f5a37c1f85
ALSA: pcm: add snd_pcm_hw_rule_noresample()
Add a helper function to allow drivers to disable hardware resampling
when the application has specified the SNDRV_PCM_HW_PARAMS_NORESAMPLE
flag.
Refer to commit and the three corresponding patch with ymfpci,
emu10k1, via82xx, it seem to be a regression
according to http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___h_w___params.html
int snd_pcm_hw_params_set_rate_resample ( snd_pcm_t * pcm,
snd_pcm_hw_params_t * params,
unsigned int val
)
Restrict a configuration space to contain only real hardware rates.
ymfpci and emu10k1 have SNDRV_PCM_RATE_CONTINUOUS and support 8000Hz to 48000Hz
after this patch and if application using
snd_pcm_hw_params_set_rate_resample(,pcm , params ,0)
why the supported rate is only 48000Hz ?
but snd_pcm_hw_params_get_rate_min() is still 8000Hz
This patch won't affect the accuracy of the playback position of the ymfpci
attach a test program which print the the playback position and the result
./alsa_test hw:0
Hardware PCM card 0 'Yamaha DS-1 (YMF724F)' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 44100
exact rate : 44100 (44100/1)
msbits : 16
buffer_size : 16383
period_size : 5461
period_time : 123832
tstamp_mode : ENABLE
period_step : 1
avail_min : 5461
period_event : 0
start_threshold : 1
stop_threshold : 16383
silence_threshold: 0
silence_size : 0
boundary : 2147352576
appl_ptr : 0
hw_ptr : 0
pcm write 5461
pcm write 5461
pcm write 5461
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 235
12 235
13 235
14 235
15 235
16 470
17 470
18 470
19 470
20 470
21 705
22 705
23 705
24 705
25 705
26 940
27 940
28 940
29 940
30 940
31 940
32 1175
33 1175
34 1175
35 1175
36 1175
37 1411
38 1411
39 1411
40 1411
41 1411
42 1646
43 1646
44 1646
45 1646
46 1646
47 1646
48 1881
49 1881
50 1881
51 1881
52 1881
53 2116
54 2116
55 2116
56 2116
57 2116
58 2351
59 2351
60 2351
61 2351
62 2351
63 2587
64 2587
65 2587
66 2587
67 2587
68 2587
69 2822
70 2822
71 2822
72 2822
73 2822
74 3057
75 3057
76 3057
77 3057
78 3057
79 3292
80 3292
81 3292
82 3292
83 3292
84 3527
85 3527
86 3527
87 3527
88 3527
89 3527
90 3763
91 3763
92 3763
93 3763
94 3763
95 3998
96 3998
97 3998
98 3998
99 3998
100 4233
101 4233
102 4233
103 4233
104 4233
105 4233
106 4468
107 4468
108 4468
109 4468
110 4468
111 4703
112 4703
113 4703
114 4703
115 4703
116 4939
117 4939
118 4939
119 4939
120 4939
121 5174
122 5174
123 5174
124 5174
125 5174
126 5174
127 5409
128 5409
129 5409
130 5409
131 5409
132 5644
133 5644
134 5644
135 5644
136 5644
137 5879
138 5879
139 5879
140 5879
141 5879
142 6115
143 6115
144 6115
145 6115
146 6115
147 6115
148 6350
149 6350
150 6350
151 6350
152 6350
153 6585
154 6585
155 6585
156 6585
157 6585
158 6820
159 6820
160 6820
161 6820
162 6820
163 6820
164 7055
165 7055
166 7055
167 7055
168 7055
169 7291
170 7291
171 7291
172 7291
173 7291
174 7526
175 7526
176 7526
177 7526
178 7526
179 7761
180 7761
181 7761
182 7761
183 7761
184 7761
185 7996
186 7996
187 7996
188 7996
189 7996
190 8231
191 8231
192 8231
193 8231
194 8231
195 8467
196 8467
197 8467
198 8467
199 8467
200 8702
201 8702
202 8702
203 8702
204 8702
205 8702
206 8937
207 8937
208 8937
209 8937
210 8937
211 9172
212 9172
213 9172
214 9172
215 9172
216 9407
217 9407
218 9407
219 9407
220 9407
221 9407
222 9643
223 9643
224 9643
225 9643
226 9643
227 9878
228 9878
229 9878
230 9878
231 9878
232 10113
233 10113
234 10113
235 10113
236 10113
237 10348
238 10348
239 10348
240 10348
241 10348
242 10348
243 10583
244 10583
245 10583
246 10583
247 10583
248 10819
249 10819
250 10819
251 10819
252 10819
253 11054
254 11054
255 11054
256 11054
257 11054
258 11289
259 11289
260 11289
261 11289
262 11289
263 11289
264 11524
265 11524
266 11524
267 11524
268 11524
269 11759
270 11759
271 11759
272 11759
273 11759
274 11995
275 11995
276 11995
277 11995
278 11995
279 11995
280 12230
281 12230
282 12230
283 12230
284 12230
285 12465
286 12465
287 12465
288 12465
289 12465
290 12700
291 12700
292 12700
293 12700
294 12700
295 12935
296 12935
297 12935
298 12935
299 12935
300 12935
301 13171
302 13171
303 13171
304 13171
305 13171
306 13406
307 13406
308 13406
309 13406
310 13406
311 13641
312 13641
313 13641
314 13641
315 13641
316 13876
317 13876
318 13876
319 13876
320 13876
321 13876
322 14111
323 14111
324 14111
325 14111
326 14111
327 14347
328 14347
329 14347
330 14347
331 14347
332 14582
333 14582
334 14582
335 14582
336 14582
337 14582
338 14817
339 14817
340 14817
341 14817
342 14817
343 15052
344 15052
345 15052
346 15052
347 15052
348 15287
349 15287
350 15287
351 15287
352 15287
353 15523
354 15523
355 15523
356 15523
357 15523
358 15523
359 15758
360 15758
361 15758
362 15758
363 15758
364 15993
365 15993
366 15993
367 15993
368 15993
369 16228
370 16228
371 16228
372 16228
373 16228
374 -32
[-- Attachment #2: alsa_test.c --]
[-- Type: text/x-csrc, Size: 4134 bytes --]
#include <assert.h>
#include <time.h>
#include <alsa/asoundlib.h>
int main(int argc, char *argv[]) {
const char *dev;
int cap, err;
snd_pcm_hw_params_t *hwparams;
snd_pcm_sw_params_t *swparams;
snd_pcm_status_t *status;
snd_pcm_t *pcm;
snd_output_t *output = NULL;
unsigned rate;
unsigned periods = 2;
unsigned int this_time, buffer_time;
int sleep_time = 1000;
int buffer[65536];
int stat[65536];
snd_pcm_uframes_t boundary, buffer_size, period_size, this_period;
int dir = 1;
int i, counter;
snd_pcm_sframes_t avail;
snd_pcm_hw_params_alloca(&hwparams);
snd_pcm_sw_params_alloca(&swparams);
dev = argc > 1 ? argv[1] : "hw:0,0";
cap = argc > 2 ? atoi(argv[2]) : 0;
rate = argc > 3 ? atoi(argv[3]) : 44100;
err = snd_pcm_open(&pcm, dev, cap == 0 ? SND_PCM_STREAM_PLAYBACK :
SND_PCM_STREAM_CAPTURE, 0);
if (err < 0) {
printf("snd_pcm_open fail %s err %s\n",dev, snd_strerror(err));
exit(0);
}
err = snd_pcm_hw_params_any(pcm, hwparams);
// assert(err == 0);
/*
err = snd_pcm_hw_params_set_rate_resample(pcm, hwparams, 0);
assert(err == 0);
*/
err = snd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
assert(err == 0);
err = snd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16_LE);
assert(err == 0);
err = snd_pcm_hw_params_set_rate_near(pcm, hwparams, &rate, NULL);
assert(err == 0);
err = snd_pcm_hw_params_set_channels(pcm, hwparams, 2);
assert(err == 0);
/*
err = snd_pcm_hw_params_set_periods_integer(pcm, hwparams);
assert(err == 0);
*/
dir = 0;
err = snd_pcm_hw_params_set_periods_near(pcm, hwparams, &periods, &dir);
assert(err == 0);
buffer_size = rate * 2;
err = snd_pcm_hw_params_set_buffer_size_near(pcm, hwparams, &buffer_size);
assert(err == 0);
err = snd_pcm_hw_params(pcm, hwparams);
assert(err == 0);
err = snd_pcm_hw_params_current(pcm, hwparams);
assert(err == 0);
err = snd_pcm_sw_params_current(pcm, swparams);
assert(err == 0);
/*
if (cap == 0)
err = snd_pcm_sw_params_set_avail_min(pcm, swparams, 1);
else
err = snd_pcm_sw_params_set_avail_min(pcm, swparams, 0);
assert(err == 0);
*/
/*
err = snd_pcm_sw_params_set_period_event(pcm, swparams, 0);
assert(err == 0);
*/
err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
assert(err == 0);
/*
err = snd_pcm_hw_params_get_buffer_time(hwparams, &buffer_time, 0);
assert(err == 0);
*/
err = snd_pcm_hw_params_get_period_size(hwparams, &period_size, 0);
assert(err == 0);
/*
err = snd_pcm_sw_params_set_start_threshold(pcm, swparams, buffer_size);
assert(err == 0);
err = snd_pcm_sw_params_get_boundary(swparams, &boundary);
assert(err == 0);
err = snd_pcm_sw_params_set_stop_threshold(pcm, swparams, buffer_size);
assert(err == 0);
*/
err = snd_pcm_sw_params_set_tstamp_mode(pcm, swparams, SND_PCM_TSTAMP_ENABLE);
assert(err == 0);
err = snd_pcm_sw_params(pcm, swparams);
assert(err == 0);
err = snd_pcm_sw_params_current(pcm, swparams);
assert(err == 0);
err = snd_output_stdio_attach(&output, stdout, 0);
if (err < 0)
printf("Output failed: %s\n", snd_strerror(err));
snd_pcm_dump(pcm, output);
/* assert(snd_pcm_hw_params_is_monotonic(hwparams) > 0); */
if (cap) {
err = snd_pcm_start(pcm);
assert(err == 0);
}
else {
this_period = 0;
while (this_period<buffer_size) {
err = snd_pcm_writei(pcm, buffer, period_size);
printf("pcm write %d\n",err);
this_period += period_size;
};
};
avail=0;
this_time =0;
counter = 0;
// printf("buffer time %d\n",buffer_time);
while (counter < 32767 && avail >= 0) {
avail = snd_pcm_avail(pcm);
stat[counter] = avail;
usleep(sleep_time);
counter++;
this_time += sleep_time;
};
for (i=0; i<counter; i++)
printf("%6d %d\n",i, stat[i]);
snd_pcm_close(pcm);
return 0;
}
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: snd_pcm_hw_rule_noresample
2011-09-20 8:24 snd_pcm_hw_rule_noresample Raymond Yau
@ 2011-09-20 8:48 ` Clemens Ladisch
2011-09-21 7:09 ` snd_pcm_hw_rule_noresample Clemens Ladisch
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Clemens Ladisch @ 2011-09-20 8:48 UTC (permalink / raw)
To: Raymond Yau; +Cc: Takashi Iwai, ALSA Development Mailing List
Raymond Yau wrote:
> ALSA: pcm: add snd_pcm_hw_rule_noresample()
> ...
>
> ymfpci and emu10k1 have SNDRV_PCM_RATE_CONTINUOUS and support 8000Hz to 48000Hz
>
> after this patch and if application using
> snd_pcm_hw_params_set_rate_resample(,pcm , params ,0)
>
> why the supported rate is only 48000Hz ?
Because these cards run at 48 kHz and resample anything else. That
the resampler is implemented in hardware does not make a conceptual
difference, and just means that the resampler has low quality.
> but snd_pcm_hw_params_get_rate_min() is still 8000Hz
This should not happen. I'd guess the rules engine hasn't noticed
that some parameters affected by the new rule need to change.
Please try the patch below. But there might be drivers where other
parameters are affected by SND_PCM_HW_PARAMS_NORESAMPLE, so I guess
all parameter bits need to be set.
> This patch won't affect the accuracy of the playback position of the ymfpci
Why should it?
Regards,
Clemens
--- alsa-lib/src/pcm/pcm.c
+++ alsa-lib/src/pcm/pcm.c
@@ -4176,6 +4176,7 @@ int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *par
params->flags |= SND_PCM_HW_PARAMS_NORESAMPLE;
else
params->flags &= ~SND_PCM_HW_PARAMS_NORESAMPLE;
+ params->rmask |= 1 << SNDRV_PCM_HW_PARAM_RATE;
return snd_pcm_hw_refine(pcm, params);
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: snd_pcm_hw_rule_noresample
2011-09-20 8:48 ` snd_pcm_hw_rule_noresample Clemens Ladisch
@ 2011-09-21 7:09 ` Clemens Ladisch
2011-09-23 1:19 ` snd_pcm_hw_rule_noresample Raymond Yau
2011-09-23 6:33 ` snd_pcm_hw_rule_noresample Raymond Yau
2 siblings, 0 replies; 5+ messages in thread
From: Clemens Ladisch @ 2011-09-21 7:09 UTC (permalink / raw)
To: Raymond Yau; +Cc: Takashi Iwai, ALSA Development Mailing List
Clemens Ladisch wrote:
> Raymond Yau wrote:
> > but snd_pcm_hw_params_get_rate_min() is still 8000Hz
>
> This should not happen. I'd guess the rules engine hasn't noticed
> that some parameters affected by the new rule need to change.
>
> Please try the patch below. But there might be drivers where other
> parameters are affected by SND_PCM_HW_PARAMS_NORESAMPLE, so I guess
> all parameter bits need to be set.
updated and applied:
http://git.alsa-project.org/?p=alsa-lib.git;a=commitdiff;h=6dab1a91cbbd
> > This patch won't affect the accuracy of the playback position of the ymfpci
When resampling is used, the interval between period interrupts is not
strictly constant, but with the noresample flag set, I guess it might
make sense to restrict the period size to a multiple of the hardware
period size. This would at least remove the jitter from the ALSA period
interrupt timing.
The ymfpci hardware has a global sample counter, but AFAICS it is not
possible to reliably get its value at the time of a period boundary.
Regards,
Clemens
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: snd_pcm_hw_rule_noresample
2011-09-20 8:48 ` snd_pcm_hw_rule_noresample Clemens Ladisch
2011-09-21 7:09 ` snd_pcm_hw_rule_noresample Clemens Ladisch
@ 2011-09-23 1:19 ` Raymond Yau
2011-09-23 6:33 ` snd_pcm_hw_rule_noresample Raymond Yau
2 siblings, 0 replies; 5+ messages in thread
From: Raymond Yau @ 2011-09-23 1:19 UTC (permalink / raw)
To: Clemens Ladisch, ALSA Development Mailing List, Takashi Iwai
2011/9/20 Clemens Ladisch <clemens@ladisch.de>:
> Raymond Yau wrote:
>> ALSA: pcm: add snd_pcm_hw_rule_noresample()
>> ...
>>
>> ymfpci and emu10k1 have SNDRV_PCM_RATE_CONTINUOUS and support 8000Hz to 48000Hz
>>
>> after this patch and if application using
>> snd_pcm_hw_params_set_rate_resample(,pcm , params ,0)
>>
>> why the supported rate is only 48000Hz ?
>
> Because these cards run at 48 kHz and resample anything else. That
> the resampler is implemented in hardware does not make a conceptual
> difference, and just means that the resampler has low quality.
>
>> but snd_pcm_hw_params_get_rate_min() is still 8000Hz
>
> This should not happen. I'd guess the rules engine hasn't noticed
> that some parameters affected by the new rule need to change.
>
> Please try the patch below. But there might be drivers where other
> parameters are affected by SND_PCM_HW_PARAMS_NORESAMPLE, so I guess
> all parameter bits need to be set.
>
>> This patch won't affect the accuracy of the playback position of the ymfpci
>
> Why should it?
>
I think the correct way for ymfpci is to add a period_bytes constraint
(just like emu10k1 and au88x0) in addition of a switch to fixed rate
at 48000Hz to force the application to choose a period time which is
close to the interval of timer interrupt
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 1024);
are there any problem in snd_pcm_drain(), snd_pcm_rewind() and
snd_pcm_forward() when the driver let the application select any
period time when those hardware mixing sound card 's DSP have to mix
audio streams?
since hwptr is inaccurate, snd_pcm_rewindable() may need to return
zero if it can only rewind to period boundary
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: snd_pcm_hw_rule_noresample
2011-09-20 8:48 ` snd_pcm_hw_rule_noresample Clemens Ladisch
2011-09-21 7:09 ` snd_pcm_hw_rule_noresample Clemens Ladisch
2011-09-23 1:19 ` snd_pcm_hw_rule_noresample Raymond Yau
@ 2011-09-23 6:33 ` Raymond Yau
2 siblings, 0 replies; 5+ messages in thread
From: Raymond Yau @ 2011-09-23 6:33 UTC (permalink / raw)
To: Clemens Ladisch, ALSA Development Mailing List
2011/9/20 Clemens Ladisch <clemens@ladisch.de>:
> Raymond Yau wrote:
>> ALSA: pcm: add snd_pcm_hw_rule_noresample()
>>
...
>>
>> ymfpci and emu10k1 have SNDRV_PCM_RATE_CONTINUOUS and support 8000Hz to 48000Hz
>>
>> after this patch and if application using
>> snd_pcm_hw_params_set_rate_resample(,pcm , params ,0)
>>
>> why the supported rate is only 48000Hz ?
>
> Because these cards run at 48 kHz and resample anything else. That
> the resampler is implemented in hardware does not make a conceptual
> difference, and just means that the resampler has low quality.
There is a demo case about the problem of emu10k1 at 44100Hz
your patch also disable the software converter
https://bugs.launchpad.net/ubuntu/+source/alsa-plugins/+bug/57089/comments/2
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-09-23 6:33 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-20 8:24 snd_pcm_hw_rule_noresample Raymond Yau
2011-09-20 8:48 ` snd_pcm_hw_rule_noresample Clemens Ladisch
2011-09-21 7:09 ` snd_pcm_hw_rule_noresample Clemens Ladisch
2011-09-23 1:19 ` snd_pcm_hw_rule_noresample Raymond Yau
2011-09-23 6:33 ` snd_pcm_hw_rule_noresample Raymond Yau
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.