%  An ADSR envelope employment demonstration
%  in additive synthesis

%  Author: Andreas Floros
%  Digital Audio Processing Applications Group
%  Dept. of Audiovisual Arts, Ionian University
%  v.1.0 - Last Modified: 22/03/2009.

clc;
clear;

% Define the synthsized note duration in seconds
note_duration = 3;

% Overall synthesis gain definition
% Must be defined for avoiding clipping due to the addition of multiple sinewaves
synthesis_gain = 0.2;

% Perform  frequency analysis of the original note recording
% in order to calculate the relative harmonics' amplitudes
filename = 'Guitar_DO.WAV';
% Define the note fundamental frequency (in Hz)
note_fundamental_frequency = 130.82;  % DO
%note_fundamental_frequency = 146.84;  % RE

% Calculate the harmonic ratios of the original input note 
[harmonic_ratios_vector, harmonic_frequency_vector, fs] = FindHarmonics(note_fundamental_frequency, filename);

% Synthesize the note using additive Fourier synthesis
generated_note = SynthesizeSound(synthesis_gain .* harmonic_ratios_vector', note_fundamental_frequency, note_duration, fs);

% Define the ADSR envelope parameter values
target = [0.99999;0;0];
gain = [0.005;0.00004;0];
adsr_durations = [25;note_duration * 1000 - 25;0];

% Create the ADSR envelope
adsr_envelope = Fx_GuitarADSR(target, gain, adsr_durations, fs);

% Apply the envelope to the generated waveform
signal_length = min([length(generated_note) length(adsr_envelope)]);
adsr_envelope = adsr_envelope(1:signal_length);
generated_note = generated_note(1:signal_length);
generated_note = adsr_envelope .* generated_note;

% Results and comparisons
% Load the original note
[original_note,fs,N] = wavread(filename);

% Time domain plots
% First create the appropriate time-domain resolution
t1 = [0:1:length(original_note)-1]*(1/fs);
t2 = [0:1:length(generated_note)-1]*(1/fs);
figure;plot(t1, original_note);hold on;
plot(t2, generated_note, 'g-');
axis('tight');xlabel('Time (sec)');ylabel('Linear normalized amplitude');

% Spectrum analysis
% Calculate the original note spectrum in dB
P_original = 20*log10(abs(fft(original_note)));
% Calculate the generated note spectrum in dB
P_generated = 20*log10(abs(fft(generated_note)));
% Create the appropriate frequency resolution vector up to fs/2
f1 = fs * [0:1:length(original_note)/2-1]' / length(original_note);
f2 = fs * [0:1:length(generated_note)/2-1]' / length(generated_note);
% Compare the spectrum plots of both original and ganerated notes 
figure; semilogx(f1, P_original(1:length(original_note)/2)); hold on
semilogx(f2, P_generated(1:length(generated_note)/2),'g-');
axis('tight');title('Note spectrum');xlabel('Frequency (Hz)');ylabel('Amplitude (dB)');hold on;

% Now acoustically compare the original and the synthesized note
disp('Playing original recorded note. Press a key when the playback is finished');
sound(original_note,fs);
pause;
disp('Now playing generated note...');
sound(generated_note,fs);