Question

I am trying to come up to speed on the ALSA API and have some questions regarding this extensive API. I am using the "hw" interface not the "plughw" interface.

Question #1: Does the snd_hw_params_any() routine retrieve the default/current parameters? Some documentation/example code indicate this routine fills in the allocated snd_pcm_hw_params_t struct with some values. Are these the current configured settings for the card:device?

The reason I am confused is because, if that routine retrieves the hw_params values, then I should be able to use any of the snd_hw_params_get routines to actually get those values. This works for the snd_hw_params_get_channels() routine. But a call to either snd_pcm_hw_params_get_format() or snd_pcm_hw_params_get_buffer_size() will fail. If I first set the format or buffer size using the set routines, I can then call the get routines to retrieve the values without error. Another way to express this question would be: why does snd_pcm_hw_params_get_format() and snd_pcm_hw_parmas_get_buffer_size() fail when I use this sequence of calls:

snd_pcm_hw_params_alloca(); snd_pcm_hw_params_any(); snd_pcm_hw_params_get_channels(); snd_pcm_hw_params_get_format(); snd_pcm_hw_params_get_buffer_size();

Question #2: How do I determine the actual size of the physical memory on the sound card? I have noticed that no matter what size I use when calling snd_pcm_hw_params_set_buffer_size/min/max() and then call the snd_pcm_hw_params_get_buffer_size() that I get the same size. Again, I am using the "hw" interface and not the "plughw" interface so it seems reasonable that I cannot set the buffer size because it is actually the amount of physical memory on the card.

Since the snd_pcm_hw_params_get_buffer_size() retrieves the frame size, then the actually size of available physical capture memory on the sound card would that frame size times the number of channels times the sample word length. For example for:

int nNumberOfChannels = 2; snd_pcm_format_t tFormat = SND_PCM_FORMAT_S16; // 2 bytes per sample snd_pcm_uframes_t = 16384;

then the actual physical memory on the card would be: 2 * 2 * 16384 = 65536 bytes of physical memory available on the card.

Is this correct or am I confused here?

Thanks,

-Andres

Was it helpful?

Solution

The buffer size returned by snd_pcm_hw_params_get_buffer_size() is not (and never was) the size of the memory resident on the 'soundcard'. In the case of local audio interfaces (e.g. not serial bus-attached devices such as USB or Firewire), this is the size of a buffer in the system's main memory to or from which DMA of audio samples periodically takes place.

For USB and Firewire audio, the buffer this refers to is an entirely software concept - although it might be DMAd from in the case of Firewire. Don't expect to be able to set the buffer size below the minimum isochronous transfer unit size.

I don't think you get any guarantees from ALSA that you can actually change these parameters - it rather depends on the constraints of the hardware in the DMA controller servicing the audio interface - and on its device driver. Arrangements where the buffer size is a power of two is not unusual because it's far easier to implement in hardware.

You should take great care to check the return values from calls to snd_pcm_hw_* API calls and not assume that you got what you requested.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top