How to "morph" sounds

For this sort of mechanism, there are a number of things that might be desirable:

  • That it can be extended easily to incorporate a larger number of input signals.
  • That alternative fade-curves can be employed - linear cross-fading tends to leave a perceptual ‘hole in the middle’.
  • ftmorf is quite nice but this limits the source signals to oscillators as opposed to any audio signal.

Here is what I came up with to address these ideas. It’s a little like Thrifleganger’s method but you only need to create a single crossfade function. There are four shapes suggested for cross-fading curves, I think Hanning sounds quite smooth.

<CsoundSynthesizer>

<CsOptions>
-dm0 -n
</CsOptions>

<CsInstruments>

sr 		= 	44100
ksmps 	= 	16
nchnls 	= 	2
0dbfs	=	1
 
instr		1
 ; create any number of signals...
 a1		poscil	0.2,200	
 a2		poscil	0.2,400
 a3		poscil	0.2,600
 a4		poscil	0.2,800
 a5		poscil	0.2,1000
 
 ; window shape used for fade-in/fade-out
 iShape	ftgen		0,0,4097,20,2,1		; hanning
 ;iShape	ftgen		0,0,4097,9,0.5,1,0	; half-sine / equal-power
 ;iShape	ftgen		0,0,4097,7,0,2048,1,2048,0		; linear
 ;iShape	ftgen		0,0,4097,20,6,1		; gaussian

 ; crossfader. Should start at zero and can extend in integer steps for the number of signals to be mixed
 kFade  line		0, p3, 4			; 0 = first signal only, 0.5 = mix of first two, 1 = second signal only etc...
  
 ; crossfade between any number of signals, note the sequence of table index offsets decreasing in integer steps
 aOut	sum		a1 * tablei:k( (kFade + 1) *0.5 , iShape, 1), \
 				a2 * tablei:k( (kFade + 0) *0.5 , iShape, 1), \
 				a3 * tablei:k( (kFade - 1) *0.5 , iShape, 1), \
 				a4 * tablei:k( (kFade - 2) *0.5 , iShape, 1), \
 				a5 * tablei:k( (kFade - 3) *0.5 , iShape, 1)	
 
 		outs		aOut, aOut				; send audio to outputs
 
endin

</CsInstruments>

<CsScore>
i 1 0 7
</CsScore>

</CsoundSynthesizer>