%granulationSpat4
%Use this script to set all the input parameters for the granulation
%effect. It is recommended you run each section individually. The effect is
%often quick to evaluate, however, if you are using very high numbers of
%grains (in the order or millions) be prepared to wait a little longer.
clear;
[x,fs] = audioread ('ladder pianodualosc.wav');%loads the audio signal to which the effect will be applied.
                                         %Type the filename inside the parantheses eg [x,fs]=audioread('example.wav');
channelsIN = 2;%is input mono or stereo?
                                                 %1; = mono 
                                                 %2; = stereo

%%      User input                                           

Extraction_length = 10      % in percentage from input signal
startposition = 10         % distance from start of input in % of input signal
Read_Type = 0;              %There are 4 options available for how grains are selected from the input file:
                            %0; = Fixed from Extraction_length
                            %1; = Forward sequential through the Extraction_length
                            %2; = Backwards sequential through the Extraction_length
                            %3; = Selected randomly from Extraction_length
step = 10;                  %reading extraction steps in samples
stepspeed = 20;             % value in %, with 0=min 100 = max
Lout = 2000;                %Lout in ms sets the length of the graunlated output file 
                            
                           
                
Grsize_ms = 100;                  %size of grain in ms
density_Hz = 20;                %in Hz (grains/second) output desnity
                            %recommended range: min= to max=

            
W = 0.9; %Fade In/Out Length as Percentage of grain where 1 = 100%. 
        %Default window type is tapered cosine (tukey) window, however this
        %can be altered quite easily by editing the grain.m function.
        %Window type will affect the spectral content of output signal.

%SPAT inputs
choutput = 2;       % number of channels to output
GDmax = 110         % sets a max Grsize for channels variation
                    % if input is same as Grsize, no variation
GDmin = 90         %sets a min Grsize for channels variation
                    % if input is same as Grsize, no variation
density_var = 2;   %0 to 100, with 0 is no variation...100 is max variation

env = 2;            %Amplitude envelope over the length of the output signal. There are 4 options here:
                                    %1; = random amplitude coefficient for each grain
                                    %2; = gaussian (bell shape) envelope over length of output signal
                                    %3; = crescendo (amplitude increasing)over length of output signal
                                    %4; = diminuendo (amplitude decreasing)over length of output signal
                                    %5; = no envelope is applied

%FX inputs
reverb= 0;          % reverb time in ms
                    % 0 = no reverb
cutoff_freq= 15000;     % cutoff in Hz applies Lowpass FIR filtering
                    % 0 = no filtering
        
y_window =0.2;      %tukeywin to output signal

%% processing inputs
% GDmax = round(fs*(GDmax/1000));%convert milliseconds to samples
% GDmin = round(fs*(GDmin/1000));%convert milliseconds to samples
reverb=reverb/1000*fs; %reverb time in samples
density_max = floor(density_Hz+density_var/100*density_Hz);
density_min = floor(density_Hz-density_var/100*density_Hz);
if density_min==0;
    density_min=1;
else
    density_min=density_min;
end


%% calling function
%[Y] = grainsynthSpat4 (x,fs,Grsize_ms,Lout,channelsIN,Read_Type,W,env,Extraction_length,startposition,density,stepspeed,step)
density_r=density_Hz;
for ch =1:1:choutput
    Y(ch,:) = grainsynthSpat4 (x,fs,Grsize_ms,Lout,channelsIN,Read_Type,W,env,Extraction_length,startposition,density_r,stepspeed,step);
    Grsize_ms = round(sqrt(GDmax-GDmin)^2*rand(1)+GDmin);
    density_r = rand(1)*(density_max-density_min)+density_min;
end
Y=Y'; %transform to channels in columns
%% Reverb
if reverb==0;
    Y=Y;
else    
    % Assign a value of 5 corresponding to the number of taps (i.e., reflections)
    % to a variable tn.
    tn = 5;
    
    % Assign the following gain loss values corresponding to each of the
    % 5 taps: 0.8, 0.5, 0.3, 0.25, 0.2. Call the variable tg.
    tg = [0.8, 0.5, 0.3, 0.25, 0.2];
    
    % Assign the following delay length values in samples corresponding to each
    % of the 5 taps: 59, 100, 195, 225, 250. Call the variable td.
    td = [59, 100, 195, 225, 250];
    
    % Assign the following gain loss values corresponding to the 4 feedback
    % comb filters: 0.805, 0.827, 0.783, 0.764. Call the variable cg.
    cg = [0.805, 0.827, 0.783, 0.764];
    
    % Assign the following delay length values in samples corresponding 4
    % feedback comb filters: 901, 778, 1011, 1123. Call the variable cd.
    cd = [floor(0.81*reverb), floor(0.7*reverb), round(0.9*reverb), 1123];
    
    % Assign a value of 0.7 corresponding to the gain factor and name the
    % variable ag.
    ag = 0.7;
    
    % Assign the following three delay length values corresponding to the three
    % allpass filters: 125, 42, 12. Call the variable ad.
    ad = [125, 42, 12];
    
    % Assign a value of 0.5 corresponding to the mix rate (dry to wet signal
    % gain) and name the variable k.
    k = 0.5;
    
    % Call the function schroeder with the defined variables above as input
    % arguments.
    for ch =1:1:choutput
    Yr(:,ch) = schroeder(Y(:,ch), tn, tg, td, cg, cd, ag, ad, k);
    end
    Y=Yr;
end 
%% Low pass filtering
if cutoff_freq==0;
    Y=Y;
else
    
    norm_cutoff_freq = cutoff_freq/(fs/2);
    coeff_num = 32;
    b_32_taps = fir1(coeff_num, norm_cutoff_freq);
    for ch =1:1:choutput
    Y(:,ch) = filter(b_32_taps, 1, Y(:,ch));
    end
end
y_window=tukeywin(length(Y),y_window);
for ch =1:1:choutput;
Y(:,ch) = Y(:,ch).*y_window;
end


%% Play the resulting audio signal
sound(Y,fs);
audiowrite('grainspat_example11.wav',Y,fs);











