All of lore.kernel.org
 help / color / mirror / Atom feed
* XRUN happens too often.
@ 2008-04-08 10:15 Rong-Jhe
  2008-04-08 11:40 ` Rong-Jhe
  2008-04-10  6:41 ` Clemens Ladisch
  0 siblings, 2 replies; 13+ messages in thread
From: Rong-Jhe @ 2008-04-08 10:15 UTC (permalink / raw)
  To: alsa-devel

I use "default" pcm and open it in block mode.
Then, I set the this pcm to perform 16-bit, two channels, and 44100 bps 
sampling rate audio data.
The number of periods per buffer is 10.

The follows are the parameters that I read from the pcm.
sampling rate = 44100 bps
period time = 21333 us
period size = 940 frames
buffer time = 213330 us
buffer size = 9408 frames

A sample in 16-bit, two channels is 4 bytes.
I allocate a audio data of 9408x4=37632 bytes.

audio_data=malloc(buffer_size*4);

This audio_data buffer will receive audio data from the network.
If this buffer is full, I use snd_pcm_writei( ) to put the buffer into the pcm.

snd_pcm_sframes_t frames;
snd_pcm_t *handle;

while((frame=snd_pcm_writei(handle, audio_data, buffer_size))<0)
{
   if(frames==-EPIPE)
      snd_pcm_prepare(handle);
   else
      printf("snd_pcm_writei error %d\n", frames);
}

The codes states that I put the entire buffer into the pcm at each time. The 
pcm use 10 periods to perform this buffer. The program can work normally.

If the sampling rate is changed, the program will encounter XRUN frequently.

The follows are the parameters that I read from the pcm after setting sampling 
rate to 48000.
sampling rate = 48000 bps
period time = 21333 us
period size = 1024 frames
buffer time = 213330 us
buffer size = 10240 frames
audio_data=malloc(buffer_size*4); //10240x4=40960

I also put the entire buffer into the pcm at each time, but snd_pcm_writei( )
will return -PIPE frequently.

What is the problem?

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

* Re: XRUN happens too often.
  2008-04-08 10:15 XRUN happens too often Rong-Jhe
@ 2008-04-08 11:40 ` Rong-Jhe
  2008-04-08 15:20   ` stan
  2008-04-10  6:41 ` Clemens Ladisch
  1 sibling, 1 reply; 13+ messages in thread
From: Rong-Jhe @ 2008-04-08 11:40 UTC (permalink / raw)
  To: alsa-devel

 
> A sample in 16-bit, two channels is 4 bytes.
> I allocate a audio data of 9408x4=37632 bytes.
> 
> audio_data=malloc(buffer_size*4);
> 
> This audio_data buffer will receive audio data from the network.
> If this buffer is full, I use snd_pcm_writei( ) to put the buffer into the 
pcm.
> 
> snd_pcm_sframes_t frames;
> snd_pcm_t *handle;
> 
> while((frame=snd_pcm_writei(handle, audio_data, buffer_size))<0)
> {
>    if(frames==-EPIPE)
>       snd_pcm_prepare(handle);
>    else
>       printf("snd_pcm_writei error %d\n", frames);
> }
> 
> The codes states that I put the entire buffer into the pcm at each time. The 
> pcm use 10 periods to perform this buffer. The program can work normally.
> 
> If the sampling rate is changed, the program will encounter XRUN frequently.
> 
> The follows are the parameters that I read from the pcm after setting 
sampling 
> rate to 48000.
> sampling rate = 48000 bps
> period time = 21333 us
> period size = 1024 frames
> buffer time = 213330 us
> buffer size = 10240 frames
> audio_data=malloc(buffer_size*4); //10240x4=40960
> 
> I also put the entire buffer into the pcm at each time, but snd_pcm_writei( )
> will return -PIPE frequently.
> 
> What is the problem?
> 
----------------------------------------------------------
I use snd_pcm_avail_update( ) to show the number of frames that can write into 
the pcm before using snd_pcm_writei( ).
I found that sometimes snd_pcm_avail_update( ) will return more than buffer 
size.
EX. buffer size = 10240, sometimes snd_pcm_avail_update( ) 10274 > 10240.
Dose this cause XRUN?
How to improve it ?

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

* Re: XRUN happens too often.
  2008-04-08 11:40 ` Rong-Jhe
@ 2008-04-08 15:20   ` stan
  2008-04-09 12:06     ` Rong-Jhe
  0 siblings, 1 reply; 13+ messages in thread
From: stan @ 2008-04-08 15:20 UTC (permalink / raw)
  To: Rong-Jhe; +Cc: alsa-devel

Rong-Jhe wrote:
>  
>   
>> A sample in 16-bit, two channels is 4 bytes.
>> I allocate a audio data of 9408x4=37632 bytes.
>>
>> audio_data=malloc(buffer_size*4);
>>
>> This audio_data buffer will receive audio data from the network.
>> If this buffer is full, I use snd_pcm_writei( ) to put the buffer into the 
>>     
> pcm.
>   
>> snd_pcm_sframes_t frames;
>> snd_pcm_t *handle;
>>
>> while((frame=snd_pcm_writei(handle, audio_data, buffer_size))<0)
>> {
>>    if(frames==-EPIPE)
>>       snd_pcm_prepare(handle);
>>    else
>>       printf("snd_pcm_writei error %d\n", frames);
>> }
>>
>> The codes states that I put the entire buffer into the pcm at each time. The 
>> pcm use 10 periods to perform this buffer. The program can work normally.
>>
>> If the sampling rate is changed, the program will encounter XRUN frequently.
>>
>> The follows are the parameters that I read from the pcm after setting 
>>     
> sampling 
>   
>> rate to 48000.
>> sampling rate = 48000 bps
>> period time = 21333 us
>> period size = 1024 frames
>> buffer time = 213330 us
>> buffer size = 10240 frames
>> audio_data=malloc(buffer_size*4); //10240x4=40960
>>
>> I also put the entire buffer into the pcm at each time, but snd_pcm_writei( )
>> will return -PIPE frequently.
>>
>> What is the problem?
>>
>>     
> ----------------------------------------------------------
> I use snd_pcm_avail_update( ) to show the number of frames that can write into 
> the pcm before using snd_pcm_writei( ).
> I found that sometimes snd_pcm_avail_update( ) will return more than buffer 
> size.
> EX. buffer size = 10240, sometimes snd_pcm_avail_update( ) 10274 > 10240.
> Dose this cause XRUN?
> How to improve it ?
>
>   
I don't have a direct answer for you, but I have an application that seems
to be able to write data using writei with no problems at rates up to
192 KHz.  You can download it from sourceforge and look at the source.

http://sourceforge.net/projects/discord/ 

I copied and adapted from other examples on the web.  Do a search for 
alsa in
the source code and it should take you to the initialization function 
and the
playing function.

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

* Re: XRUN happens too often.
  2008-04-08 15:20   ` stan
@ 2008-04-09 12:06     ` Rong-Jhe
  2008-04-09 22:28       ` stan
  0 siblings, 1 reply; 13+ messages in thread
From: Rong-Jhe @ 2008-04-09 12:06 UTC (permalink / raw)
  To: alsa-devel

> I don't have a direct answer for you, but I have an application that seems
> to be able to write data using writei with no problems at rates up to
> 192 KHz.  You can download it from sourceforge and look at the source.
> 
> http://sourceforge.net/projects/discord/ 
> 
> I copied and adapted from other examples on the web.  Do a search for 
> alsa in
> the source code and it should take you to the initialization function 
> and the
> playing function.
> 

Thanks for your help.
I think that XRUN may happen because the time of using snd_pcm_writei().
I have a problem about snd_pcm_write().
If the pcm is block, when does snd_pcm_writei() return?

I try to write the audio data into the dsp file directly without ALSA library.
The data will be written into DMA of the soundcard.
This action of writting is asynchronous, and the write() returns after 
queueing the data intto the DMA.

I guess the problem may be caused by the late time which the second 
snd_pcm_writei() is called.
The time between two snd_pcm_writei() may be too long, so the pcm enters XRUN 
state.

The period time in this pcm is 21333 us, and the buffer time is 213330 us 
because there are 10 periods in a buffer.

I recorded the time timeA that snd_pcm_writei() is called, and the time timeB 
that snd_pcm_writei() returns.
I calculate the duration between timeA and timeB, and the duration is not 
regular.

If snd_pcm_writei() is synchronous, the duration may be equal to the buffer 
time( 10xperiod time).
According to the measurement, snd_pcm_writei() seems not to be synchronous.
Can anyone tell me the basic theory of snd_pcm_writei(), especially in dmix 
mode.

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

* Re: XRUN happens too often.
  2008-04-09 12:06     ` Rong-Jhe
@ 2008-04-09 22:28       ` stan
  2008-04-10  1:01         ` Lee Revell
  0 siblings, 1 reply; 13+ messages in thread
From: stan @ 2008-04-09 22:28 UTC (permalink / raw)
  To: Rong-Jhe; +Cc: alsa-devel

Rong-Jhe wrote:
>> I don't have a direct answer for you, but I have an application that seems
>> to be able to write data using writei with no problems at rates up to
>> 192 KHz.  You can download it from sourceforge and look at the source.
>>
>> http://sourceforge.net/projects/discord/ 
>>
>> I copied and adapted from other examples on the web.  Do a search for 
>> alsa in
>> the source code and it should take you to the initialization function 
>> and the
>> playing function.
>>
>>     
>
> Thanks for your help.
> I think that XRUN may happen because the time of using snd_pcm_writei().
> I have a problem about snd_pcm_write().
> If the pcm is block, when does snd_pcm_writei() return?
>
> I try to write the audio data into the dsp file directly without ALSA library.
> The data will be written into DMA of the soundcard.
> This action of writting is asynchronous, and the write() returns after 
> queueing the data intto the DMA.
>
> I guess the problem may be caused by the late time which the second 
> snd_pcm_writei() is called.
> The time between two snd_pcm_writei() may be too long, so the pcm enters XRUN 
> state.
>
> The period time in this pcm is 21333 us, and the buffer time is 213330 us 
> because there are 10 periods in a buffer.
>
> I recorded the time timeA that snd_pcm_writei() is called, and the time timeB 
> that snd_pcm_writei() returns.
> I calculate the duration between timeA and timeB, and the duration is not 
> regular.
>
> If snd_pcm_writei() is synchronous, the duration may be equal to the buffer 
> time( 10xperiod time).
> According to the measurement, snd_pcm_writei() seems not to be synchronous.
> Can anyone tell me the basic theory of snd_pcm_writei(), especially in dmix 
> mode.
>
>   
I'm not sure I understand what your asking, and I don't know if
I'm the right person to answer at any rate :-), but here goes.

I think you are asking why there is variation in the time that a
system call takes (writei is calling the alsa library, a system library),
and if so then it is because all modern OSs have multitasking and 
interrupts.
Even hardened real time systems can have variation on interrupt
call response times, depending on what is happening.  The write to the sound
device is an interrupt, and the OS controls that.

That being said, if you are having underruns because of interrupt processing
time you are very close to the limit on your system.  I don't think that can
be it unless you are doing something like video processing at the time 
you are
playing, or something like beagle or dbupdate is running (higher 
priority tasks
than the sound card unless you have real time sound set).

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

* Re: XRUN happens too often.
  2008-04-09 22:28       ` stan
@ 2008-04-10  1:01         ` Lee Revell
  2008-04-10  3:29           ` Rong-Jhe
  0 siblings, 1 reply; 13+ messages in thread
From: Lee Revell @ 2008-04-10  1:01 UTC (permalink / raw)
  To: stan; +Cc: alsa-devel, Rong-Jhe

On Wed, Apr 9, 2008 at 6:28 PM, stan <ghjeold_i_mwee@cox.net> wrote:
>  That being said, if you are having underruns because of interrupt processing
>  time you are very close to the limit on your system.  I don't think that can
>  be it unless you are doing something like video processing at the time
>  you are
>  playing, or something like beagle or dbupdate is running (higher
>  priority tasks
>  than the sound card unless you have real time sound set).

Rong-Jhe,

If you aren't already, try using SCHED_FIFO priority for your audio thread.

Lee

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

* Re: XRUN happens too often.
  2008-04-10  1:01         ` Lee Revell
@ 2008-04-10  3:29           ` Rong-Jhe
  2008-04-10  4:54             ` Lee Revell
  0 siblings, 1 reply; 13+ messages in thread
From: Rong-Jhe @ 2008-04-10  3:29 UTC (permalink / raw)
  To: alsa-devel

Thanks to all that answer my question.
My application is receiving audio data from newtork and play it with ALSA 
library. 
The environment is in ARM not in PC. The same codes can not perform well in 
ARM as in PC.
I have not seen the implementation of snd_pcm_writei(), and only read the 
document of ALSA to use this function.
I guess snd_pcm_writei() will generate a thread that can write data into the 
DMA of soundcard at each period.
This may explain why the duration of snd_pcm_writei() is not regular, and why 
ALSA lib can use function call to implement mixing without a mixing server.
Sometimes the duration is long and sometimes is short.
This may be caused by the generation of the thread in snd_pcm_writei().

I think the thread plays the role of mixing server and terminates when all the 
periods of buffer are played. Then XRUN state is entered.
In my environment, the speed of receiving audio data from network is slow than 
playing audio data with snd_pcm_writei().
In the beginning, the pcm will enter XRUN state, because the audio data from 
network is not full enough to play.
I use more buffer to receive data and play less buffer with snd_pcm_writei(), 
so the time that audio buffer runs out can be delayed.
The delay can let the thread in snd_pcm_writei() to have enough space to play 
audio data.
When the buffer runs out, the thread in snd_pcm_writei() may still has 
remaining data to play, so XRUN won't happen.

I don't know whether I am right. After I see the implementation of 
snd_pcm_writei(), I may have more correct explanation.

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

* Re: XRUN happens too often.
  2008-04-10  3:29           ` Rong-Jhe
@ 2008-04-10  4:54             ` Lee Revell
  2008-04-10  7:59               ` Rong-Jhe
  0 siblings, 1 reply; 13+ messages in thread
From: Lee Revell @ 2008-04-10  4:54 UTC (permalink / raw)
  To: Rong-Jhe; +Cc: alsa-devel

On Wed, Apr 9, 2008 at 11:29 PM, Rong-Jhe <r93922118@ntu.edu.tw> wrote:
> Thanks to all that answer my question.
>  My application is receiving audio data from newtork and play it with ALSA
>  library.
>  The environment is in ARM not in PC. The same codes can not perform well in
>  ARM as in PC.
>  I have not seen the implementation of snd_pcm_writei(), and only read the
>  document of ALSA to use this function.
>  I guess snd_pcm_writei() will generate a thread that can write data into the
>  DMA of soundcard at each period.
>  This may explain why the duration of snd_pcm_writei() is not regular, and why
>  ALSA lib can use function call to implement mixing without a mixing server.

ALSA does not generate threads for you like this.  I was referring to
your application's audio thread, assuming that your app is indeed
multithreaded.

The duration probably varies because the call to snd_pcm_writei() will
block until there is enough space in the ALSA ringbuffer to receive
your data.

Lee

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

* Re: XRUN happens too often.
  2008-04-08 10:15 XRUN happens too often Rong-Jhe
  2008-04-08 11:40 ` Rong-Jhe
@ 2008-04-10  6:41 ` Clemens Ladisch
  1 sibling, 0 replies; 13+ messages in thread
From: Clemens Ladisch @ 2008-04-10  6:41 UTC (permalink / raw)
  To: Rong-Jhe; +Cc: alsa-devel

Rong-Jhe wrote:
> buffer size = 9408 frames
>
> A sample in 16-bit, two channels is 4 bytes.
> I allocate a audio data of 9408x4=37632 bytes.
>
> audio_data=malloc(buffer_size*4);
>
> This audio_data buffer will receive audio data from the network.
> If this buffer is full, I use snd_pcm_writei( ) to put the buffer into the pcm.

When this buffer is full, the device buffer is completely empty,
and even the slightest delay will result in an underrun.

Write data to the device buffer immediately when you receive it.


HTH
Clemens

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

* Re: XRUN happens too often.
  2008-04-10  4:54             ` Lee Revell
@ 2008-04-10  7:59               ` Rong-Jhe
  2008-04-10  8:20                 ` Jaroslav Kysela
  2008-04-10  8:24                 ` Rong-Jhe
  0 siblings, 2 replies; 13+ messages in thread
From: Rong-Jhe @ 2008-04-10  7:59 UTC (permalink / raw)
  To: alsa-devel


> 
> ALSA does not generate threads for you like this.  I was referring to
> your application's audio thread, assuming that your app is indeed
> multithreaded.
> 
> The duration probably varies because the call to snd_pcm_writei() will
> block until there is enough space in the ALSA ringbuffer to receive
> your data.
> 
> Lee
> 

I found that there will be a thread generated after calling snd_pcm_open().
I use command 'ps' to check it.
Due to this I guess snd_pcm_writei() only put the data into the buffer of the 
thread 'pcm'.

This thread then schedules of mixes the audio data, and put it into the buffer 
of ALSA driver.
ALSA ringbuffer only belongs to ALSA library, and ALSA driver uses anoother 
buffer in kernel.
Thus, there must be a thread that can put the data in ALSA ringbuffer into the 
buffer of ALSA driver.

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

* Re: XRUN happens too often.
  2008-04-10  7:59               ` Rong-Jhe
@ 2008-04-10  8:20                 ` Jaroslav Kysela
  2008-04-10 12:19                   ` Rong-Jhe
  2008-04-10  8:24                 ` Rong-Jhe
  1 sibling, 1 reply; 13+ messages in thread
From: Jaroslav Kysela @ 2008-04-10  8:20 UTC (permalink / raw)
  To: Rong-Jhe; +Cc: ALSA development

On Thu, 10 Apr 2008, Rong-Jhe wrote:

> > ALSA does not generate threads for you like this.  I was referring to
> > your application's audio thread, assuming that your app is indeed
> > multithreaded.
> > 
> > The duration probably varies because the call to snd_pcm_writei() will
> > block until there is enough space in the ALSA ringbuffer to receive
> > your data.
> > 
> > Lee
> > 
> 
> I found that there will be a thread generated after calling 
> snd_pcm_open(). I use command 'ps' to check it. Due to this I guess 
> snd_pcm_writei() only put the data into the buffer of the thread 'pcm'.

Nope, you probably use dmix plugin. This thread is only for management for 
shared device and has nothing to do with sample transfers.

						Jaroslav

-----
Jaroslav Kysela <perex@perex.cz>
Linux Kernel Sound Maintainer
ALSA Project, Red Hat, Inc.

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

* Re: XRUN happens too often.
  2008-04-10  7:59               ` Rong-Jhe
  2008-04-10  8:20                 ` Jaroslav Kysela
@ 2008-04-10  8:24                 ` Rong-Jhe
  1 sibling, 0 replies; 13+ messages in thread
From: Rong-Jhe @ 2008-04-10  8:24 UTC (permalink / raw)
  To: alsa-devel


> 
> I found that there will be a thread generated after calling snd_pcm_open().
> I use command 'ps' to check it.
> Due to this I guess snd_pcm_writei() only put the data into the buffer of 
the 
> thread 'pcm'.
> 
> This thread then schedules of mixes the audio data, and put it into the 
buffer 
> of ALSA driver.
> ALSA ringbuffer only belongs to ALSA library, and ALSA driver uses anoother 
> buffer in kernel.
> Thus, there must be a thread that can put the data in ALSA ringbuffer into 
the 
> buffer of ALSA driver.
> 

I found that snd_pcm_direct_server_create() in ALSA library will create a 
thread.
This resolves my problem that why ALSA library needn't use a daemon to mixing 
audio like other mixing server.

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

* Re: XRUN happens too often.
  2008-04-10  8:20                 ` Jaroslav Kysela
@ 2008-04-10 12:19                   ` Rong-Jhe
  0 siblings, 0 replies; 13+ messages in thread
From: Rong-Jhe @ 2008-04-10 12:19 UTC (permalink / raw)
  To: alsa-devel

Jaroslav Kysela <perex <at> perex.cz> writes:

> Nope, you probably use dmix plugin. This thread is only for management for 
> shared device and has nothing to do with sample transfers.
> 
> 						Jaroslav
> 

Sorry, I am confused with the mechanism of ALSA library.
I roughly viewed the implementation of snd_pcm_writei(). In my config, 
snd_pcm_writei() will call snd_pcm_mmap_writei().
In snd_pcm_mmap_writei(), the available space is checked, and will wait for 
available space if the pcm is in block mode and the space is not large enough.
Then snd_pcm_mmap_write_area() is called.
I think that snd_pcm_mmap_commit() do the work of put data into the buffer in 
user space.
Function snd_pcm_mmap_commit() shoud call snd_pcm_dmix_mmap_commit in my 
config.
I saw snd_pcm_dmix_start_timer() here, and snd_pcm_dmix_start_timer() calls 
ioctl().
I don't know which file in ALSA driver will receive this ioctl system call.
Does this function start something like timer, and this timer will put the 
buffer in user space into the buffer in kernel space automatically?
I can't understand this mechanism.
I am confused with the interaction between ALSA library and ALSA driver.
I think the mixing procedure is implemented in user space, and ALSA driver 
only put the mixed buffer from user space to the soundcard.
Am I right?

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

end of thread, other threads:[~2008-04-10 12:19 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-08 10:15 XRUN happens too often Rong-Jhe
2008-04-08 11:40 ` Rong-Jhe
2008-04-08 15:20   ` stan
2008-04-09 12:06     ` Rong-Jhe
2008-04-09 22:28       ` stan
2008-04-10  1:01         ` Lee Revell
2008-04-10  3:29           ` Rong-Jhe
2008-04-10  4:54             ` Lee Revell
2008-04-10  7:59               ` Rong-Jhe
2008-04-10  8:20                 ` Jaroslav Kysela
2008-04-10 12:19                   ` Rong-Jhe
2008-04-10  8:24                 ` Rong-Jhe
2008-04-10  6:41 ` 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.