[alsa-devel] Understanding _snd_pcm_channel_area Struct (PCM Interface)!

Guilherme grlongo.ireland at gmail.com
Tue Jun 30 16:40:20 CEST 2009


Tks takashi....

The doubt comes from this block of code:

for (chn = 0; chn < channels; chn++) {
            if ((areas[chn].first % 8) != 0) {
                    printf("areas[%i].first == %i, abortando...\n", chn, 
areas[chn].first);
                    exit(EXIT_FAILURE);
            }
            //pega endereço e offset da area
            samples[chn] = /*(signed short *)*/(((unsigned char 
*)areas[chn].addr) + (areas[chn].first / 8));
           
         if ((areas[chn].step % 16) != 0) {
                printf("areas[%i].step == %i, aborting...\n", chn, 
areas[chn].step);
                exit(EXIT_FAILURE);
         }
           
                steps[chn] = areas[chn].step / 8;
                samples[chn] += offset * steps[chn];
        }

first:

areas[chn].first % 8   ( I am using chn = 1). So for the only area that 
I have, if I get the value of the parameter 'first' isn't divisible by 
8, the program exits.
The  same doubt happens with "areas[chn].step % 16"  and  
"areas[chn].step / 8".

This is the parameter I am using:

static snd_pcm_format_t format = SND_PCM_FORMAT_S16;   //sample format 
unsigned 16 bit endian

Perhaps with this practical example I can understand better.

Thanks for ur patient!



Tks!

-------------------

Guilherme Longo

Dept. Eng. da Computação
Unaerp

Linux User - #484927

*Before Asking
http://www.istf.com.br/?page=perguntas

!- I'd rather die on my feet than live on my knees -!



Takashi Iwai wrote:
> At Fri, 26 Jun 2009 23:56:43 -0300,
> Guilherme wrote:
>   
>> Takashi...
>>
>> The base_address and the step sounds pretty clear to me.... just the 
>> offset I could not understand.
>>
>> What the difference in being  .first = 0 or .first = 2??? Could you 
>> provide please a more in depth explanation. I tried really hard find 
>> this but there is nothing related in the documentation.
>>
>> area[0].addr = base_address;
>> 	addr[0].first = 0;
>> 	addr[0].step = 4;
>> 	addr[1].addr = base_address;
>> 	addr[1].first = 2;
>> 	addr[1].step = 4;
>>
>> P.S. being a stereo or a mono pipeline I understand... just the way the offset works that is not so clear to me.
>>     
>
> Actually, the non-interleaved formats can be represented also with
> a single base_address (and is so in the actual implementation).
>
> 	addr[0].addr = base_addr;
> 	addr[0].first = 0;
> 	addr[0].step = 2;
> 	addr[1].addr = base_addr;
> 	addr[1].first = mono_buffer_len;
> 	addr[1].step = 2;
> 	addr[2].addr = base_addr;
> 	addr[2].first = mono_buffer_len * 2;
> 	addr[2].step = 2;
> 	...
>
> The "first" is the offset of the first sample.  The address of the
> first sample of the channel is simply calculated as addr + first.
> This is because just we want to keep the base address same to all
> channels as much as possible especially in mmap mode.
>
>
> Takashi
>
>   


More information about the Alsa-devel mailing list