* DMA buffer alignment
@ 2014-12-04 15:54 Carlo Caione
2014-12-04 16:20 ` Clemens Ladisch
2014-12-05 2:23 ` Raymond Yau
0 siblings, 2 replies; 5+ messages in thread
From: Carlo Caione @ 2014-12-04 15:54 UTC (permalink / raw)
To: alsa-devel
Hi,
I'm working with a SoC sound hw that requires that all the data
written into the DMA memory is aligned a 64 byte boundary. Actually
the alignment is required since the format of the data into the DMA
memory is (for a 2 channel 16bit audio): 16 samples for the left
channel followed by 16 samples for the right channel. If I try to
write anything that is not aligned to the 64 bytes I got audio
corruption (high pitched noise).
Several user-space programs (like aplay) work well with my hw, since
the buffer sent from the user-space is always (padded) of period-size
bytes, that is aligned to my 64 bytes boundary. Others (like
speaker-test) are not working because sometimes they snd_pcm_writei()
a buffer that is not multiple of 64 bytes. In general every time I
write into the DMA area a buffer that is not aligned, my hw pointer is
not aligned anymore with the 64 bytes and the noise starts.
IIUC it is not possible to force the user-space programs to send
buffers with a fixed size so the problem should be solved in
kernel-space (am I wrong on this point?).
Any suggestion on how to tackle this problem?
Thanks,
--
Carlo Caione
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: DMA buffer alignment
2014-12-04 15:54 DMA buffer alignment Carlo Caione
@ 2014-12-04 16:20 ` Clemens Ladisch
2014-12-05 1:04 ` Carlo Caione
2014-12-05 2:23 ` Raymond Yau
1 sibling, 1 reply; 5+ messages in thread
From: Clemens Ladisch @ 2014-12-04 16:20 UTC (permalink / raw)
To: Carlo Caione, alsa-devel
Carlo Caione wrote:
> Several user-space programs (like aplay) work well with my hw, since
> the buffer sent from the user-space is always (padded) of period-size
> bytes, that is aligned to my 64 bytes boundary. Others (like
> speaker-test) are not working because sometimes they snd_pcm_writei()
> a buffer that is not multiple of 64 bytes.
When a program writes two chunks of 32 bytes each, the final contents of
the memory are the same. So what exactly is the problem?
Regards,
Clemens
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: DMA buffer alignment
2014-12-04 16:20 ` Clemens Ladisch
@ 2014-12-05 1:04 ` Carlo Caione
2014-12-05 11:34 ` Clemens Ladisch
0 siblings, 1 reply; 5+ messages in thread
From: Carlo Caione @ 2014-12-05 1:04 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel
On Thu, Dec 4, 2014 at 5:20 PM, Clemens Ladisch <clemens@ladisch.de> wrote:
> Carlo Caione wrote:
>> Several user-space programs (like aplay) work well with my hw, since
>> the buffer sent from the user-space is always (padded) of period-size
>> bytes, that is aligned to my 64 bytes boundary. Others (like
>> speaker-test) are not working because sometimes they snd_pcm_writei()
>> a buffer that is not multiple of 64 bytes.
>
> When a program writes two chunks of 32 bytes each, the final contents of
> the memory are the same. So what exactly is the problem?
Hi Clemens,
let's say that our application sends uning snd_pcm_writei() a buffer
that is exactly 64 bytes and that our hwoff (appl_ofs) is pointing to
a memory location 0 in the DMA area.
When this buffer is taken from the SoC sound driver, the .copy
callback writes this buffer as follow: 32 bytes (left channel) to
memory locations from *hwoff to *hwoff+31, and 32 bytes (right
channel) for *hwoff+32 to *hwoff+63.
Problem is when my buffer is not multiple of 64 bytes, for example if
the buffer size is < 64. If I receive a buffer of lenght 32 byte than
my DMA memory is filled as follows: 16 bytes from *hwoff to *hwoff+15
and 16 bytes from *hwoff+32 to *hwoff+47, leaving 32 bytes in the
block not initialized. My hardware is always expecting to read a block
of data (64 byte) for *hwoff to *hwoff+63 and it actually does,
reading rubbish from the memory locations not initialized.
Even worst my hw requires that the hw pointer is always aligned to 64
bytes and now my new hw pointer is at *hwoff+32 that is not aligned on
the boundary.
In some way I should always guarantee that the size of the buffer
passed to my .copy callback is multiple of 64 bytes.
I hope this clarifies a bit,
--
Carlo Caione
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: DMA buffer alignment
2014-12-05 1:04 ` Carlo Caione
@ 2014-12-05 11:34 ` Clemens Ladisch
0 siblings, 0 replies; 5+ messages in thread
From: Clemens Ladisch @ 2014-12-05 11:34 UTC (permalink / raw)
To: Carlo Caione; +Cc: alsa-devel
Carlo Caione wrote:
> let's say that our application sends uning snd_pcm_writei() a buffer
> that is exactly 64 bytes and that our hwoff (appl_ofs)
The hardware and the software (appl) pointers are independent.
> is pointing to a memory location 0 in the DMA area.
> When this buffer is taken from the SoC sound driver, the .copy
> callback writes this buffer as follow: 32 bytes (left channel) to
> memory locations from *hwoff to *hwoff+31, and 32 bytes (right
> channel) for *hwoff+32 to *hwoff+63.
> Problem is when my buffer is not multiple of 64 bytes, for example if
> the buffer size is < 64. If I receive a buffer of lenght 32 byte than
> my DMA memory is filled as follows: 16 bytes from *hwoff to *hwoff+15
> and 16 bytes from *hwoff+32 to *hwoff+47, leaving 32 bytes in the
> block not initialized.
These bytes are written later. And if they are not written fast enough,
you get an underrun. This is no difference from any other sound card.
> In some way I should always guarantee that the size of the buffer
> passed to my .copy callback is multiple of 64 bytes.
The .copy callback just copies samples to memory; this is possible
with any alignment.
The DMA runs asynchronously, and uses its own pointer.
Regards,
Clemens
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: DMA buffer alignment
2014-12-04 15:54 DMA buffer alignment Carlo Caione
2014-12-04 16:20 ` Clemens Ladisch
@ 2014-12-05 2:23 ` Raymond Yau
1 sibling, 0 replies; 5+ messages in thread
From: Raymond Yau @ 2014-12-05 2:23 UTC (permalink / raw)
To: Carlo Caione; +Cc: ALSA Development Mailing List
> Hi,
> I'm working with a SoC sound hw that requires that all the data
> written into the DMA memory is aligned a 64 byte boundary. Actually
> the alignment is required since the format of the data into the DMA
> memory is (for a 2 channel 16bit audio): 16 samples for the left
> channel followed by 16 samples for the right channel.
Do you mean the sound card only support non interleaved mode ?
>If I try to
> write anything that is not aligned to the 64 bytes I got audio
> corruption (high pitched noise).
> Several user-space programs (like aplay) work well with my hw, since
> the buffer sent from the user-space is always (padded) of period-size
> bytes, that is aligned to my 64 bytes boundary. Others (like
> speaker-test) are not working because sometimes they snd_pcm_writei()
> a buffer that is not multiple of 64 bytes. In general every time I
> write into the DMA area a buffer that is not aligned, my hw pointer is
> not aligned anymore with the 64 bytes and the noise starts.
You need to add constraint to restrict period bytes to 64
enum dma_residue_granularity {
DMA_RESIDUE_GRANULARITY_DESCRIPTOR = 0,
DMA_RESIDUE_GRANULARITY_SEGMENT = 1,
DMA_RESIDUE_GRANULARITY_BURST = 2,
};
Can it report DMA_RESIDUE_GRANULARITY_SEGMENT or
DMA_RESIDUE_GRANULARITY_BURST ?
>
> IIUC it is not possible to force the user-space programs to send
> buffers with a fixed size so the problem should be solved in
> kernel-space (am I wrong on this point?).
> Any suggestion on how to tackle this problem?
>
pulseaudio seem not support non interleaved mode ?
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-12-05 11:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-04 15:54 DMA buffer alignment Carlo Caione
2014-12-04 16:20 ` Clemens Ladisch
2014-12-05 1:04 ` Carlo Caione
2014-12-05 11:34 ` Clemens Ladisch
2014-12-05 2:23 ` Raymond Yau
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.