All of lore.kernel.org
 help / color / mirror / Atom feed
* Alsa timing question
@ 2011-08-25  0:10 Raymond Toy
  2011-08-25  7:15 ` Clemens Ladisch
  0 siblings, 1 reply; 13+ messages in thread
From: Raymond Toy @ 2011-08-25  0:10 UTC (permalink / raw)
  To: alsa-devel

I'm working on an application where I'd like to have relatively fixed timing
between calls to snd_pcm_writei.  As an example, of this I used the sample
pcm.c code from <
http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html#a65>.
 I placed a simple function to write out the time (from clock_getttime)
before each call to snd_pcm_writei in write_loop.  With a sample rate of
48kHz and a buffer time of 128000 and period time of 42667, what I see is
that most calls to snd_pcm_writei are spaced about 50 ms apart.  This makes
some sense, but I was expecting the calls to be about 42.67 ms apart.
 However, about every 6th call, the time is just 200 us or so.  Why is that?


Is there any simple way to make the calls spaced more closely to 42.67 ms
apart?  Do I need to do something more complicated to achieve this?

Ray

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

* Re: Alsa timing question
  2011-08-25  0:10 Alsa timing question Raymond Toy
@ 2011-08-25  7:15 ` Clemens Ladisch
  2011-08-25 15:52   ` Raymond Toy
  2011-08-29 20:24   ` Raymond Toy
  0 siblings, 2 replies; 13+ messages in thread
From: Clemens Ladisch @ 2011-08-25  7:15 UTC (permalink / raw)
  To: Raymond Toy; +Cc: alsa-devel

Raymond Toy wrote:
> I'm working on an application where I'd like to have relatively fixed timing
> between calls to snd_pcm_writei.

Why?

> [...] I see is that most calls to snd_pcm_writei are spaced about 50 ms
> apart.  This makes some sense, but I was expecting the calls to be about
> 42.67 ms apart.  However, about every 6th call, the time is just 200 us
> or so.  Why is that?

In theory, when the device is configured for a specific period size, its
interrupts (and therefore the application wakeups) will arrive spaced at
this interval (modulo any scheduling delays).

However, if you're using the dmix plugin, the period size of your
application's device will not necessarily be identical with the period
size of the hardware device.  To see the actual period size, look into
/proc/asound/card?/pcm0p/sub0/hw_params.


Regards,
Clemens

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

* Re: Alsa timing question
  2011-08-25  7:15 ` Clemens Ladisch
@ 2011-08-25 15:52   ` Raymond Toy
  2011-08-26  8:02     ` Clemens Ladisch
  2011-08-26  8:29     ` Olivier Guillion - Myriad
  2011-08-29 20:24   ` Raymond Toy
  1 sibling, 2 replies; 13+ messages in thread
From: Raymond Toy @ 2011-08-25 15:52 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

On Thu, Aug 25, 2011 at 12:15 AM, Clemens Ladisch <clemens@ladisch.de>wrote:

> Raymond Toy wrote:
> > I'm working on an application where I'd like to have relatively fixed
> timing
> > between calls to snd_pcm_writei.
>
> Why?
>

It's a bit complicated.  A different process generates the audio and places
the data in a shared memory area.  My process sends signals the other
process to generate more data, I read the shared memory area (for the
previously generated data).  Sometime later, the other process fills the
shared area with new samples.  Thus, if the timing between calls is not
fairly regular, I'll either reread the same data or miss the new data.  (I'm
not in control of how this works.  I just have to deal with what I'm
given.)

>
> > [...] I see is that most calls to snd_pcm_writei are spaced about 50 ms
> > apart.  This makes some sense, but I was expecting the calls to be about
> > 42.67 ms apart.  However, about every 6th call, the time is just 200 us
> > or so.  Why is that?
>
> In theory, when the device is configured for a specific period size, its
> interrupts (and therefore the application wakeups) will arrive spaced at
> this interval (modulo any scheduling delays).
>
> However, if you're using the dmix plugin, the period size of your
> application's device will not necessarily be identical with the period
> size of the hardware device.  To see the actual period size, look into
> /proc/asound/card?/pcm0p/sub0/hw_params.
>
>
It says:

access: MMAP_INTERLEAVED
format: S16_LE
subformat: STD
channels: 2
rate: 44100 (44100/1)
period_size: 44096
buffer_size: 88192

Ray

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

* Re: Alsa timing question
  2011-08-25 15:52   ` Raymond Toy
@ 2011-08-26  8:02     ` Clemens Ladisch
  2011-08-26  8:29     ` Olivier Guillion - Myriad
  1 sibling, 0 replies; 13+ messages in thread
From: Clemens Ladisch @ 2011-08-26  8:02 UTC (permalink / raw)
  To: Raymond Toy; +Cc: alsa-devel

Raymond Toy wrote:
> On Thu, Aug 25, 2011 at 12:15 AM, Clemens Ladisch <clemens@ladisch.de>wrote:
> > Raymond Toy wrote:
> > > I'm working on an application where I'd like to have relatively fixed timing
> > > between calls to snd_pcm_writei.
> >
> > Why?
> 
> It's a bit complicated.  A different process generates the audio and places
> the data in a shared memory area.  My process sends signals the other
> process to generate more data, I read the shared memory area (for the
> previously generated data).  Sometime later, the other process fills the
> shared area with new samples.  Thus, if the timing between calls is not
> fairly regular, I'll either reread the same data or miss the new data.

The obvious way to resolve this problem would be to add a signal from
the other process to your process.  Even a serial number in the shared
memory area would help detecting problems.

> (I'm not in control of how this works.  I just have to deal with what
> I'm given.)

"It is a vessel of fertilizer, and none may abide its strength."

> > > [...] I see is that most calls to snd_pcm_writei are spaced about 50 ms
> > > apart.  This makes some sense, but I was expecting the calls to be about
> > > 42.67 ms apart.  However, about every 6th call, the time is just 200 us
> > > or so.  Why is that?
> >
> > In theory, when the device is configured for a specific period size, its
> > interrupts (and therefore the application wakeups) will arrive spaced at
> > this interval (modulo any scheduling delays).
> >
> > However, if you're using the dmix plugin,

Your other mail shows you're using the PulseAudio plugin.

> > the period size of your application's device will not necessarily be
> > identical with the period size of the hardware device.

PulseAudio doesn't use period interrupts, it uses its own timer that,
apparently, runs at 50 ms.

In theory, you should use a period size that is an exact multiple of
50 ms, but in practice, this is not possible because the device's sample
clock is not synchronized with the computer's timer.

You could try to use, e.g.,  500 ms periods so that the inaccuracies of
PA's timer result in smaller relative jitter in your own timing, but
this will increase latency.

Try asking on the PA list how to get accurate period timing.


Regards,
Clemens

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

* Re: Alsa timing question
  2011-08-25 15:52   ` Raymond Toy
  2011-08-26  8:02     ` Clemens Ladisch
@ 2011-08-26  8:29     ` Olivier Guillion - Myriad
  2011-08-26 15:56       ` Raymond Toy
  1 sibling, 1 reply; 13+ messages in thread
From: Olivier Guillion - Myriad @ 2011-08-26  8:29 UTC (permalink / raw)
  To: Raymond Toy; +Cc: alsa-devel

Hi,

Raymond Toy wrote:
> > > I'm working on an application where I'd like to have relatively fixed
> > timing
> > > between calls to snd_pcm_writei.
> >
> > Why?
> >
> 
> It's a bit complicated.  A different process generates the audio and places the
> data in a shared memory area.  My process sends signals the other process to
> generate more data, I read the shared memory area (for the previously generated
> data).  Sometime later, the other process fills the shared area with new
> samples.  Thus, if the timing between calls is not fairly regular, I'll either
> reread the same data or miss the new data.  (I'm not in control of how this
> works.  I just have to deal with what I'm given.)

IMO, it's not a good idea to try to synchronize perfectly two processes by way 
of an interrupt.
If the generating process has to remain untouched, you should probably 
bufferize its data in your own process before sending it to writei. It would 
add some latency, but make the data flow safer.
Here is how it could work:
1- Your process writes a "magic" pattern at the end of the shared area
2- It sends a signal to the other process to make it generate data
3- It checks whether the magic pattern is still here
4- When changed, it means the data have been calculated. It saves them to an 
internal circular buffer
5- If the circular buffer is not full, it restarts at 1-
6-In parallel, when data can be written to the device through writei, they are 
taken from the circular buffer.

Hope this helps,
Olivier

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

* Re: Alsa timing question
  2011-08-26  8:29     ` Olivier Guillion - Myriad
@ 2011-08-26 15:56       ` Raymond Toy
  2011-08-27  8:08         ` Olivier Guillion - Myriad
  0 siblings, 1 reply; 13+ messages in thread
From: Raymond Toy @ 2011-08-26 15:56 UTC (permalink / raw)
  To: Olivier Guillion - Myriad; +Cc: alsa-devel

On Fri, Aug 26, 2011 at 1:29 AM, Olivier Guillion - Myriad <
olivier@myriad-online.com> wrote:

> Hi,
>
> Raymond Toy wrote:
> > > > I'm working on an application where I'd like to have relatively fixed
> > > timing
> > > > between calls to snd_pcm_writei.
> > >
> > > Why?
> > >
> >
> > It's a bit complicated.  A different process generates the audio and
> places the
> > data in a shared memory area.  My process sends signals the other process
> to
> > generate more data, I read the shared memory area (for the previously
> generated
> > data).  Sometime later, the other process fills the shared area with new
> > samples.  Thus, if the timing between calls is not fairly regular, I'll
> either
> > reread the same data or miss the new data.  (I'm not in control of how
> this
> > works.  I just have to deal with what I'm given.)
>
> IMO, it's not a good idea to try to synchronize perfectly two processes by
> way
> of an interrupt.
> If the generating process has to remain untouched, you should probably
> bufferize its data in your own process before sending it to writei. It
> would
> add some latency, but make the data flow safer.
> Here is how it could work:
> 1- Your process writes a "magic" pattern at the end of the shared area
> 2- It sends a signal to the other process to make it generate data
> 3- It checks whether the magic pattern is still here
> 4- When changed, it means the data have been calculated. It saves them to
> an
> internal circular buffer
>

A nice idea, but I'm not sure it will work in my scenario.  The "magic"
pattern could potentially be real data (the buffer contains audio samples),
so that would cause funny, hard-to-reproduce glitches.  Plus, I think that
when I request new data, something is always written.

Clemens idea of a counter at the beginning of the buffer would work nicely,
but requires changes in the generating process.

Thanks,

Ray

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

* Re: Alsa timing question
  2011-08-26 15:56       ` Raymond Toy
@ 2011-08-27  8:08         ` Olivier Guillion - Myriad
  2011-08-27  9:15           ` Jassi Brar
  2011-08-29 18:41           ` Raymond Toy
  0 siblings, 2 replies; 13+ messages in thread
From: Olivier Guillion - Myriad @ 2011-08-27  8:08 UTC (permalink / raw)
  To: Raymond Toy; +Cc: alsa-devel

Hi,

Raymond Toy <rtoy@google.com> wrote :
> > IMO, it's not a good idea to try to synchronize perfectly two processes by way
> > of an interrupt. If the generating process has to remain untouched, you should
> > probably bufferize its data in your own process before sending it to writei.
> > It would add some latency, but make the data flow safer. Here is how it could
> > work: 1- Your process writes a "magic" pattern at the end of the shared area
> > 2- It sends a signal to the other process to make it generate data 3- It
> > checks whether the magic pattern is still here 4- When changed, it means the
> > data have been calculated. It saves them to an internal circular buffer
> >
> 
> A nice idea, but I'm not sure it will work in my scenario.  The "magic"
> pattern could potentially be real data (the buffer contains audio samples), so
> that would cause funny, hard-to-reproduce glitches. 

You are theorically right, even if I doubt that much genuine audio buffer could 
end with, let's say : 0x8000 0x7FFF followed by "This is magic!!!" string :)

>  Plus, I think that when I
> request new data, something is always written.

I thought it was asynchronous, and you just send a signal to your generating 
process to ask it generate data.

> Clemens idea of a counter at the beginning of the buffer would work nicely, but
> requires changes in the generating process.

Right. But if you can modify  the generating process and recompile it, there is 
no more problem. Can you?

Olivier

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

* Re: Alsa timing question
  2011-08-27  8:08         ` Olivier Guillion - Myriad
@ 2011-08-27  9:15           ` Jassi Brar
  2011-08-29 18:41           ` Raymond Toy
  1 sibling, 0 replies; 13+ messages in thread
From: Jassi Brar @ 2011-08-27  9:15 UTC (permalink / raw)
  To: Olivier Guillion - Myriad; +Cc: alsa-devel, Raymond Toy

On Sat, Aug 27, 2011 at 1:38 PM, Olivier Guillion - Myriad
<olivier@myriad-online.com> wrote:
> Raymond Toy <rtoy@google.com> wrote :
>> > IMO, it's not a good idea to try to synchronize perfectly two processes by way
>> > of an interrupt. If the generating process has to remain untouched, you should
>> > probably bufferize its data in your own process before sending it to writei.
>> > It would add some latency, but make the data flow safer. Here is how it could
>> > work: 1- Your process writes a "magic" pattern at the end of the shared area
>> > 2- It sends a signal to the other process to make it generate data 3- It
>> > checks whether the magic pattern is still here 4- When changed, it means the
>> > data have been calculated. It saves them to an internal circular buffer
>> >
>>
>> A nice idea, but I'm not sure it will work in my scenario.  The "magic"
>> pattern could potentially be real data (the buffer contains audio samples), so
>> that would cause funny, hard-to-reproduce glitches.
>
> You are theorically right, even if I doubt that much genuine audio buffer could
> end with, let's say : 0x8000 0x7FFF followed by "This is magic!!!" string :)
>
It can be made simpler.
If anything like that, I tend to agree with Clemens idea if he meant each
chunk (particular size of data written by the producer process and read by
consumer process) starts with a, say 32bits, serial number.
After reading, the reader resets the serial to 0, for the writer to
get the message
that the data has been consumed.
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

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

* Re: Alsa timing question
  2011-08-27  8:08         ` Olivier Guillion - Myriad
  2011-08-27  9:15           ` Jassi Brar
@ 2011-08-29 18:41           ` Raymond Toy
  1 sibling, 0 replies; 13+ messages in thread
From: Raymond Toy @ 2011-08-29 18:41 UTC (permalink / raw)
  To: Olivier Guillion - Myriad; +Cc: alsa-devel

On Sat, Aug 27, 2011 at 1:08 AM, Olivier Guillion - Myriad <
olivier@myriad-online.com> wrote:

> Hi,
>
> Raymond Toy <rtoy@google.com> wrote :
> > > IMO, it's not a good idea to try to synchronize perfectly two processes
> by way
> > > of an interrupt. If the generating process has to remain untouched, you
> should
> > > probably bufferize its data in your own process before sending it to
> writei.
> > > It would add some latency, but make the data flow safer. Here is how it
> could
> > > work: 1- Your process writes a "magic" pattern at the end of the shared
> area
> > > 2- It sends a signal to the other process to make it generate data 3-
> It
> > > checks whether the magic pattern is still here 4- When changed, it
> means the
> > > data have been calculated. It saves them to an internal circular buffer
> > >
> >
> > A nice idea, but I'm not sure it will work in my scenario.  The "magic"
> > pattern could potentially be real data (the buffer contains audio
> samples), so
> > that would cause funny, hard-to-reproduce glitches.
>
> You are theorically right, even if I doubt that much genuine audio buffer
> could
> end with, let's say : 0x8000 0x7FFF followed by "This is magic!!!" string
> :)
>

Agreed.


>
> >  Plus, I think that when I
> > request new data, something is always written.
>
> I thought it was asynchronous, and you just send a signal to your
> generating
> process to ask it generate data.
>

I'm not 100% sure, but the signal is really request to generate the next set
of data and the "current" set is returned.  If we call faster than
necessary, we always get some data, plus calls to generate new data to be
read next time.  I suspect the new data is just written into a buffer,
overwriting whatever was there.  Hence, the problem I have if the callback
requests are not regularly spaced according to the period size.

>
> > Clemens idea of a counter at the beginning of the buffer would work
> nicely, but
> > requires changes in the generating process.
>
> Right. But if you can modify  the generating process and recompile it,
> there is
> no more problem. Can you?
>

Sure, but once I have to modify both, there's not point in a "magic" string.
 I can do what Clemens suggested.

Ray

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

* Re: Alsa timing question
  2011-08-25  7:15 ` Clemens Ladisch
  2011-08-25 15:52   ` Raymond Toy
@ 2011-08-29 20:24   ` Raymond Toy
  2011-08-30  7:49     ` Clemens Ladisch
  1 sibling, 1 reply; 13+ messages in thread
From: Raymond Toy @ 2011-08-29 20:24 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

In theory, when the device is configured for a specific period size, its
> interrupts (and therefore the application wakeups) will arrive spaced at
> this interval (modulo any scheduling delays).
>
> However, if you're using the dmix plugin, the period size of your
> application's device will not necessarily be identical with the period
> size of the hardware device.  To see the actual period size, look into
> /proc/asound/card?/pcm0p/sub0/hw_params.
>

Would dmix allow me to control this better than pulse audio? (I'm still
looking into how to get pulse audio to do what I want.)

Ray

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

* Re: Alsa timing question
  2011-08-29 20:24   ` Raymond Toy
@ 2011-08-30  7:49     ` Clemens Ladisch
  2011-08-30 19:04       ` Raymond Toy
  0 siblings, 1 reply; 13+ messages in thread
From: Clemens Ladisch @ 2011-08-30  7:49 UTC (permalink / raw)
  To: Raymond Toy; +Cc: alsa-devel

Raymond Toy wrote:
>> However, if you're using the dmix plugin, the period size of your
>> application's device will not necessarily be identical with the period
>> size of the hardware device.
> 
> Would dmix allow me to control this better than pulse audio?

These parameters must be chosen by dmix before the first dmix device is
used, so applications cannot control them directly.

The defaults for dmix's period_size, period_time, and periods are 1024,
-1, and 16.  They can be overridden by setting the configuration values
defaults.dmix.DRIVER.period_size/period_time/periods, where DRIVER is
the internal driver name (the name between the colon and the hyphen in
/proc/asound/cards, or the file name in /usr/share/alsa/cards/).


Regards,
Clemens

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

* Re: Alsa timing question
  2011-08-30  7:49     ` Clemens Ladisch
@ 2011-08-30 19:04       ` Raymond Toy
  2011-08-31 20:07         ` Clemens Ladisch
  0 siblings, 1 reply; 13+ messages in thread
From: Raymond Toy @ 2011-08-30 19:04 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

On Tue, Aug 30, 2011 at 12:49 AM, Clemens Ladisch <clemens@ladisch.de>wrote:

> Raymond Toy wrote:
> >> However, if you're using the dmix plugin, the period size of your
> >> application's device will not necessarily be identical with the period
> >> size of the hardware device.
> >
> > Would dmix allow me to control this better than pulse audio?
>
> These parameters must be chosen by dmix before the first dmix device is
> used, so applications cannot control them directly.
>
> The defaults for dmix's period_size, period_time, and periods are 1024,
> -1, and 16.  They can be overridden by setting the configuration values
> defaults.dmix.DRIVER.period_size/period_time/periods, where DRIVER is
> the internal driver name (the name between the colon and the hyphen in
> /proc/asound/cards, or the file name in /usr/share/alsa/cards/).
>
>
Thanks for the info.  Can this be done programmatically?  I've done some
tests using dmix by setting up my .asoundrc appropriately, and dmix works
very nicely once I got the dmix period size and buffer size to agree with my
application.  However for the application, I don't want to have to tell the
user to set up dmix.  (Yes, I know this is not nice, but we're doing this
for testing right now, to make it easier for users to test this.)

Thanks,

Ray

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

* Re: Alsa timing question
  2011-08-30 19:04       ` Raymond Toy
@ 2011-08-31 20:07         ` Clemens Ladisch
  0 siblings, 0 replies; 13+ messages in thread
From: Clemens Ladisch @ 2011-08-31 20:07 UTC (permalink / raw)
  To: Raymond Toy; +Cc: alsa-devel

Raymond Toy wrote:
> Clemens Ladisch <clemens@ladisch.de> wrote:
>     The defaults for dmix's period_size, period_time, and periods are 1024,
>     -1, and 16.  They can be overridden by setting the configuration values
>     defaults.dmix.DRIVER.period_size/period_time/periods, where DRIVER is
>     the internal driver name (the name between the colon and the hyphen in
>     /proc/asound/cards, or the file name in /usr/share/alsa/cards/).
>
> Thanks for the info.  Can this be done programmatically?

Not really.  You could define your own device, but it wouldn't work together
with any open default dmix device.

> However for the application, I don't want to have to tell the user to set
> up dmix.

If you know that you're using dmix, and which hardware device is actually
used, you could use a PCM slave timer to get notifications of period
interrupts.  (The dmix plugin also uses this mechanism, but then rounds
the events to the application's period size.)

For PulseAudio, there seems to be no choice but to use a period size that
is somehow aligned to PA's internal timer granularity.


Regards,
Clemens

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

end of thread, other threads:[~2011-08-31 20:07 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-25  0:10 Alsa timing question Raymond Toy
2011-08-25  7:15 ` Clemens Ladisch
2011-08-25 15:52   ` Raymond Toy
2011-08-26  8:02     ` Clemens Ladisch
2011-08-26  8:29     ` Olivier Guillion - Myriad
2011-08-26 15:56       ` Raymond Toy
2011-08-27  8:08         ` Olivier Guillion - Myriad
2011-08-27  9:15           ` Jassi Brar
2011-08-29 18:41           ` Raymond Toy
2011-08-29 20:24   ` Raymond Toy
2011-08-30  7:49     ` Clemens Ladisch
2011-08-30 19:04       ` Raymond Toy
2011-08-31 20:07         ` 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.