[alsa-devel] hw_params function and OSS emulation

Takashi Iwai tiwai at suse.de
Wed Aug 22 11:17:45 CEST 2007


At Tue, 21 Aug 2007 13:15:16 -0500,
Timur Tabi wrote:
> 
> I'm working on an ASoC driver, and I noticed that with OSS emulation enabled, 
> my snd_pcm_ops.hw_params and and snd_pcm_ops.hw_free are called multiple times 
> when an OSS driver uses the OSS emulation.  In my case, .hw_params is called 
> *four* times, each time with a different DMA buffer size and number of periods.
> 
> The problem is that my driver allocates a DMA buffer in my .hw_params 
> function.  For now, I have it deallocate the buffers at the top of the 
> function and then allocate new ones based on the new hw_params values.
> 
> This is really annoying.  So I have a few questions:
> 
> 1) Is there any way this can be fixed?  Can't the OSS emulation code figure 
> out what it needs and wait until it's done before it calls .hw_params?

It's hard to fix.  There is no distinct between hw_params setup and
prepare setup in the OSS API.  In the OSS API, the device has to be
always ready for use at any time.  And, OSS API doesn't define the
default parameters (there are tacit understandings, though).  Because
of these requirements, the emulation needs to set up hw_params and
prepare at each time you open, or at each time any parameter-change
(OSS) ioctl is called.

> As a solution to the DMA buffer deallocate/reallocate hack I'm using, would it 
> be okay to move the actual allocations to snd_pcm_ops.prepare()?  My 
> .hw_params function will collect the relevant data and keep them in some 
> private structure.  Then when .prepare() is called, I do the actual buffer 
> allocation.

It's no good idea because the prepare callback _is_ the one that is
more frequently called in ALSA API than hw_params.

> 2) Can I assume that .prepare() is called only once?

No.  It's called to restart the stream after xrun, suspend/resume,
etc.  hw_params isn't called for restarting the stream.

> 3) Can I assume that .hw_params() is never called after .prepare() is called?

The call is allowed.


Takashi


More information about the Alsa-devel mailing list