Interesting aspect of the crossfade function

Algorithm development and general DSP issues

Moderator: frank

Post Reply
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Interesting aspect of the crossfade function

Post 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.
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post 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.
Frank Thomson
Experimental Noize
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Post 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.
pharaohamps
Posts: 34
Joined: Thu Nov 09, 2006 6:58 am
Contact:

Post 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.
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Post 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!
pharaohamps
Posts: 34
Joined: Thu Nov 09, 2006 6:58 am
Contact:

Post 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.
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Post 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!!!
Post Reply