[alsa-devel] Pops, Clicks on Capture w/ S/PDIF, Cirrus Logic CS4207, HDA
Hello, I have a custom platform with a Cirrus Logic CS4207 connected to an HDA bus of a Intel US15W & Atom processor. I'm trying to capture audio from the S/PDIF input of the CS4207 and getting pops & clicks. I'm not sure if there is another platform out there that utilizes the S/PDIF input of this chip so this might be new although usage of US15W shouldn't be anything new.
Software-wise I'm running: Moblin release 2.1 Advanced Linux Sound Architecture Driver Version 1.0.20. 2.6.31.6-17.10.moblin2-custom - The kernel is built to include a back ported version of the 2.6.32 Cirrus Logic patch for HDA. I guess we backported a checkin from the nearest stable kernel release. We had to do a couple of things to get it to work like comment a line in the driver so that it ignores the digital mic input as it seems the driver only supported one digital input and during the parsing the private data (NID and such) were getting clobbered when the DMIC node is parsed. As a result the capture was using the wrong node. position_fix=1 had to be applied also because there was a repeating audio issue.
So now we're getting some audio but it comes with pops and clicks when we try to capture. An analysis of the captured stream shows there are corruptions of the data that are 8192 frames apart which I believe are the 4096 frame period boundaries (although tough to know for sure). When the corruption occurs there seems to be 5 to 7 frames that are screwed up. Also worth noting: these same exact samples appear in the stream at a prior location so I think its old buffer data. My guess is that we're reading the buffer before the "writer" was done writing it.
I've tried to mess around with the buffer size & period size (although buff was always == per*4); tried mmap; I also tried messing around with the bdl_pos_adj option in the driver. It sounded like maybe this was most likely to solve the problem. But that didn't have any effect. So I started studying the code and realized there was going to be some learning curve here so I was hoping someone could point me in the right direction to help resolve this.
Thank you! Dave Z.
Here are my capture settings:
Recording raw data 'test.raw' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo Hardware PCM card 0 'HDA Intel MID' device 1 subdevice 0 Its setup is: stream : CAPTURE access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 16 buffer_size : 16384 period_size : 4096 period_time : 85333 tstamp_mode : NONE period_step : 1 avail_min : 4096 period_event : 0 start_threshold : 1 stop_threshold : 16384 silence_threshold: 0 silence_size : 0 boundary : 1073741824 appl_ptr : 0 hw_ptr : 0
Dave Zielinski wrote:
... So now we're getting some audio but it comes with pops and clicks when we try to capture. An analysis of the captured stream shows there are corruptions of the data that are 8192 frames apart which I believe are the 4096 frame period boundaries (although tough to know for sure). When the corruption occurs there seems to be 5 to 7 frames that are screwed up. Also worth noting: these same exact samples appear in the stream at a prior location so I think its old buffer data.
How far away is that prior location; exactly buffer_size?
If not, this looks like a bug in the CS4207's RX sample rate converter. Try disabling it by setting bit 6 in the S/PDIF interface control register (insert "coef |= 0x0040;" in the init_digital function).
Regards, Clemens
Clemens, Yes prior location is exactly 1 buffer_size! - which is this case was 16384. But what does that mean?
Also, I tried inserting 'coef |= 0x0040' and ran a 'arecord | aplay' and it sounded like white-noise. Although I am using a Sine wave generator to troubleshoot this and it sounded like changing the frequency audibly affect it a little, so it's not pure noise. But anyway it sounds like this is a different problem. I would not expect this to be a freq conversion problem as I'm putting in 48kHz and reading as 48kHz. Also I can put in 44.1kHz and read out 48kHz and everything seems to work the same.
Do you have any other ideas for things the check? In the meantime will be studying the code in the meantime to try and get my arms around how buffers are getting transferred from the hardware to kernel-space and kernel-space to user-land. I currently don't understand this.
Thanks for your response, Dave Z.
-----Original Message----- From: Clemens Ladisch [mailto:clemens@ladisch.de] Sent: Thursday, August 12, 2010 1:55 AM To: Dave Zielinski Cc: alsa-devel@alsa-project.org Subject: Re: [alsa-devel] Pops, Clicks on Capture w/ S/PDIF, Cirrus Logic CS4207, HDA
Dave Zielinski wrote:
... So now we're getting some audio but it comes with pops and clicks when we try to capture. An analysis of the captured stream shows there are corruptions of the data that are 8192 frames apart which I believe are the 4096 frame period boundaries (although tough to know for sure). When the corruption occurs there seems to be 5 to 7 frames that are screwed up. Also worth noting: these same exact samples appear in the stream at a prior location so I think its old buffer data.
How far away is that prior location; exactly buffer_size?
If not, this looks like a bug in the CS4207's RX sample rate converter. Try disabling it by setting bit 6 in the S/PDIF interface control register (insert "coef |= 0x0040;" in the init_digital function).
Regards, Clemens
Dave Zielinski wrote:
Yes prior location is exactly 1 buffer_size! - which is this case was 16384. But what does that mean?
It means that the controller did not actually write to that part of the buffer before it updated the buffer pointer. This appears to be a HDA controller bug which must be worked around in the controller driver.
Regards, Clemens
participants (2)
-
Clemens Ladisch
-
Dave Zielinski