All of lore.kernel.org
 help / color / mirror / Atom feed
* ALSA throwing buffers away?
@ 2010-11-23 16:36 Radivoje Jovanovic
  2010-11-23 17:03 ` Clemens Ladisch
  0 siblings, 1 reply; 5+ messages in thread
From: Radivoje Jovanovic @ 2010-11-23 16:36 UTC (permalink / raw)
  To: alsa-devel

Hello,
I am developing driver for a really simple hardware. Hardware has codec that
supports mono/stereo and the amplifier that supports only one speaker so the
driver has to be mono driver and the codec is setup to manage mono data. I
have setup ALSA with following parameters:

.info =            (SNDRV_PCM_INFO_NONINTERLEAVED |
                 SNDRV_PCM_INFO_BLOCK_TRANSFER |
                 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),

    .formats = SNDRV_PCM_FMTBIT_U16_LE |
           SNDRV_PCM_FMTBIT_U16_BE |
           SNDRV_PCM_FMTBIT_S16_LE |
           SNDRV_PCM_FMTBIT_S16_BE |
           SNDRV_PCM_FMTBIT_U8,
.channels_min = 1,
 .channels_max = 1,

Initially I was happy since sound started playing right away, but I noticed
that songs are skipping. I created buffers that collect statistics about
playback which is printed at the STOP trigger. The hardware is going through
ALSA circular buffer correctly, and ALSA is filling the buffer as the
hardware progresses, but after each buffer iteration ALSA skips the buffer
length of the data?! For example:
If buffer is .5 Mb ALSA will fill first .5Mb from the file into the buffer.
As the hardware is playing the sound ALSA fills the buffer starting 1.0 Mb
away from the begining of the file (the data from .5-1.0 Mb never makes it
to the buffer). This pattern repeats constantly to the end of the song. I
have tried SNDRV_PCM_INFO_INTERLEAVED with the same results (in this case
ALSA will not even try to play stereo files using my mono driver). The files
I tested are stereo and mono and they all behave the same. I am collecting
ALSA info in the snd_pcm_lib_write1 method in the pcm_lib.c file. I was
wondering if ALSA maybe deals with two circular buffers in the same time, or
if anybody has an idea what is going on here?

~cheers,
Ogi

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

* Re: ALSA throwing buffers away?
  2010-11-23 16:36 ALSA throwing buffers away? Radivoje Jovanovic
@ 2010-11-23 17:03 ` Clemens Ladisch
  2010-11-23 17:25   ` Radivoje Jovanovic
  0 siblings, 1 reply; 5+ messages in thread
From: Clemens Ladisch @ 2010-11-23 17:03 UTC (permalink / raw)
  To: Radivoje Jovanovic; +Cc: alsa-devel

Radivoje Jovanovic wrote:
> I am developing driver for a really simple hardware. Hardware has codec that
> supports mono/stereo and the amplifier that supports only one speaker so the
> driver has to be mono driver and the codec is setup to manage mono data. I
> have setup ALSA with following parameters:
> 
> .info =            (SNDRV_PCM_INFO_NONINTERLEAVED |

Better use SNDRV_PCM_INFO_INTERLEAVED; this is the format used by almost
all (stereo) sound cards, and so it is expected even for mono files
(where there actually isn't any difference).

> after each buffer iteration ALSA skips the buffer length of the data?!

This might be a problem with the reporting of the DMA pointer.

Please explain (or show) how your DMA works and how the pointer callback
is implemented.

> I have tried SNDRV_PCM_INFO_INTERLEAVED with the same results (in this
> case ALSA will not even try to play stereo files using my mono driver).

When using the "default" or "plughw" device, alsa-lib will automatically
convert the sample format.


Regards,
Clemens

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

* Re: ALSA throwing buffers away?
  2010-11-23 17:03 ` Clemens Ladisch
@ 2010-11-23 17:25   ` Radivoje Jovanovic
  2010-11-23 17:40     ` Clemens Ladisch
  0 siblings, 1 reply; 5+ messages in thread
From: Radivoje Jovanovic @ 2010-11-23 17:25 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

>
> Radivoje Jovanovic wrote:
> > I am developing driver for a really simple hardware. Hardware has codec
> that
> > supports mono/stereo and the amplifier that supports only one speaker so
> the
> > driver has to be mono driver and the codec is setup to manage mono data.
> I
> > have setup ALSA with following parameters:
> >
> > .info =            (SNDRV_PCM_INFO_NONINTERLEAVED |
>
> > Better use SNDRV_PCM_INFO_INTERLEAVED; this is the format used by almost
> > all (stereo) sound cards, and so it is expected even for mono files
> > (where there actually isn't any difference).
>

I am worried about this approach since if I want to play stereo sound  I
would have to increase .channels_max = 2, since if I keep it to 1 ALSA will
report that hw configuration does not match and it will not play stereo at
all. If I increase .channels_max=2 am I going to get only L or R channel for
my mono therefore I will be throwing one channel away?

>

> > after each buffer iteration ALSA skips the buffer length of the data?!
>
> > This might be a problem with the reporting of the DMA pointer.
>
> > Please explain (or show) how your DMA works and how the pointer callback
> > is implemented.
>

       Here is my pointer callback:

     offset=READ_REG16(AUDIO_
CONFIG_DMA_CUR_ADDR_HIGH))<<16) | READ_REG16(AUDIO_CONFIG_DMA_CUR_ADDR_LOW);

    offset = offset - substream->runtime->dma_addr;

    if (offset >= runtime->buffer_size)
        offset = 0;
    return offset;

I am also collecting the data in each interrupt routine from the hardware:

trip:9dc04000 next_trip:9dc08000 current_DMA_Location:9dc04000
ALSA reports from snd_pcm_lib_write1 that is filling the buffer from
0-16384. The first byte of the data ALSA fills is buffer away from where it
should be which is wrong.

trip:9dc08000 next_trip:9dc0c000 current_DMA_Location:9dc08000
ALSA reports from snd_pcm_lib_write1 that is filling the buffer from 16384 -
2*16384. The first byte of the data is exactly 16384 away from the first
byte of previous fill which is 100% correct.

trip:9dc0c000 next_trip:9dc10000  current_DMA_Location:9dc0c000
ALSA reports from snd_pcm_lib_write1 that is filling the buffer from 2*16384
- 3*16384. The first byte of the data is exactly 16384 away from the first
byte of previous fill which is 100% correct.

trip:9dc10000 next_trip:9dc14000 current_DMA_Location:9dc10000
ALSA reports that is filling the buffer from 3*16384 - 4*16384. The first
byte of the data is exactly 16384 away from the first byte of previous fill
which is 100% correct.

trip:9dc14000 next_trip:9dc18000 current_DMA_Location:9dc14000
ALSA reports from snd_pcm_lib_write1 that is filling the buffer from 4*16384
- 5*16384. The first byte of the data is exactly 16384 away from the first
byte of previous fill which is 100% correct.

and this continues to the end of the buffer like this. The buffer size is
524288, period size is 16384 and the interrupts are generated every period
size. All of the info has the jiffies time stamp as well. Out of here I can
see that the hardware is following the buffer correctly and that ALSA is
correctly filling the buffer, but with wrong data.

~cheers,
Ogi


On Tue, Nov 23, 2010 at 9:03 AM, Clemens Ladisch <clemens@ladisch.de> wrote:

> Radivoje Jovanovic wrote:
> > I am developing driver for a really simple hardware. Hardware has codec
> that
> > supports mono/stereo and the amplifier that supports only one speaker so
> the
> > driver has to be mono driver and the codec is setup to manage mono data.
> I
> > have setup ALSA with following parameters:
> >
> > .info =            (SNDRV_PCM_INFO_NONINTERLEAVED |
>
> Better use SNDRV_PCM_INFO_INTERLEAVED; this is the format used by almost
> all (stereo) sound cards, and so it is expected even for mono files
> (where there actually isn't any difference).
>
> > after each buffer iteration ALSA skips the buffer length of the data?!
>
> This might be a problem with the reporting of the DMA pointer.
>
> Please explain (or show) how your DMA works and how the pointer callback
> is implemented.
>
> > I have tried SNDRV_PCM_INFO_INTERLEAVED with the same results (in this
> > case ALSA will not even try to play stereo files using my mono driver).
>
> When using the "default" or "plughw" device, alsa-lib will automatically
> convert the sample format.
>
>
> Regards,
> Clemens
>

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

* Re: ALSA throwing buffers away?
  2010-11-23 17:25   ` Radivoje Jovanovic
@ 2010-11-23 17:40     ` Clemens Ladisch
  2010-11-23 17:51       ` Radivoje Jovanovic
  0 siblings, 1 reply; 5+ messages in thread
From: Clemens Ladisch @ 2010-11-23 17:40 UTC (permalink / raw)
  To: Radivoje Jovanovic; +Cc: alsa-devel

Radivoje Jovanovic wrote:
> > Radivoje Jovanovic wrote:
> > > I am developing driver for a really simple hardware. Hardware has codec that
> > > supports mono/stereo and the amplifier that supports only one speaker so the
> > > driver has to be mono driver and the codec is setup to manage mono data. I
> > > have setup ALSA with following parameters:
> > >
> > > .info =            (SNDRV_PCM_INFO_NONINTERLEAVED |
> >
> > Better use SNDRV_PCM_INFO_INTERLEAVED; this is the format used by almost
> > all (stereo) sound cards, and so it is expected even for mono files
> > (where there actually isn't any difference).
> 
> I am worried about this approach since if I want to play stereo sound  I
> would have to increase .channels_max = 2,

No, ALSA can automatically convert the sample format.

> Here is my pointer callback:
> 
> offset=READ_REG16(AUDIO_CONFIG_DMA_CUR_ADDR_HIGH))<<16) | READ_REG16(AUDIO_CONFIG_DMA_CUR_ADDR_LOW);
> 
> offset = offset - substream->runtime->dma_addr;

This offset looks as if it is in bytes, but you have to return a value
measured in frames.  Use bytes_to_frames().

>     if (offset >= runtime->buffer_size)
>         offset = 0;

Remove this check; the ALSA framework already checks this and outputs
debugging info if this happens.


Regards,
Clemens

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

* Re: ALSA throwing buffers away?
  2010-11-23 17:40     ` Clemens Ladisch
@ 2010-11-23 17:51       ` Radivoje Jovanovic
  0 siblings, 0 replies; 5+ messages in thread
From: Radivoje Jovanovic @ 2010-11-23 17:51 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel

I have changed the pointer callback as you suggest.
Unfortunately, the result is still the same. Still the buffer filling is
skipping to fill all the data correctly. I am using Advanced Linux Sound
Architecture Driver Version 1.0.21.
~cheers,
Ogi

On Tue, Nov 23, 2010 at 9:40 AM, Clemens Ladisch <clemens@ladisch.de> wrote:

> Radivoje Jovanovic wrote:
> > > Radivoje Jovanovic wrote:
> > > > I am developing driver for a really simple hardware. Hardware has
> codec that
> > > > supports mono/stereo and the amplifier that supports only one speaker
> so the
> > > > driver has to be mono driver and the codec is setup to manage mono
> data. I
> > > > have setup ALSA with following parameters:
> > > >
> > > > .info =            (SNDRV_PCM_INFO_NONINTERLEAVED |
> > >
> > > Better use SNDRV_PCM_INFO_INTERLEAVED; this is the format used by
> almost
> > > all (stereo) sound cards, and so it is expected even for mono files
> > > (where there actually isn't any difference).
> >
> > I am worried about this approach since if I want to play stereo sound  I
> > would have to increase .channels_max = 2,
>
> No, ALSA can automatically convert the sample format.
>
> > Here is my pointer callback:
> >
> > offset=READ_REG16(AUDIO_CONFIG_DMA_CUR_ADDR_HIGH))<<16) |
> READ_REG16(AUDIO_CONFIG_DMA_CUR_ADDR_LOW);
> >
> > offset = offset - substream->runtime->dma_addr;
>
> This offset looks as if it is in bytes, but you have to return a value
> measured in frames.  Use bytes_to_frames().
>
> >     if (offset >= runtime->buffer_size)
> >         offset = 0;
>
> Remove this check; the ALSA framework already checks this and outputs
> debugging info if this happens.
>
>
> Regards,
> Clemens
>

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

end of thread, other threads:[~2010-11-23 17:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-23 16:36 ALSA throwing buffers away? Radivoje Jovanovic
2010-11-23 17:03 ` Clemens Ladisch
2010-11-23 17:25   ` Radivoje Jovanovic
2010-11-23 17:40     ` Clemens Ladisch
2010-11-23 17:51       ` Radivoje Jovanovic

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.