function [vibrato_ammodL vibrato_ammodR rotary_speaker] = rotaryspeaker( modfreq, width, fc)
%[vibrato_ammodL vibrato_ammodR rotary_speaker] = rotaryspeaker( modfreq, width, fc)
%               
%   This function allows you to create a rotary loudspeaker
%   effect of an audio signal being sent to rotating horns
%   using vibrato, amplitude modulation and chorus effects.
%                               
%       modfreq = modulation frequency (best results between 1 and 5) 
%       width = width of vibrato (best results between 0.001 and 0.005) 
%       fc = carrier frequency (best results between 1 and 5)  
%                           
%   Example:
%       [vibrato_ammodL vibrato_ammodR rotary_speaker] = rotaryspeaker( 2, 0.001, 2)
%



[x,fs] = wavread('smoothpiano');%importing wave file and frequency of file used

%left side vibrato
ya_alt=0;
Delay=width; % basic delay of input sample in sec
DELAY=round(Delay*fs); % basic delay in # samples
WIDTH=round(width*fs); % modulation width in # samples
if WIDTH>DELAY 
  error('delay greater than basic delay !!!');
  return;
end

MODFREQ=modfreq/fs; % modulation frequency in # samples
LEN=length(x);        % # of samples in WAV-file
L=2+DELAY+WIDTH*2;    % length of the entire delay  
Delayline=zeros(L,1); % memory allocation for delay
yL=zeros(size(x));% memory allocation for output vector
for n=1:(LEN-1)
   M=MODFREQ;
   MOD=sin(M*2*pi*n); %creating modulating sine wave 
   TAP=1+DELAY+WIDTH*MOD;
   i=floor(TAP);
   frac=TAP-i;
   Delayline=[x(n);Delayline(1:L-1)]; 
   
   yL(n,1)=(Delayline(i+1)+(1-frac)*Delayline(i)-(1-frac)*ya_alt);  
   ya_alt=yL(n,1); %Allpass Interpolation
   
end  
   

%Amplitude modulation left side
%Creating amplitude modulation of the singal after the vibrato is added
n = length(yL); %Length of the Output Vector
c = (1:n) / fs; 
c = 2 * pi * fc * c; 
ampmodL = sin(c);
ampmodL = ampmodL';

vibrato_ammodL = yL .* ampmodL; %vibrato added with amplitude modulation
    
%Right side vibrato
ya_alt=0;
Delay=width; % basic delay of input sample in sec
DELAY=round(Delay*fs); % basic delay in # samples
WIDTH=round(width*fs); % modulation width in # samples
if WIDTH>DELAY 
  error('delay greater than basic delay !!!');
  return;
end
MODFREQ=modfreq/fs; % modulation frequency in # samples
LEN=length(x);        % # of samples in WAV-file
L=2+DELAY+WIDTH*2;    % length of the entire delay  
Delayline=zeros(L,1); % memory allocation for delay
yR=zeros(size(x));     % memory allocation for output vector
for n=1:(LEN-1)
   M=MODFREQ;
   MOD=-sin(M*2*pi*n); %creating modulating sine wave, Inverting sin wave of right signal
   TAP=1+DELAY+WIDTH*MOD;
   i=floor(TAP);
   frac=TAP-i;
   Delayline=[x(n);Delayline(1:L-1)]; 
   
   yR(n,1)=(Delayline(i+1)+(1-frac)*Delayline(i)-(1-frac)*ya_alt);  
   ya_alt=yR(n,1);%Allpass Interpolation
end
%Amplitude modulation left side
%Creating amplitude modulation of the singal after the vibrato is added
ampmodR = ampmodL .* -1;%inverting amplitude modulation of right signal

vibrato_ammodR = yR .* ampmodR; %vibrato added with amplitude modulation

rotary_speaker = [(vibrato_ammodR.*0.7)+vibrato_ammodL , (vibrato_ammodL.*0.7)+vibrato_ammodR];%create rotating stereo image
  
rotary_speaker = rotary_speaker./max(max(abs(rotary_speaker))); % normailise function

%chorus Left
%adding chorus effect to the vibrato and amplitude modulation
 ya_alt=0;
Delay=0.001; % basic delay of input sample in sec
DELAY=round(Delay*fs); % basic delay in # samples
WIDTH=round(0.001*fs); % modulation width in # samples
if WIDTH>DELAY 
  error('delay greater than basic delay !!!');
  return;
end
%MODFREQ=Modfreq/SAMPLERATE; % modulation frequency in # samples
LEN=length(vibrato_ammodL);        % # of samples in WAV-file
L=2+DELAY+WIDTH*2;    % length of the entire delay  
Delayline=zeros(L,1); % memory allocation for delay
y=zeros(size(vibrato_ammodL));     % memory allocation for output vector


noise = rand(length(rotary_speaker),1); %creating white noise, length of the whole sound
noise = (noise - 0.5).*2;

%implementing a low pass filter, 
cutoff = 15; %the white noise is only heard below this frequency

cutoffnorm = cutoff./(fs/2);

f = [0 cutoffnorm cutoffnorm+0.00002 1];
m = [1 1 0.0005 0];

[b, a] = yulewalk(12, f, m); %Low pass filter 

noise = filter(b,a, noise);

noise = noise./max(max(abs(noise))); % normailise noise

for l=1:(LEN-1)
%    M=MODFREQ;
   MOD=noise(l,1);
   TAP=1+DELAY+WIDTH*MOD;
   i=floor(TAP);
   frac=TAP-i;
   Delayline=[vibrato_ammodL(l);Delayline(1:L-1)]; 
   %---Allpass Interpolation------------------------------
   y(l,1)=(Delayline(i+1)+(1-frac)*Delayline(i)-(1-frac)*ya_alt);  
   ya_alt=y(l,1);
   
end

vibrato_ammodL = (y.*0.002) + (vibrato_ammodL.*0.998);%Adding chorus with left vibrato signal, amount can be changed

%chorus Right
%adding chorus effect to the vibrato and amplitude modulation
 ya_alt=0;
Delay=0.001; % basic delay of input sample in sec
DELAY=round(Delay*fs); % basic delay in # samples
WIDTH=round(0.001*fs); % modulation width in # samples
if WIDTH>DELAY 
  error('delay greater than basic delay !!!');
  return;
end
%MODFREQ=Modfreq/SAMPLERATE; % modulation frequency in # samples
LEN=length(vibrato_ammodL);        % # of samples in WAV-file
L=2+DELAY+WIDTH*2;    % length of the entire delay  
Delayline=zeros(L,1); % memory allocation for delay
y=zeros(size(vibrato_ammodL));     % memory allocation for output vector


noise = rand(length(rotary_speaker),1); %creating white noise, length of the whole sound
noise = (noise - 0.5).*2;

%implementing a low pass filter, the white noise is only heard below this
%frequency
cutoff = 15; %the white noise is only heard below this frequency

cutoffnorm = cutoff./(fs/2);

f = [0 cutoffnorm cutoffnorm+0.00002 1];
m = [1 1 0.0005 0];

[b, a] = yulewalk(12, f, m); %Low pass filter 

noise = filter(b,a, noise);

noise = noise./max(max(abs(noise))); % normailise noise

for l=1:(LEN-1)
%    M=MODFREQ;
   MOD=noise(l,1);
   TAP=1+DELAY+WIDTH*MOD;
   i=floor(TAP);
   frac=TAP-i;
   Delayline=[vibrato_ammodR(l);Delayline(1:L-1)]; 
   %---Allpass Interpolation------------------------------
   y(l,1)=(Delayline(i+1)+(1-frac)*Delayline(i)-(1-frac)*ya_alt);  
   ya_alt=y(l,1);
   
end

vibrato_ammodR = (y.*0.002) + (vibrato_ammodR.*0.998);%Adding chorus with right vibrato signal, amount can be changed

rotary_speaker = [(vibrato_ammodR.*0.7)+vibrato_ammodL , (vibrato_ammodL.*0.7)+vibrato_ammodR];%create rotating stereo image
  
rotary_speaker = rotary_speaker./max(max(abs(rotary_speaker))); % normailise function

wavwrite(rotary_speaker, fs, 'rotating_speaker_effect.wav'); % creating output WAV file

sound(rotary_speaker, fs); %play sound 
end

