All of lore.kernel.org
 help / color / mirror / Atom feed
* what is exactly pcm.boundary?
@ 2017-01-05 18:10 Ricardo Biehl
  2017-01-05 20:36 ` Takashi Sakamoto
  0 siblings, 1 reply; 7+ messages in thread
From: Ricardo Biehl @ 2017-01-05 18:10 UTC (permalink / raw)
  To: alsa-devel

Hello. After some thoughts in ALSA internals (hw_ptr, appl_ptr, mmap'ed buffer,
ioctls) I got me in many doubts. I would love if you help me understanding this.

Well, in src/pcm/pcm_local.h  line ~469:

1	static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm)
2	{
3		snd_pcm_sframes_t avail;
4		avail = *pcm->hw.ptr + pcm->buffer_size - *pcm->appl.ptr;
5		if (avail < 0)
6			avail += pcm->boundary;
7		else if ((snd_pcm_uframes_t) avail >= pcm->boundary)
8			avail -= pcm->boundary;
9		return avail;
10	}

First, I assumed that both hw_ptr and appl_ptr always points to addresses inside
a REGION of memory that is exactly the size of buffer = (period_size * periods).

I've also tried to imagine line 4 as: The forward distance between appl_ptr and
hw_ptr where our application can write new samples:
	|s0|s1|s2|s3|s4|s5|s6|s7|s8|s9|    buffer_size = 10
For example, if hw_ptr is on 's1' and appl_ptr is on 's7' we'll have
( 1 + 10 - 7 = 4 ) [s8,s9,s0,s1] available to write, right?

	hw_ptr = Last sample that sound device has eaten up in ring buffer.
	appl_ptr = Last sample that application has written in ring buffer.

Ok, the problem comes, for example, when hw_ptr is on 's9' and appl_ptr is on
's4', so the sum is ( 9 + 10 - 4 = 15 ) -- a number greater than buffer_size.
Although I expected pcm->boundary is equal buffer_size and then the test in 7th
line would correct it:
	(9 + 10 - 4 = 15)
	(15 >= 10)  7th line condition test
        (15 - buffer_size = __5__)
resulting in five [s5,s6,s7,s8,s9] samples available. But it's not.

Why? And what is exactly 'boundary' ?
I read this
<http://www.mail-archive.com/alsa-user@lists.sourceforge.net/msg29891.html>
but doesn't help me

Another question ... can I thrust in hw_ptr value after a HWSYNC? will it be the
exactly value of the current processed sample?

And to end ... is the latency of HWSYNC operation insignificant, or it could
block or something that increases latency may happen?

Thank you very much! Cheers :-)

--
Ricardo Biehl Pasquali

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: what is exactly pcm.boundary?
  2017-01-05 18:10 what is exactly pcm.boundary? Ricardo Biehl
@ 2017-01-05 20:36 ` Takashi Sakamoto
  2017-01-05 21:14   ` Ricardo Biehl
  0 siblings, 1 reply; 7+ messages in thread
From: Takashi Sakamoto @ 2017-01-05 20:36 UTC (permalink / raw)
  To: Ricardo Biehl, alsa-devel

Hi,

On Jan 6 2017 03:10, Ricardo Biehl wrote:
> Well, in src/pcm/pcm_local.h  line ~469:
>
> 1	static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t *pcm)
> 2	{
> 3		snd_pcm_sframes_t avail;
> 4		avail = *pcm->hw.ptr + pcm->buffer_size - *pcm->appl.ptr;
> 5		if (avail < 0)
> 6			avail += pcm->boundary;
> 7		else if ((snd_pcm_uframes_t) avail >= pcm->boundary)
> 8			avail -= pcm->boundary;
> 9		return avail;
> 10	}
>
> First, I assumed that both hw_ptr and appl_ptr always points to addresses inside
> a REGION of memory that is exactly the size of buffer = (period_size * periods).

No. Both of the 'appl_ptr' and 'hw_ptr' is not within the size of 
buffer. They round up to the size of boundary. The size of boundary is 
calculated in these lines.

https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/core/pcm_native.c?h=v4.10-rc2#n590

590	while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
591		runtime->boundary *= 2;

You can also see current value of the boundary in PCM substream via 
procfs, like:
$ cat /proc/asound/card0/pcm0p/sub0/sw_params
tstamp_mode: ENABLE
period_step: 1
avail_min: 1088
start_threshold: 18446744073709551615
stop_threshold: 4971973988617027584
silence_threshold: 0
silence_size: 0
boundary: 4971973988617027584

You can see it's not the size of allocated memory because it's quite large.

The size of boundary is always multiple of the size of period in 
intermediate buffer for user space, up to UINT_MAX. Both of 'hw_ptr' and 
'appl_ptr' means total number of processed PCM frames in current PCM 
substream. They're not directly related to dedicated buffer for data 
transmission.


Regards

Takashi Sakamoto

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: what is exactly pcm.boundary?
  2017-01-05 20:36 ` Takashi Sakamoto
@ 2017-01-05 21:14   ` Ricardo Biehl
  2017-01-06  8:09     ` Clemens Ladisch
  0 siblings, 1 reply; 7+ messages in thread
From: Ricardo Biehl @ 2017-01-05 21:14 UTC (permalink / raw)
  To: Takashi Sakamoto; +Cc: alsa-devel

2017-01-05 18:36 GMT-02:00, Takashi Sakamoto <o-takashi@sakamocchi.jp>:
> Hi,
>
> On Jan 6 2017 03:10, Ricardo Biehl wrote:
>> Well, in src/pcm/pcm_local.h  line ~469:
>>
>> 1	static inline snd_pcm_uframes_t snd_pcm_mmap_playback_avail(snd_pcm_t
>> *pcm)
>> 2	{
>> 3		snd_pcm_sframes_t avail;
>> 4		avail = *pcm->hw.ptr + pcm->buffer_size - *pcm->appl.ptr;
>> 5		if (avail < 0)
>> 6			avail += pcm->boundary;
>> 7		else if ((snd_pcm_uframes_t) avail >= pcm->boundary)
>> 8			avail -= pcm->boundary;
>> 9		return avail;
>> 10	}
>>
>> First, I assumed that both hw_ptr and appl_ptr always points to addresses
>> inside
>> a REGION of memory that is exactly the size of buffer = (period_size *
>> periods).
>
> No. Both of the 'appl_ptr' and 'hw_ptr' is not within the size of
> buffer. They round up to the size of boundary. The size of boundary is
> calculated in these lines.
>
> https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/core/pcm_native.c?h=v4.10-rc2#n590
>
> 590	while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
> 591		runtime->boundary *= 2;
>
> You can also see current value of the boundary in PCM substream via
> procfs, like:
> $ cat /proc/asound/card0/pcm0p/sub0/sw_params
> tstamp_mode: ENABLE
> period_step: 1
> avail_min: 1088
> start_threshold: 18446744073709551615
> stop_threshold: 4971973988617027584
> silence_threshold: 0
> silence_size: 0
> boundary: 4971973988617027584
>
> You can see it's not the size of allocated memory because it's quite large.
>
> The size of boundary is always multiple of the size of period in
> intermediate buffer for user space, up to UINT_MAX. Both of 'hw_ptr' and
> 'appl_ptr' means total number of processed PCM frames in current PCM
> substream. They're not directly related to dedicated buffer for data
> transmission.
>

Oh Thanks :-)
I was so far from the answer ...

In this way, can I get the offset of hardware pointer in my pcm char device
mmaped area with:

	offset_in_buffer = hw_ptr % buffer_size;  ?

>
> Regards
>
> Takashi Sakamoto
>

--
Ricardo Biehl Pasquali

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: what is exactly pcm.boundary?
  2017-01-05 21:14   ` Ricardo Biehl
@ 2017-01-06  8:09     ` Clemens Ladisch
  2017-01-06 16:08       ` Ricardo Biehl
  0 siblings, 1 reply; 7+ messages in thread
From: Clemens Ladisch @ 2017-01-06  8:09 UTC (permalink / raw)
  To: Ricardo Biehl; +Cc: alsa-devel, Takashi Sakamoto

Ricardo Biehl wrote:
> In this way, can I get the offset of hardware pointer in my pcm char device
> mmaped area with:
>
> 	offset_in_buffer = hw_ptr % buffer_size;  ?

Are you talking about code in your driver (where you are responsible for
asking the hardware), or user space code (where you must not directly
read hw_ptr)?  What is the actual problem you're trying to solve?


Regards,
Clemens

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: what is exactly pcm.boundary?
  2017-01-06  8:09     ` Clemens Ladisch
@ 2017-01-06 16:08       ` Ricardo Biehl
  2017-01-06 18:27         ` Pierre-Louis Bossart
  2017-01-07  9:06         ` Clemens Ladisch
  0 siblings, 2 replies; 7+ messages in thread
From: Ricardo Biehl @ 2017-01-06 16:08 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel, Takashi Sakamoto

2017-01-06 6:09 GMT-02:00, Clemens Ladisch <clemens@ladisch.de>:
>
> Are you talking about code in your driver (where you are responsible for
> asking the hardware), or user space code (where you must not directly
> read hw_ptr)?  What is the actual problem you're trying to solve?
>

Hello!
I'm developing a "live microphone system over local network" which are user
space programs (clients => server) transferring audio nearly real-time
(human imperceptible latency).
I need to elaborate a good solution of implementation to have everything working
as expected -- networking, scheduling, IO management etc -- However I need at
first make sure I can get control over audio.

I decided to use ioctl() level of communication with ALSA in kernel, and what I
need is synchronization :-)
I must know which sample the hardware is currently processing to prevent a lot
of losses or latency increasing.

Cheers!

--
Ricardo Biehl Pasquali

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: what is exactly pcm.boundary?
  2017-01-06 16:08       ` Ricardo Biehl
@ 2017-01-06 18:27         ` Pierre-Louis Bossart
  2017-01-07  9:06         ` Clemens Ladisch
  1 sibling, 0 replies; 7+ messages in thread
From: Pierre-Louis Bossart @ 2017-01-06 18:27 UTC (permalink / raw)
  To: Ricardo Biehl, Clemens Ladisch; +Cc: alsa-devel, Takashi Sakamoto

On 1/6/17 10:08 AM, Ricardo Biehl wrote:
> 2017-01-06 6:09 GMT-02:00, Clemens Ladisch <clemens@ladisch.de>:
>>
>> Are you talking about code in your driver (where you are responsible for
>> asking the hardware), or user space code (where you must not directly
>> read hw_ptr)?  What is the actual problem you're trying to solve?
>>
>
> Hello!
> I'm developing a "live microphone system over local network" which are user
> space programs (clients => server) transferring audio nearly real-time
> (human imperceptible latency).
> I need to elaborate a good solution of implementation to have everything working
> as expected -- networking, scheduling, IO management etc -- However I need at
> first make sure I can get control over audio.
>
> I decided to use ioctl() level of communication with ALSA in kernel, and what I
> need is synchronization :-)
> I must know which sample the hardware is currently processing to prevent a lot
> of losses or latency increasing.

I would hate to sound pedantic but sample-accurate control (10us at 
48kHz) is far from trivial. The hw_ptr points to the ring buffer, but 
you may have additional samples queued up in DMA transfers, FIFOS, 
codecs and last some analog delays. On a network-based solution the 
different components typically don't use the same audio clock and you 
will have to deal with drifts between source and sink.
Best of luck.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: what is exactly pcm.boundary?
  2017-01-06 16:08       ` Ricardo Biehl
  2017-01-06 18:27         ` Pierre-Louis Bossart
@ 2017-01-07  9:06         ` Clemens Ladisch
  1 sibling, 0 replies; 7+ messages in thread
From: Clemens Ladisch @ 2017-01-07  9:06 UTC (permalink / raw)
  To: Ricardo Biehl; +Cc: alsa-devel

Ricardo Biehl wrote:
> I'm developing a "live microphone system over local network" which are user
> space programs (clients => server) transferring audio nearly real-time
> (human imperceptible latency).
> I need to elaborate a good solution of implementation to have everything working
> as expected -- networking, scheduling, IO management etc -- However I need at
> first make sure I can get control over audio.
>
> I decided to use ioctl() level of communication with ALSA in kernel

Neither using ioctls directly nor using mmap will reduce latency.

First get it correct with the normal ALSA API.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-01-07  9:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-05 18:10 what is exactly pcm.boundary? Ricardo Biehl
2017-01-05 20:36 ` Takashi Sakamoto
2017-01-05 21:14   ` Ricardo Biehl
2017-01-06  8:09     ` Clemens Ladisch
2017-01-06 16:08       ` Ricardo Biehl
2017-01-06 18:27         ` Pierre-Louis Bossart
2017-01-07  9:06         ` Clemens Ladisch

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.