snd_pcm_status_get_avail() values

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I've got a driver with the following settings:

,----
| static const struct snd_pcm_hardware svenm_pcm_hardware = {
|       .info                   = SNDRV_PCM_INFO_MMAP |
|                                 SNDRV_PCM_INFO_MMAP_VALID |
|                                 SNDRV_PCM_INFO_BLOCK_TRANSFER |
|                                 SNDRV_PCM_INFO_PAUSE |
|                                 SNDRV_PCM_INFO_RESUME |
|                                 SNDRV_PCM_INFO_INTERLEAVED,
|       .formats                = SNDRV_PCM_FMTBIT_S16_LE |
|                                 SNDRV_PCM_FMTBIT_U16_LE,
|       .channels_min           = 2, /* 2 = only stereo */
|       .channels_max           = 2,
|       .period_bytes_min       = 8*1024,
|       .period_bytes_max       = 8*1024,
|       .periods_min            = 2,
|       .periods_max            = 2,
|       .buffer_bytes_max       = 4*8*1024,
| };
`----

,----[ _pcm_prepare() ]
|       chip->playback.hw_buffer_size = prtd->period_bytes * 2; /* byte size */
|       chip->playback.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
`----

Since my HW only allows for a period number of 2, I would like to always
receive period_bytes_min(max) input bytes from an application (mplayer,
xine, etc.) so that I can always fill one complete HW output buffer.

The application (mplayer) does [3] to determine the number of bytes it
is allowed to write with snd_pcm_writei() (for logging see [4]):

,----[ 3 ]
|     bytes_to_write = snd_pcm_status_get_avail(status) * bytes_per_sample;
`----

(Here 1 sample equals 4 bytes, S16_LE, stereo.)

,----[ 4 ]
| fill_audio_out_buffers: bytes_to_write=16384
| alsa-play: frames=4096, len=16384
| fill_audio_out_buffers: bytes_to_write=8192                                                           
| alsa-play: frames=2048, len=8192
| fill_audio_out_buffers: bytes_to_write=8192                                                           
| alsa-play: frames=2048, len=8192
| fill_audio_out_buffers: bytes_to_write=8192                                                           
| alsa-play: frames=2048, len=8192
| fill_audio_out_buffers: bytes_to_write=16384                                                          
| alsa-play: frames=4096, len=16384
| fill_audio_out_buffers: bytes_to_write=16384                                                          
| alsa-play: frames=4096, len=16384
`----

Furthermore, I'm using the pcm-indirect framework[1] and my hw_ptr
always toggles between 0 and period_bytes[2] (bufnum refers to the HW
playback buffer number).

,----[ 1 ]
| static snd_pcm_uframes_t
|         chip_pcm_pointer(struct snd_pcm_substream *substream)
| {
|         ...
|         return snd_pcm_indirect_playback_pointer(substream, &chip->playback,
|                prtd->playback_hw_ptr);
| }
`----

,----[ 2 ]
| if (bufnum == 0)
|         prtd->playback_hw_ptr = 0;
| else
|         prtd->playback_hw_ptr = prtd->period_bytes;
`----

Thus, how is the value returned by snd_pcm_status_get_avail determined?
I mean, if my pointer always toggles between 0 and period_bytes[2], how
can ALSA return the values logged in [4]?  Would this mean that I'm not
able to process (in the application) the samples fast enough and the HW
buffer runs empty in the meantime?  
(I would expect snd_pcm_status_get_avail to always returns 8192.)

Or is there an additional parameter or constraint to somehow limit the
input sample number from an application?

Thanks.

Regards,
Markus Korber
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux