Tunnelman,
No worries at all!
The CauseHere's the full scoop. First of all, I have to
apologize for not testing the fix I suggested more robustly. The fix has an error, which is that the 24 sample bits clocked in from the A to D chip are
signed data, not unsigned data. If you change the left shift to 7 bits instead of 8 (per the fix), that leaves the uppermost bit a zero which is fine for positive values but it makes negative values positive which messes up the sound considerably EXCEPT when the final gain is set to 100% (which is where I had it when testing; that's default initialization in most patches). Why does it sound fine at 100%? The gain system resource is actually a cut/boost stage (It really should have been configured to display 0% to 200% because that is what it really does, which is where all this clipping trouble probably started; more on that later below). Setting the gain at 100% actually multiplies the output signal by two, which is equivalent to a single bit shift to the left, which gets rid of the offending incorrect bit (assuming you're testing with an effect which causes no net gain change, which I was), so you only hear the nasty distortion when you
reduce the gain below "100%".
Two different ways to clipThere are two different ways to clip. One is to exceed the range of the input A to D which is 2V peak to peak. The second is to have have a net gain in the effect path which brings the output signal out of range.
If your guitar output runs so hot that it is clipping the input stage then no amount of post A/D processing will ever get the missing data back. The guitar needs to be turned down enough to avoid clipping the input.
Now, let's say you write an effect which has a gain of 400%, and your guitar puts out 2V peak to peak (full range). That effect will output a significantly clipped signal and no post-effect processing will restore the missing data. The solution is to write the effect to perform a gain reduction before processing.
Now, lets say you have an effect which has a gain of about 100% (most of the currently released effects), and your guitar is running full range, and you set the "Gain" system resource (the right most knob in all currently released patches) to "100%". That last gain stage actually runs 0 to 200% even though it displays as 0 to 100% (That was really a mistake on my part; I should have shown the range differently). So at a setting of 100% the gain stage is actually multiplying by
two, which
will cause the output to clip!. This is what is happening to you.
Two solutions you can use todayHere are two solutions you can use today:
1) Set the output gain knob to "50%". This will really give you a mathematical gain of "100%" (i.e. out=in), which generally will not clip the output as long as your input remains in range to begin with. The downside of this change is that you'd probably want to make it to all patches so that each patch loads with a 50% setting.
2) Modify the system gain stage so that it really does run "0 - 100%" (as displayed) instead of "0 - 200%" (as currently functioning). To do this, just comment out line 103 ("shl y,#1") of COYOTE1_Conduit_Engine.spin.
- Code: Select all
'Signed multiply y<32> = (x<16> * y<16>)
test x, sign_bit wz
if_nz neg x, x
shr x, #16
call #mult
'shl y, #1
if_nz neg y, y
The upside is that all current patches will now operate with a default output gain stage of 100% (which will match the displayed value when adjusting the knob). The downside is that you loose the capability to boost the output signal an extra 2x (6db) if needed (not such a big deal, really, since you can always turn up at the amp. It is handy sometimes to have the extra gain range when practicing through headphones.).
The long term solutionIn the next Workbench & OS release I'll either change the output gain to truly run 0-100% (as indicated on the display), or to run 0-200% with a 100% default in all patches and a proper display range of 0-200%.
What about dropping the gain at the input?Yes, it is still possible to drop your gain by 2x at the input processing stage, but that's generally not the best place to do it from a SNR (signal-to-noise ratio) standpoint. The fix above is better. If you still wanted to drop the gain at the input processing stage, you'd just have to add the line "sar in_data_XXXXXX,#1 " after each of the two existing "shl in_data_XXXXX,#8 " lines like this:
- Code: Select all
'Left justify incoming 24 bit sample
shl in_data_right,#8
sar in_data_right,#1
and
- Code: Select all
'Left justify incoming 24 bit sample
shl in_data_left,#8
sar in_data_left,#1
The SAR instruction performs an "Arithmatic" (i.e. signed) bit shift, which will ensure that the upper bit is maintained properly for the sign of the value.