Re: period_size and relation to number of samples

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

 



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);
|    ...
`----

>From my understanding the application blocks until it can send new data.
However, although the application always delivers 0x1200 bytes to ALSA,
my driver receives different amount of data.  Why?  Is there some
buffering in ALSA?  

Secondly, although my period_size is 0x2000 bytes, why do I receive for
example 0x0a00+0x0800+0x1200=0x2400 bytes (see [0]) or 0x1200 bytes and
not at most 0x2000 bytes?

Thirdly, 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 below [4]?  

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

,----[ 4 ]
| loop: writing 0x480 samples to sound device
| audio_alsa_out: writing 0x480 samples to ALSA
| 
| loop: writing 0x480 samples to sound device
| audio_alsa_out: writing 0x480 samples to ALSA
| 
| loop: writing 0x480 samples to sound device
| audio_alsa_out: #avail: 0x700
| audio_alsa_out: writing 0x480 samples to ALSA
| 
| loop: writing 0x480 samples to sound device
| audio_alsa_out: #avail: 0xa80
| audio_alsa_out: writing 0x480 samples to ALSA
| 
| loop: writing 0x480 samples to sound device
| audio_alsa_out: #avail: 0xe00
| audio_alsa_out: writing 0x480 samples to ALSA
| 
| loop: writing 0x480 samples to sound device
| audio_alsa_out: #avail: 0x980
| audio_alsa_out: writing 0x480 samples to ALSA
| 
| loop: writing 0x480 samples to sound device
| audio_alsa_out: #avail: 0x500
| audio_alsa_out: writing 0x480 samples to ALSA
| 
| loop: writing 0x480 samples to sound device
| audio_alsa_out: #avail: 0x80
| audio_alsa_out: writing 0x480 samples to ALSA
| 
| loop: writing 0x480 samples to sound device
| audio_alsa_out: #avail: 0x400
| audio_alsa_out: writing 0x480 samples to ALSA
| 
| loop: writing 0x480 samples to sound device
| audio_alsa_out: #avail: 0x780
| audio_alsa_out: writing 0x480 samples to ALSA
`----

Thanks in advance.

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