Page 1 of 1

Interesting aspect of the crossfade function

Posted: Fri Apr 10, 2015 7:37 am
by Digital Larry
This morning I was double checking a crossfade block, and a phase invert block. As I often do, I checked this using a full amplitude WAV file and WOW did I not get what I expected.

I figured that on either extreme of the crossfade control I'd get the signal (though hard to tell what phase it is) and in the middle I'd get nothing because they'd totally cancel each other out. In the middle I actually got a half amplitude signal with tons of crossover distortion!

The crossfade starts by creating a difference signal between the two inputs. Well, what happens if you have a full amplitude signal and then take the difference of its negative? Yep, you just clipped off the top half of the waveform because x - (-x) = 2x!

So in general, if you are using a crossfade control, and get weird results, it might be preferable to put a -6dB volume cut (sof 0.5, 0) in front of one or both inputs.

Posted: Fri Apr 10, 2015 9:14 am
by frank
Yup, and that is why we get a tremolo type effect in the pitch shifter. Phase can cause signals to add or cancel as we cross fade between pointers.

Posted: Fri Apr 10, 2015 11:22 am
by Digital Larry
Yeah I just spent a pretty focused bit of time finishing the reverse engineering of the pitch shift for the FV-1 simulator in SpinCAD. Boy was that fun (not). But now it seems to sound pretty close to the FV-1 itself.

During the crossfade sections, components of your signal will either be in or out of phase with their copy half a buffer length away. It's really easy to see with a sine wave signal going in.

Posted: Sun Apr 19, 2015 7:44 am
by pharaohamps
That totally makes sense to me. Look at a crossfade as being like a mixer in a way, ideally you want to have both signals down 3dB at midpoint and 0dB / -inf dB at either end.

The typical mixer stage is this:

Code: Select all

rdax adcl,0.5	 
rdax adcr,0.5	;sum inputs to mono
wrax insig,1	;input sum register
Read the left input and scale to 1/2, then read the right input and scale to 1/2. Since 1/2 of adcl is still in the ACC, the second RDAX operation sums the two, then you just need to stash the resultant value to your desired location or use as-is.

The typical crossfade is this:

Code: Select all

RDAX	siga,-1	;read 'A' signal, with opposite sign
RDAX	sigb,1	;read 'B' signal, add to the A signal
MULX	xfade	;multiply by the xfade coefficient (pot derived)
RDAX	siga,1	;add back the A signal with correct sign
Note that the initial RDAC operations to read the two signals just invert the sign and do not scale. If you send big signals in here it's going to clip, period.

If there is a chance of getting overs / clipping, you can try this instead:

Code: Select all

RDAX	siga,-0.5	;read 'A' signal, with opposite sign
RDAX	sigb,0.5	;read 'B' signal, add to the A signal
MULX	xfade	;multiply by the xfade coefficient (pot derived)
RDAX	siga,0.5	;add back the A signal with correct sign
No extra operations needed. I'm assuming you're using SpinCAD here (hi, Gary!) so maybe put a checkbox in the block to allow for the 3dB cut on each side of the fade? Or sliders to determine how much cut for each side? Would save several instructions compared to dropping in a SOF block for two signals, not to mention the associated holding registers.

Posted: Sun Apr 19, 2015 9:07 am
by Digital Larry
Me? Use SpinCAD? :D :D

Thanks for your suggestion. I think a global scaling parameter is probably best since it really needs to match on all sides. It's a great idea!

Boom. It is done. Look for it in the next release!

Posted: Sun Apr 19, 2015 3:02 pm
by pharaohamps
Actually, it doesn't have to match on all sides but the two for the "A" signal need to be opposite and equal to cancel out properly. Do we REALLY need to have them separate? Nah. If you have to scale them separately you can either go in and hand-edit the code or use an SOF in front.

Thanks for adding that, I am a big fan of SpinCAD.

Posted: Sun Apr 19, 2015 5:00 pm
by Digital Larry
pharaohamps wrote:hand-edit the code
Please, NO! The humanity!
pharaohamps wrote:or use an SOF in front.
Almost as bad! OK OK you get your way! Sheeeesshh!!!