[alsa-devel] arecord: does hardware or software throw away unused
My hardware is putting a stream of MAX_CHANNELS into memory, and firing the IRQs on my period boundary with respect to this full MAX_CHANNELS stream.
If I apply an arecord -c <MAX_CHANNELS-x> flag, essentially saying that I only want to capture less than the maximum number of channels, will arecord expect that the *hardware* will throw away the unused channel data, and the data placed into memory is a contiguous stream of only pertinent channels?
Or will arecord see the MAX_CHANNELS in my driver, and use its *software* to strip out the upper channels worth of data automatically for me?
For example, if I am capturing 2 channels of u8 data, and my dma regardless puts the data into memory as 11111111222222221111111122222222_IRQ_11111111222222221111111122222222. If I apply an "arecord -c 1 ...", and my DMA remains unchanged, will the resulting wavfile have 1111111111111111_IRQ_1111111111111111?
Thanks, Rob
Rob Nertney wrote:
My hardware is putting a stream of MAX_CHANNELS into memory, and firing the IRQs on my period boundary with respect to this full MAX_CHANNELS stream. [...] will arecord see the MAX_CHANNELS in my driver, and use its *software* to strip out the upper channels worth of data automatically for me?
Yes.
Regards, Clemens
Thanks for the quick reply.
I just changed my channels to half of MAX_CHANNELS, and when i play the resulting WAV file, my voice is super slow (50% slower, I'd wager) I ensured my MAX_PERIODS went up with a decrease in channels, but I can't tell what would cause the effect. Any thoughts?
On Fri, Sep 2, 2016 at 12:01 AM, Clemens Ladisch clemens@ladisch.de wrote:
Rob Nertney wrote:
My hardware is putting a stream of MAX_CHANNELS into memory, and firing
the
IRQs on my period boundary with respect to this full MAX_CHANNELS stream. [...] will arecord see the MAX_CHANNELS in my driver, and use its *software* to strip out the upper channels worth of data automatically for me?
Yes.
Regards, Clemens
Rob Nertney wrote:
I just changed my channels to half of MAX_CHANNELS, and when i play the resulting WAV file, my voice is super slow (50% slower, I'd wager)
This sounds like a bug in your driver.
Regards, Clemens
So the arecord (and aplay for this matter)'s pointer callback? The writing ALSA driver user guide says
*This callback is called when the PCM middle layer inquires the current hardware position on the buffer. The position must be returned in frames, ranging from 0 to buffer_size - 1. This is called usually from the buffer-update routine in the pcm middle layer, which is invoked when snd_pcm_period_elapsed() is called in the interrupt routine. Then the pcm middle layer updates the position and calculates the available space, and wakes up the sleeping poll threads, etc.*
"Returned in frames". Does this mean returned in MAX_CHANNELS frames?
On Fri, Sep 2, 2016 at 12:09 AM, Clemens Ladisch clemens@ladisch.de wrote:
Rob Nertney wrote:
I just changed my channels to half of MAX_CHANNELS, and when i play the
resulting WAV file, my voice is super slow (50% slower, I'd wager)
This sounds like a bug in your driver.
Regards, Clemens
Rob Nertney wrote:
"Returned in frames". Does this mean returned in MAX_CHANNELS frames?
One frames contains all channels. The number of channels was set with the hw_params callback, and will never be outside the constraints that your driver has provided.
Regards, Clemens
So right now my buffer is 32768, and I am filling the dma_area, firing an IRQ every 2048 Bytes, which aligns to 32 frames of 32b, 16ch data @ 16khz. When I don't specify a lower number of channels, it works as expected (at least the capture sounds correct). Less than 16, the capture goes too fast. If I define my hw_params like this, is it correct for multiple channels?
channels_min = 1 channels_max = 16 buffer_bytes_max = 32768 period_bytes_min = 32768/16 period_bytes_max = 32768/16 periods_min = 16 periods_max = 16
Everything is really associated around a 2048 Byte IRQ. The IRQ handler is simply snd_pcm_period_elapsed (again, called every BUF/16, or 2048 bytes); the pointer callback is the number of frames (as you mentioned, based upon max_channels) currently copied into dma_area. I can't identify where the speedup would come from when i specify lesser channels
Thanks, Rob
On Wed, Sep 14, 2016 at 3:29 AM, Clemens Ladisch clemens@ladisch.de wrote:
Rob Nertney wrote:
"Returned in frames". Does this mean returned in MAX_CHANNELS frames?
One frames contains all channels. The number of channels was set with the hw_params callback, and will never be outside the constraints that your driver has provided.
Regards, Clemens
Rob Nertney wrote:
If I define my hw_params like this, is it correct for multiple channels?
channels_min = 1 channels_max = 16
I don't know what the actual constraints of your hardware are.
buffer_bytes_max = 32768 period_bytes_min = 32768/16 period_bytes_max = 32768/16 periods_min = 16 periods_max = 16
Everything is really associated around a 2048 Byte IRQ.
Is that an actual constraint of your hardware?
Anyway, this will not work with, e.g., 15 channels; 60-byte frames do not fit into 32768 bytes.
Regards, Clemens
Hi Clemens,
I'm building the hardware, so I can technically do whatever I want. I didn't want to add more to the hardware if ALSA can handle this.
The hardware is spec-ed to *always* have 16 channels worth of data being written into DDR. I think this comes full-circle to my original question of whether arecord can filter out channels. It sounds like arecord can handle multiple channels, but its under the assumption that the hardware itself changes (in the pcm_open function) to only copy in the requested channels worth of data; i.e. arecord assumes that the data in dma_area is exactly as requested by arecord.
If it's -c10 channels worth of data requested, my hardware needs to change to capture only 10 channels, and throw away the last 6 before it writes it to DDR. Does that sound right?
Thanks, Rob
On Fri, Sep 16, 2016 at 12:26 AM, Clemens Ladisch clemens@ladisch.de wrote:
Rob Nertney wrote:
If I define my hw_params like this, is it correct for multiple channels?
channels_min = 1 channels_max = 16
I don't know what the actual constraints of your hardware are.
buffer_bytes_max = 32768 period_bytes_min = 32768/16 period_bytes_max = 32768/16 periods_min = 16 periods_max = 16
Everything is really associated around a 2048 Byte IRQ.
Is that an actual constraint of your hardware?
Anyway, this will not work with, e.g., 15 channels; 60-byte frames do not fit into 32768 bytes.
Regards, Clemens
Rob Nertney wrote:
I'm building the hardware, so I can technically do whatever I want. I didn't want to add more to the hardware if ALSA can handle this.
The hardware is spec-ed to *always* have 16 channels worth of data being written into DDR. I think this comes full-circle to my original question of whether arecord can filter out channels.
When the ALSA library automatically converts sample formats, it can also adjust the number of channels. (This does not happen if some program decides to use the "hw" device to bypass all conversions.)
It sounds like arecord can handle multiple channels, but its under the assumption that the hardware itself changes (in the pcm_open function) to only copy in the requested channels worth of data; i.e. arecord assumes that the data in dma_area is exactly as requested by arecord.
The ALSA kernel framework assumes that the snd_pcm_hw constraints correctly describe the capabilities of your hardware. Any conversions happen in userspace.
Your driver never sees what happens in userspace; the values to be set by the .hw_params callback are guaranteed to fit into your driver's constraints.
Regards, Clemens
Hi Clemens,
That is where my confusion was. When you said hw_params are only what the HW supports (makes sense :) ). Making minchan=maxchan, I can now record less than max channels.
Thanks for the help!
On Wed, Sep 21, 2016 at 12:01 AM, Clemens Ladisch clemens@ladisch.de wrote:
Rob Nertney wrote:
I'm building the hardware, so I can technically do whatever I want. I didn't want to add more to the hardware if ALSA can handle this.
The hardware is spec-ed to *always* have 16 channels worth of data being written into DDR. I think this comes full-circle to my original question
of
whether arecord can filter out channels.
When the ALSA library automatically converts sample formats, it can also adjust the number of channels. (This does not happen if some program decides to use the "hw" device to bypass all conversions.)
It sounds like arecord can handle multiple channels, but its under the assumption that the hardware itself changes (in the pcm_open function) to only copy in the requested channels worth of data; i.e. arecord assumes that the data in dma_area is exactly as requested by arecord.
The ALSA kernel framework assumes that the snd_pcm_hw constraints correctly describe the capabilities of your hardware. Any conversions happen in userspace.
Your driver never sees what happens in userspace; the values to be set by the .hw_params callback are guaranteed to fit into your driver's constraints.
Regards, Clemens
participants (2)
-
Clemens Ladisch
-
Rob Nertney