[alsa-devel] period_size and relation to number of samples

Markus Korber korbse at gmx.at
Mon Sep 10 10:28:57 CEST 2007


Thus spake Takashi Iwai:

> At Thu, 06 Sep 2007 16:30:17 +0200,
> Markus Korber wrote:
>
>> Thus, is it possible to buffer the data in ALSA before sending them to
>> the driver, in such a way, that the driver always receives period_size
>> samples, regardless of what the application sends to ALSA?  And how
>> would I configure ALSA for such a setup?
>
> No, it's NOT guaranteed.  The application may behave in a very wrong
> manner.
>
> The point is that it's driver's responsibility to check whether the
> data filled is OK or not.  The ALSA framework is not a style like
> "fill -> wakeup -> process".  Instead, the data transfer is done
> asynchronously, and the driver is woken up via irq (or whatever).

Thanks for clarification.  However, one more question: The application
always delivers 0x1200 bytes to ALSA via snd_pcm_mmap_writei() but my
driver receives the following (buffer_size=0x4000, period_size=0x2000):

(bufnum refers to buffer 0 or 1 of my two output buffers.)

,----[ 0 ]
| Entered chip_playback_copy (bufnum: 0 -> src: 0xffce1000, bytes: 0x2400)
| Entered chip_playback_copy (bufnum: 0 -> src: 0xffce3400, bytes: 0x1200)
| 
| Entered chip_playback_copy (bufnum: 1 -> src: 0xffce4600, bytes: 0x0a00)
| Entered chip_playback_copy (bufnum: 1 -> src: 0xffce1000, bytes: 0x0800)
| Entered chip_playback_copy (bufnum: 1 -> src: 0xffce1800, bytes: 0x1200)
| 
| Entered chip_playback_copy (bufnum: 0 -> src: 0xffce2a00, bytes: 0x1200)
| Entered chip_playback_copy (bufnum: 0 -> src: 0xffce3c00, bytes: 0x1200)
| 
| Entered chip_playback_copy (bufnum: 1 -> src: 0xffce4e00, bytes: 0x0200)
| Entered chip_playback_copy (bufnum: 1 -> src: 0xffce1000, bytes: 0x1000)
| 
| Entered chip_playback_copy (bufnum: 0 -> src: 0xffce2000, bytes: 0x1200)
| Entered chip_playback_copy (bufnum: 0 -> src: 0xffce3200, bytes: 0x1200)
| 
| Entered chip_playback_copy (bufnum: 1 -> src: 0xffce4400, bytes: 0x0c00)
| Entered chip_playback_copy (bufnum: 1 -> src: 0xffce1000, bytes: 0x0600)
| Entered chip_playback_copy (bufnum: 1 -> src: 0xffce1600, bytes: 0x1200)
`----

Now, I'm using the pcm-indirect framework[1] and my hw_ptr always
toggles between 0 and period_bytes[2].

,----[ 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;
`----

This is what the application does[3] (for logging see [4]):

,----[ 3 ]
| while( number_of_frames > 0) {
|    if ( (state == SND_PCM_STATE_RUNNING) ) {
|       snd_pcm_status(this->audio_fd, pcm_stat);
|       
|       num_avail = snd_pcm_status_get_avail(pcm_stat);
|       printf("audio_alsa_out: #avail: %#04x\n", num_avail);
| 
|       if (num_avail < number_of_frames) {
|          wait_result = snd_pcm_wait(this->audio_fd, 1000);
|          printf("audio_alsa_out:write:loop:wait_result=%d\n",wait_result);
|          if (wait_result <= 0) return 0;
|       }      
|    }
|    
|    printf ("audio_alsa_out: writing %#04x samples to ALSA\n", number_of_frames);
|    result = snd_pcm_mmap_writei(this->audio_fd, buffer, number_of_frames);
|    ...
`----



More information about the Alsa-devel mailing list