2009/9/8 Takashi Iwai <tiwai@xxxxxxx> > At Tue, 8 Sep 2009 15:38:25 +0200, > Lennart Poettering wrote: > > > > On Tue, 08.09.09 08:29, Takashi Iwai (tiwai@xxxxxxx) wrote: > > > > > > This turned out to cause a couple of issues with some drivers (i > think > > > > CS46xx is one of them, ice1712 another, I lack the hw in question, so > it's rather common e.g HDA also have snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 128); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128); > > > > i never tried to track this down further). Basically on those drivers > > > > both _set_buffer_size_near() and _set_periods_near() would fail with > > > > EINVAL for some reason and then causing snd_pcm_hw_params() to return > > > > ENOENT. Removing the two calls and calling snd_pcm_hw_params() would > > > > however work. Changing the order of the first two calls, i.e. doing > > > > first _set_periods_near() and then _set_buffer_size_near() would make > > > > both calls succeed and the snd_pcm_hw_params(), too. > > > > > > The general problem in the hw_params setup is that the multiple > > > parameters depending with each other are allowed almost freely. > > > And, yet another problematic constraint is like cs46xx's one, the > > > power-of-two rule. This limits strongly the value range. > > > > > > Also, another issue is the presence of three units to specify the same > > > thing. There are units, frame, bytes and time for period and buffer > > > sizes. Especially the former two and the time units can be > > > inconsistent due to the integer rounding. > > > > I always use 'frames' as unit for the actual calls, even if I said > > bytes. > > It's not about what unit you use. It's the fact that three units > exist in the hw_params space parallel and they have to be aligned with > each other. See ens1371 example below. > > > > > > It would be good if the ALSA docs would actually mention in which > > > > order those functions need to be called, if the order matters, which > > > > it apparently does. > > > > > > There is no golden rule, unfortunately, AFAIK. There can be pretty > > > weird hardware, e.g. the buffer size depending on rate. But, as a > > > rule of thumb: > > > 1. set access, format, channels and rate first, > > > 2. if you need larger buffers than shorter periods, set the buffer > > > size first, > > > 3. set the period size only when you must specify it > > > > This breaks on ice1712 at least... > > Might be. > The front device of ice1712 has a route plugin you may need to use hw:0,0 if you are using mmap_begin, .... and read/write 10 and 12 channels like jackd Actually the front device of emu10k1 has two IFACE_PCM controls , most likely you will need to modify EMU10K1.conf so that capture do not hook those controls > > > > But, this can also fail when a hardware has a strong dependency > > > between period and buffer sizes together with a strong constraint > > > in period size. In that case, you may need to try another way, > > > set period and hw_params. > > > > For me the large buffers matter most. And large periods are the second > > most important thing. Would something like the following make sense? > > > > <snip> > > snd_pcm_hw_params_any(pcm, hw); > > snd_pcm_hw_params_set_access(pcm, hw, ...); > > snd_pcm_hw_params_set_format(pcm, hw, ...); > > snd_pcm_hw_params_set_rate_near(pcm, hw, ...); > > snd_pcm_hw_params_set_channels_near(pcm, hw, ...); > > > > snd_pcm_hw_params_copy(hw2, hw); > > > > /* We care more about buffer size than the period size, so try setting > > things in this order first */ > > snd_pcm_hw_params_set_buffer_size_near(hw, ...); > > snd_pcm_hw_params_set_periods_near(hw, ...); > > > > if (snd_pcm_hw_params(pcm, hw) < 0) { > > /* This order didn't work, so let's try it the other way round */ > > snd_pcm_hw_params_set_periods_near(hw2, ...); > > snd_pcm_hw_params_set_buffer_size_near(hw2, ...); > > > > if (snd_pcm_hw_params(pcm, hw2) < 0) { > > /* fail fatally */ > > .... > > } > > } > > </snip> > > I think yes. But needs more testing of course :) > > > > > > ens1371 has some issues with the buffer size: if you ask it for 65536 > > > > bytes in the playback buffer it will only agree to 65532. If the next > > > > time you ask for 65532 right-away it will only agree to 65528, and so > on...) > > > > > > The byte size can depend on the sample format and channels. > > > This might be the case. Otherwise I don't see any strong restriction > > > of buffer/period size in ens1371 code. It has the restriction of > > > sample rates, though. > > > > I only actually manipulate samples here, not bytes. So the prob is > > that if you ask for a buffer size of n samples it will only agree to > > n-1 samples, for every possible n. Other drivers don't do that. > > Then the problem is likely the sample rate setup. ens1371 can't give > you always the integer sample rate. Now the problem of multiple units > appears here like a ghost. Almost every parameter is associated with > other parameters in the end due to the constraints below: > buffer_time = buffer_size / sample_rate > buffer_size = buffer_bytes / (channels * format_width) > > When you get a non-integer rate value, even buffer_size can be > affected, rounded down to the next integer value. > > All for one, one for all -- what a perfect world. > > > thanks, > > Takashi > _______________________________________________ > Alsa-devel mailing list > Alsa-devel@xxxxxxxxxxxxxxxx > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel