[alsa-devel] How to retrieve the final data being played by HW
I'm studying ALSA lib and trying to write a plugin that can perform AEC function. I have to retrieve the data being played and use it as reference. I've read pcm_dmix.c and found dmix just simply mixes data into HW mmap buffer (destination buffer). My problem is, there might be several dmix instances, which doesn't know if there is other dmix instance. So how can I know the mixed data is exactly the data being played. For example, the 1st instance had mixes the data into destination buffer, but 2nd instance haven't complete the mix operation. Would the data in destination buffer be playing by HW? Or there is some mechanism to guarantee the data will be played after all mix operation is done.
On Thu, Apr 29, 2010 at 05:15:38PM +0800, Yu Hang wrote:
For example, the 1st instance had mixes the data into destination buffer, but 2nd instance haven't complete the mix operation. Would the data in destination buffer be playing by HW? Or there is some mechanism to guarantee the data will be played after all mix operation is done.
You need to ensure that the user configures the plugin stack appropriately to ensure that your plugin is the last one that's run, you can't do this purely from within your plugin. Even if that's done you'd also need to rely on them not configuring any DSP in the hardware which would disrupt things.
On 4/29/2010 5:19 PM, Mark Brown wrote:
On Thu, Apr 29, 2010 at 05:15:38PM +0800, Yu Hang wrote:
For example, the 1st instance had mixes the data into destination buffer, but 2nd instance haven't complete the mix operation. Would the data in destination buffer be playing by HW? Or there is some mechanism to guarantee the data will be played after all mix operation is done.
You need to ensure that the user configures the plugin stack appropriately to ensure that your plugin is the last one that's run, you can't do this purely from within your plugin. Even if that's done you'd also need to rely on them not configuring any DSP in the hardware which would disrupt things.
From the pcm_dmix.c, dmix plugin must be followed by HW plugin. Which means I cannot insert my own plugin below dmix. Unless I patch pcm_dmix.c, I cannot retrieve the final data. Or I can patch pcm_hw.c in order to achieve my goal. Even if I patch pcm_hw.c, how can I know when the data is actually sent to HW? I have totally no idea about ALSA driver mechanism. A biggest question is, how alsa lib (in user space) knows the HW needs new data (it must happen by interrupt) and feed HW with new data.
On Thu, Apr 29, 2010 at 05:46:26PM +0800, Yu Hang wrote:
On 4/29/2010 5:19 PM, Mark Brown wrote:
You need to ensure that the user configures the plugin stack appropriately to ensure that your plugin is the last one that's run, you can't do this purely from within your plugin. Even if that's done you'd also need to rely on them not configuring any DSP in the hardware which would disrupt things.
From the pcm_dmix.c, dmix plugin must be followed by HW plugin. Which means I cannot insert my own plugin below dmix. Unless I patch pcm_dmix.c, I cannot retrieve the final data. Or I can patch pcm_hw.c in order to achieve my goal.
Well, you can't assume people are using dmix at all - most modern desktop systems use PulseAudio, and it's also getting more and more usage on embedded systems.
Even if I patch pcm_hw.c, how can I know when the data is actually sent to HW?
The information the driver gives you about where it's up to in the buffer and the latency will tell you this - PulseAudio is probably the most detailed example out there of this. Note that "actually sent to HW" can cover a multitude of things. There's the data that software can change, but there's also the potential for additional latency in buffers and DSP functionality before the audio that's actually being played.
I have totally no idea about ALSA driver mechanism. A biggest question is, how alsa lib (in user space) knows the HW needs new data (it must happen by interrupt) and feed HW with new data.
Most ALSA drivers continually process data from a ring buffer, with their progress through the ring buffer being updated either from interrupts generated by hardware or by polling from a timer. The driver tells userspace what region in the buffer is currently available for writing, and userspace tells the driver how much data has actually been written.
participants (2)
-
Mark Brown
-
Yu Hang