This is the bug/patch tracker for Rockbox. Click here for more information.
Quick links: Bugs · Patches · Rockbox frontpage
FS#11631 - Recording gains on Clip+ are very quiet, yet exhibit massive clipping
Attached to Project:
Rockbox
Opened by Kevin Puetz (puetzk) - Saturday, 18 September 2010, 08:42 GMT+2
Last edited by Michael Sevakis (MikeS) - Monday, 12 December 2011, 21:13 GMT+2
Opened by Kevin Puetz (puetzk) - Saturday, 18 September 2010, 08:42 GMT+2
Last edited by Michael Sevakis (MikeS) - Monday, 12 December 2011, 21:13 GMT+2
|
DetailsRecordings on Sansa Clip+ are very quiet, yet still exhibit heavy "clipping".
This is not normal digital "clip-to-limits", though; it's more like an integer overflow. This appears to be because of the way audiohw_set_recvol distributes gain betwen the mic preamp and the ADC; it is trying to keep the mic as quiet as possible, even if this requires overdrivingthe ADC (> -0dB gain). Adjusting the thresholds (clipp-gain.patch) so that it does not take the ADC above 0dB unless it has to eliminates this clipping (except for very high input gains, where it's probably unavoidable) |
This task depends upon
Closed by Michael Sevakis (MikeS)
Monday, 12 December 2011, 21:13 GMT+2
Reason for closing: Fixed
Additional comments about closing: Considering this resolved to be consistent with hardware operation.
Monday, 12 December 2011, 21:13 GMT+2
Reason for closing: Fixed
Additional comments about closing: Considering this resolved to be consistent with hardware operation.
It looks like the real root cause is that the register bit the code thinks turns off the AGC does something else on AS3543; it changes the mic circuit between differential and single-ended mode. Recording pink noise with steadily-increasing volume shows very clearly that we are still in some sort of automatic gain-control mode.
That would imply that the AS3543 doesn't really do "automatic gain control" like the previous ones did, it just attenuates the signal to <1Vpp (which can be used to accomplish the same thing; if it's turned up too loud, then it's automatically reduced to just loud enough).
So I think on the Clip+ (and presumably other AS3525v2), we are running the mic with too much supply voltage, and the limiter is functioning as AGC. Since that will almost always produce a signal near -0dB, it makes sense that an ADC gain that is positive will cause clipping. Do we know where the setting for AudioSet2.VMICS=0 (2.0V) came from?
That said, looking at the datasheet, it would appear that we do switch from differential to singled ended mode when recording because the AGC register was remapped. I'm not sure what the implications of that are.
RB recordings always max out at 12dBfs, regardless of what the gain is set to.
Thanks, but that build is older then r30209, which I believe fixes the problem. If you update to something post r30209, does the problem still occur?
I see exactly the same "integer overflow" problem on Clip+v2 with 3.9.1, forcing me to use recording gain of -3dB, resulting in typical recorded levels of -30dB. I've modified the Clip+ by removing the mic and bringing an external input into the high side mic connection. The input is live music (square dance), with external AGC before the Sansa, so dynamic range is moderate. As long as I keep the level there, I get excellent recordings.
With a private version I just built from r30883M (presumably including saratoga's fix) the integer overflow is very much more noticeable, even at lower levels than avoid the problem with 3.9.1.
I'm pretty motivated to get this running well. My targets (and only hardware) are Clip and Clip+; output is MP3 at 96Kb/sec 44.1KHz mono.
More homework to do - I haven't looked at the patch or diffed code to see the post r30209 change yet, and have only glanced at the datasheet so far.
I'll post back what I learn, but would be grateful for any other bits of intel about this from the guys that actually understand the code :)
Also, because of FS#12350 you should only use mono.
I didn't see/hear any in 391_+0db.wav.
I could see the same instances in a file recorded at +3db in mp3. All files above are from the distributed 3.9.1 image - I haven't tried rebuilding that from source yet.
The local builds I've done so far are from r30883M. In r30883_-3db.wav. I think I could see the artifact ~12sec, but the real issue is that it just sounds really bad.
My next steps are to rebuild 3.9.1 from source and play with it, then start looking at the code.
I have rebuilt 3.9.1 from source and it behaves just like the original image I downloaded (which is a good thing). That is, at Gain -3 I get recorded level around -30dB, but with no flaws.
I downloaded dailies latest (20111110) and oldest (20111014) and both exhibit the same very garbled, maybe "underwater" sounding distortion I heard with my private r30883 build.
I also put daily 20111110 on an unmodified Clip+ and recorded a little voice thru the mic. With Gain 0dB, I got a recording at -30dB with my voice garbled/burbly just like the music I'd put into the other recorder with the mic removed. I've attached a little clip of that.
This record quality is pretty unacceptable - but it's not in a released build. Sorry - I don't know protocol - should that be raised as a separate bug, or do we just fix it with this one?
But the very interesting thing is that I looked more closely at the places where the integer overflow occurs, and (with and without the patch) it's always around absolute level of +0.249. Then in one sample it jumps to -0.250. It looks like we're clearly just 2 bits shy of full scale. If we could pick those 2 bits up, the overflow would be at FS and nobody could complain about it.
Of course there's still whatever is broken in later builds to clean up.
To be clear, that was the problem I fixed after 3.9.1.
So how do we find what introduced the garble distortion?
I looked at the waveforms of the 1KHz recording and found some distortions. All looked like perhaps missing samples. I've attached a picture of one instance of it. I scanned through the recording by eye and found 15 consecutive "missing samples" or whatever they are. All were almost exactly 23ms apart. Does that offer any insight? Is there an interrupt at ~23ms that might be spending too much time in the service routine or something?
Since 391 meets all my needs (I think - haven't built yet for the V1 and V2 Clips I have, just for Clip+) except for the low record level, I hoped to be able to just scale the level up using that code base. I added just the static inline scalevolume() fix in pcm-as3525.c from r30209 to the 3.9.1 source. (I didn't add the #include pcm-internal.h.) While it scaled the level up just as expected, the recorded signal was again garbled/burbly. I tried shifting 1 bit instead of 2, and the signal was scaled up less (exactly as it should be), but the burbling remained.
I tried to run the same loop but do nothing, with *samples++ +=0;. Don't know if the compiler was smart enough to optimize that out, but the burbling was clearly not there. Of course level was quite low, as expected. Then I tried *samples +=1; *samples++ -=1;. That would take twice as long, but might fool the optimizer (if the optimizer was skipping the +=0.) Again no burble.
So unfortunately, it looks like there's something in the scalevolume() fix that causes the burbling to occur.
But that's awful simple (and fast) code. Any idea how it could cause trouble?
I hope some of this is helpful...
I have to suspect that we're changing something besides just samples. Are we certain what's being DMA'd in is purely raw data words with no other structure? Are we certain of the size of the loop? Is there any way the starting pointer dynamically changes so we're playing with the wrong buffer?
I you feel confident that it works please commit it, can't be any worse than current builds^^
After that, do the normal build procedure.
I would but I want to make sure noone's too attached to the DMA recording for some reason. I'm not nor do I think it's that important in the context of what must be accomplished.
FS#12428is gone and the waveform extends to 0dB. However the gain setting doesn't seem to work as intended, when turned down from 0dB it simply scales down the entire waveform. Here are two recordings of the same song played on guitar, one with gain set at 0dB the other set with gain at -12dB.http://www.box.com/s/0011b5r9jgu51uj1q8zf
http://www.box.com/s/cjmociaia1ztebe0ae5r
If you match the levels of the files in an audio editor you'll se that dynamic range is comparable, the file with lower set gain has slightly worse dynamic range due an increased DC offset.
Could you explain how it doesn't work as intended?
My point is that the expected behavior is that of the -12dB wave looking different to the 0dB wave reduced by -12dB in that the -12dB file has the peaks reaching higher levels. That's how my H120 behaves and makes for higher quality recordings.
>However the gain setting doesn't seem to work as intended, when turned down from 0dB it simply scales down the entire waveform.
I realize this was a poorly worded, obviously more is going on that pure scaling. Since I don't have knowledge about how the hardware and software works you may take this with a grain of salt:
The way it is now is as if the AGC "threshold" follows the gain setting rather than remaining at 0dB. Maybe the AGC would be better left disabled to avoid dynamic range issues? Mild clipping can be removed in audio software with good results.
I get similar waveforms regardless of whether I amplify the -12dB recording by +12dB or amplify the 0dB recording by -12dB. In either case I kill the DC. You won't get rid of it unless we add a DC blocker to recording where a hardware one isn't available since it's a hardware issue and not an uncommon one at that.
I still see what I'd expect to see with without serious anomaly. So far, the problem sounds outside the scope of recording on simple hardware.
Personally, I'd stick with the H120 if you want to record anything in any seriousness. :)
To be clear, waveform scaling and amplification are one and the same. How were you expecting them to be different?
guitar strumming gain -12dB - +12 dB Gain + DC Blocker.wav:
http://jhmikes.cleansoap.org/guitar%20strumming%20gain%20-12dB%20-%20%2B12%20dB%20Gain%20%2B%20DC%20Blocker.wav
guitar strumming gain 0dB - DC Blocker.wav:
http://jhmikes.cleansoap.org/guitar%20strumming%20gain%200dB%20-%20DC%20Blocker.wav
Current behaviour has -both- files looking like the black area after volume matching. I'd argue this is not the intended behaviour.
Though I'd love to see what a AGC user setting could do. ::)
There should be an as3514 block diagram available online if you have any questions about it.
Microphone Inputs
-3 gain pre-setting (28dB/34dB/40dB) with AGC
Could these be controlled via software?
We already do this.
>How this reflects reality I'm obviously not clear about, only reflects my experience with stand-alone hardware.
Honestly, if you're not going to take the time to understand whats going on, you probably should not be posting here. These long circular suggestions that we implement things we implemented years ago may save you the trouble of understanding whats going on, but they're a waste of everyone else's time.
Then I built for my other target - ClipV1 (maybe some V2s, but haven't tried that yet). Record level is good - as expected. But the recorded signal is too slow - low pitch and slower than real time. The effect is sample rate dependent: at 48K it was ~4.4% slow; at 44.1K ~3.4% slow; at 32K ~0.7% slow; at 24K correct within measurement uncertainty. (Measurement was from the leading edge of visually identifiable cycles in specific drum beats about 15 sec apart.)
Audibly, it sounded a little slow and low pitched. At 44.1K, twice in a 20 second sample the pitch went up noticeably for a little over a second. While I'm not saying this is what was happening, those short pitch increases could be consistent with generally not keeping up, but occasionally buffer alignment being just right so it could keep up for a little bit.
The Clip sounded OK (and timing was normal) with 3.10. Level, of course, was low.
A possible interpretation is that at least at these sample rates, we can't keep up without the DMA. Do we know whether funman's DMA implementation was driven by anything more urgent than staying consistent with the playback approach?
What I found was that 44.1kHz is accurate to about 0.167%. Earlier checks with test_sampr show some other hardware sample rates to be very inaccurate, with quite an audible pitch change.
What I also found was the presence duplicated samples very frequently in the waveform while recording through the clipv1's microphone a sinewave played on my computer. This isn't so much an indication that it can't keep up due to processor speed but with interrupt latency issues. One area that can disable interrupts for an extended time is the I2C driver. Possibly other interrupt callbacks spend an excessive amount of time. With DMA, the interrupts are less frequent so the overflow just happens far less often between the frames but would nonetheless still happen once in awhile.
The first thing I tried (because it was easy) was lowering the FIFO POP watermark (resulting in even MORE interrupts). Nonetheless, this got rid of the majority of the issue but not all of it. I can use FIQ for recording but this latency issue will still affect playback with an occasional 1-sample dropout between DMA frames.
Also, DMA channels should be prioritized to service audio first rather than SD.
Portal Player targets are slower (80MHz max, 30MHz normal), with a I2S input FIFO half the size of what's on AS3525 and do not suffer these problems. This AMS hardware is definitely fast enough to do it without a problem if latency is minded properly. It's fast enough that latency problems with audio should simply not exist.
Well, anyway, it turns out reducing latency is not the major part of the issue. I set audio-related stuff at the highest priority (first to be serviced in DMA for I2SOUT and highest priority in VIC for I2SIN) and most importantly kept track of whether a sample was saved or discarded across interrupts, which seem to have totally solved the issue. Will have a patch shortly.
I noticed Fuzev2 has some latency issues, with some dropped sample overflow, perhaps from the button routine which does alot of waiting. I'm thinking seriously that enabling nested IRQ to be a proper thing to do.
I rebuilt with your patch for both ClipV1 and Clip+. Both sounded fine, both with sine waves and music.
Thanks so much for the fix!