% Magnitude and Phase Hybridization Effect
% Original matlab code from DAFX chapter 8 pg 285
% This function cominbines three sounds with different combinations of
% their magnitudes and phases.  Options include combining magnitudes and
% phase or only the magnitudes or only the phases

function [sound_effect_out]=sound_magandphase_mush(x1,x2,x3,n1,WLen,w1,cr,ct)

%----- initializations -----
%These initializations create the vectors for the sound to be processed in
%Matlab.  
L = min(length(x1),length(x2));
x1 = [zeros(WLen, 1); x1; zeros(WLen-mod(L,n1),1)]/max(abs(x1));
x2 = [zeros(WLen, 1); x2; zeros(WLen-mod(L,n1),1)]/max(abs(x2));
x3 = [zeros(WLen,1); x3; zeros(WLen-mod(L,n1),1)]/max(abs(x3));
sound_effect_out = zeros(length(x1),1);

%---------------------------------------------
n2=n1; %Synthesis hop size
w2=w1;  %Synthesis window type
% ---------------------------------------------
in = 0;  %Start index for input
out = 0;  %Start index for output
pend = length(x1) - WLen; %End index

while in<pend
%Grain is widowed buffer of input sound multiplied by analysis window
grain1 = x1(in+1:in+WLen).* w1; 
grain2 = x2(in+1:in+WLen).* w1; 
grain3 = x3(in+1:in+WLen).*w1;
% ------------------------------------------
%fftshift for vectors swaps the left and right halves of the vector moving
%the zero frequency component to the centre of the array.
%Obtain FFT of the grain
f1 = fft(fftshift(grain1)); 
%Obtain the magnitude of the spectrum
r1 = abs(f1); 
%Obtain the phase of the spectrum
theta1 = angle(f1); 

f2 = fft(fftshift(grain2));
r2 = abs(f2);
theta2 = angle(f2);

f3 = fft(fftshift(grain3));
r3 = abs(f3);
theta3 = angle(f3);

%Options for combining the magnitudes of the input sounds
if cr==1;
    r = r1.*r2.*r3;
elseif cr==2;
    r = r1.*r2;
elseif cr==3;
    r = r2.*r3;
elseif cr==4;
    r = r1.*r3;
elseif cr==5;
    r = r1;
elseif cr==6;
    r = r2;
elseif cr==7;
    r = r3;
else
    error('Your selection is invalid');
end

%Options for combining the phases of the input sounds
if ct==1;  
    theta = theta1.*theta2.*theta3;
elseif ct==2;
    theta = theta1.*theta2;
elseif ct==3;
    theta = theta2.*theta3;
elseif ct==4;
    theta = theta1.*theta3;
elseif ct==5;
    theta = theta1;
elseif ct==6;
    theta = theta2;
elseif ct==7;
    theta = theta3;
else
    error('Your selection is invalid');
end
 
%Combines new magnitude and phase into one new output sound
ft = (r.*exp(1i*theta));  
%Output grain is the real part of the IFFT of the new output sound.
%Output grain is a buffer storing data of the new output sound multiplied
%by the synthesis window.
grain = fftshift(real(ifft(ft))).*w2;

%Output vector added to grain
sound_effect_out(out+1:out+WLen) = sound_effect_out(out+1:out+WLen) + grain;
in = in + n1;
out = out + n2;
end

%Output vectot is computed and normalised
sound_effect_out = sound_effect_out(WLen+1:WLen+L) / max(abs(sound_effect_out));

