[alsa-devel] Requiring the same sample rate for playback and record?
In my driver, how do I tell ALSA that the sample rate for playback must be the same as for capture?
I know I can have my driver remember the sample rate for the first stream open, and then if the second stream doesn't specify the same sample rate, it can reject it, but this is inelegant. I'm hoping there's a more straightforward way.
At Fri, 20 Jun 2008 14:08:50 -0500, Timur Tabi wrote:
In my driver, how do I tell ALSA that the sample rate for playback must be the same as for capture?
I know I can have my driver remember the sample rate for the first stream open, and then if the second stream doesn't specify the same sample rate, it can reject it, but this is inelegant. I'm hoping there's a more straightforward way.
Right now there is no "elegant" way for this, unfortunately. A common way many drivers use is to remember the rate of the first stream, then add it to hw_constraint of the secondary streams. But, this could be also a bit racy (unavoidable due to its design) although practically it seems working.
Takashi
Takashi Iwai wrote:
Right now there is no "elegant" way for this, unfortunately. A common way many drivers use is to remember the rate of the first stream, then add it to hw_constraint of the secondary streams. But, this could be also a bit racy (unavoidable due to its design) although practically it seems working.
Ok, thanks. I assume the same solution applies if I have a sample *format* restriction?
At Mon, 23 Jun 2008 07:08:22 -0500, Timur Tabi wrote:
Takashi Iwai wrote:
Right now there is no "elegant" way for this, unfortunately. A common way many drivers use is to remember the rate of the first stream, then add it to hw_constraint of the secondary streams. But, this could be also a bit racy (unavoidable due to its design) although practically it seems working.
Ok, thanks. I assume the same solution applies if I have a sample *format* restriction?
Yes.
Takashi
Takashi Iwai wrote:
Right now there is no "elegant" way for this, unfortunately. A common way many drivers use is to remember the rate of the first stream, then add it to hw_constraint of the secondary streams.
Can you give me an example of a driver that does this? I can't seem to find one.
But, this could be also a bit racy (unavoidable due to its design) although practically it seems working.
I've been trying to implement this, but I'm not sure how. I have a couple questions:
1) Which snd_pcm_hw_constraint_xxx function should I use to specify a sample rate or sample size constraint of a single number? I'm thinking snd_pcm_hw_constraint_list().
2) Where should I be calling this function? In my _hw_params() function? What I would like to do is require the constraint to be enforced only when a stream is already playing. That is, if playback is paused, then the capture stream can set any sample rate it wants. Is this doable, or just too complicated?
At Mon, 14 Jul 2008 16:25:04 -0500, Timur Tabi wrote:
Takashi Iwai wrote:
Right now there is no "elegant" way for this, unfortunately. A common way many drivers use is to remember the rate of the first stream, then add it to hw_constraint of the secondary streams.
Can you give me an example of a driver that does this? I can't seem to find one.
In a simple case, you don't need hw_constraint functions. Just override the corresponding fields of runtime->hw in open callback.
For example, pci/via82xx.c sets the current rate value to runtime->hw.rate_min/max if there is another stream. More complicated examples are found in echoaudio driver.
But, this could be also a bit racy (unavoidable due to its design) although practically it seems working.
I've been trying to implement this, but I'm not sure how. I have a couple questions:
- Which snd_pcm_hw_constraint_xxx function should I use to specify a sample
rate or sample size constraint of a single number? I'm thinking snd_pcm_hw_constraint_list().
The simplest way is to override the runtime->hw parameter as mentinoed in the above.
- Where should I be calling this function? In my _hw_params()
function?
Usually these hw_constraints are set in open callback.
What I would like to do is require the constraint to be enforced only when a stream is already playing. That is, if playback is paused, then the capture stream can set any sample rate it wants. Is this doable, or just too complicated?
This is a scenario above a simple hw_constraint. This would be also confusing to apps in many cases.
Takashi
Takashi Iwai wrote:
In a simple case, you don't need hw_constraint functions. Just override the corresponding fields of runtime->hw in open callback.
For example, pci/via82xx.c sets the current rate value to runtime->hw.rate_min/max if there is another stream.
Are you talking about this code:
} else { /* a fixed rate */ runtime->hw.rates = SNDRV_PCM_RATE_KNOT; runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate; }
Last I heard, ASoC doesn't work with SNDRV_PCM_RATE_KNOT. But I think I can still use this method. I'll just need to use a real SNDRV_PCM_RATE_xxx value.
On Wed, 2008-07-16 at 10:11 -0500, Timur Tabi wrote:
Takashi Iwai wrote:
In a simple case, you don't need hw_constraint functions. Just override the corresponding fields of runtime->hw in open callback.
For example, pci/via82xx.c sets the current rate value to runtime->hw.rate_min/max if there is another stream.
Are you talking about this code:
} else { /* a fixed rate */ runtime->hw.rates = SNDRV_PCM_RATE_KNOT; runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate; }
Last I heard, ASoC doesn't work with SNDRV_PCM_RATE_KNOT. But I think I can still use this method. I'll just need to use a real SNDRV_PCM_RATE_xxx value.
Supporting KNOT in the core is probably the best solution. It shouldn't be too hard at add ....
Liam
At Wed, 16 Jul 2008 10:11:27 -0500, Timur Tabi wrote:
Takashi Iwai wrote:
In a simple case, you don't need hw_constraint functions. Just override the corresponding fields of runtime->hw in open callback.
For example, pci/via82xx.c sets the current rate value to runtime->hw.rate_min/max if there is another stream.
Are you talking about this code:
} else { /* a fixed rate */ runtime->hw.rates = SNDRV_PCM_RATE_KNOT; runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate; }
Last I heard, ASoC doesn't work with SNDRV_PCM_RATE_KNOT. But I think I can still use this method. I'll just need to use a real SNDRV_PCM_RATE_xxx value.
KNOT is set there just because it can be any rate (and easy to handle). If the rate is a normal one, e.g. 48kHz, then you can set the appropriate bitflag in hw.rates.
Takashi
Takashi Iwai wrote:
In a simple case, you don't need hw_constraint functions. Just override the corresponding fields of runtime->hw in open callback.
It looks like ASoC overwrites runtime->hw in *its* _open callback, so I have to use the hw_constraint functions.
At Wed, 16 Jul 2008 14:19:43 -0500, Timur Tabi wrote:
Takashi Iwai wrote:
In a simple case, you don't need hw_constraint functions. Just override the corresponding fields of runtime->hw in open callback.
It looks like ASoC overwrites runtime->hw in *its* _open callback, so I have to use the hw_constraint functions.
Then you can call like:
snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, fixed_rate, fixed_rate);
Takashi
Takashi Iwai wrote:
Then you can call like:
snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, fixed_rate, fixed_rate);
Ok, I think I got this working. However, I'm not sure how to handle the sample size. I have this:
struct snd_pcm_runtime *first_runtime = ssi_private->first_stream->runtime;
snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, first_runtime->sample_bits, first_runtime->sample_bits);
Is SNDRV_PCM_HW_PARAM_SAMPLE_BITS for the logical or physical width? That is, if my first stream is playing S24_BE samples, do I restrict the second stream to 24 bits or 32 bits?
participants (3)
-
Liam Girdwood
-
Takashi Iwai
-
Timur Tabi