% Sebastian J. Schlecht, Saturday, 10 August 2019
% 
clear; clc; close all;

fs = 48000;

%% create sine wave sample
len = fs/20;
frequency = 412.7;
sustain = sin( frequency * linspace(0,2*pi/20,len) ).';

%% Randomize phase without zero-padding
fftLen = len; % no zero padding
frequencyBinsShort = linspace(0,fs,fftLen).';
Sustain = fft(sustain, fftLen);
phaseShort = angle(Sustain);

randomTemp = rescale( rand(fftLen/2-1,1), -pi, pi) ;
randomPhaseShort = [0; randomTemp; 0; -flipud(randomTemp)];
RandomSustain = exp(1i*randomPhaseShort) .* abs(Sustain);

randomSustain = ifft(RandomSustain);

%% Randomize phase with zero-padding
lenLong = fs*3;
fftLen = lenLong;
frequencyBinsLong = linspace(0,fs,fftLen).';
Sustain = fft(sustain, fftLen);

randomTemp = rescale( rand(fftLen/2-1,1), -pi, pi) ;
randomPhase = [0; randomTemp; 0; -flipud(randomTemp)];
LongSustain = exp(1i*randomPhase) .* abs(Sustain);

longSustain = ifft(LongSustain);

%% Window and randomize phase with zero-padding
windowedSustain = sustain .* tukeywin(len,1);

fftLen = lenLong;
frequencyBinsLong = linspace(0,fs,fftLen).';
WindowedSustain = fft(windowedSustain, fftLen);

randomTemp = rescale( rand(fftLen/2-1,1), -pi, pi) ;
randomPhase = [0; randomTemp; 0; -flipud(randomTemp)];
WindowedLongSustain = exp(1i*randomPhase) .* abs(WindowedSustain);

windowedLongSustain = ifft(WindowedLongSustain);




%% plot
fig = figure(6); hold on; grid on;
plot([sustain])
% legend({'this'})
xlabel('Time [samples]')
ylabel('Amplitude [linear]')
axis tight
fig.PaperPosition = [0.25 0.25 4 2];
print('OrignalSample','-dpng','-r300')


fig = figure(7); hold on; grid on;
plot(0:len,[sustain;0]);
plot((0:len)+len,[sustain;0]);
plot((0:len)+2*len+1,[sustain;0]);
% legend({'this'})
xlabel('Time [samples]')
ylabel('Amplitude [linear]')
axis tight
fig.PaperPosition = [0.25 0.25 6 2];
print('OrignalSampleLooped','-dpng','-r300')


fig = figure(1); hold on; grid on;
plot(0:len,[sustain;sustain(1)]);
plot((0:len)+len,[sustain;sustain(1)]);
% legend({'this'})
xlabel('Time [samples]')
ylabel('Amplitude [linear]')
axis([len-300, len+300,-1,1])
fig.PaperPosition = [0.25 0.25 6 2];
print('OrignalSampleLoopedZoom','-dpng','-r300')



fig = figure(2); hold on; grid on;
plot(0:len,[randomSustain;randomSustain(1)]);
plot((0:len)+len,[randomSustain;randomSustain(1)]);
% legend({'this'})
xlabel('Time [samples]')
ylabel('Amplitude [linear]')
axis([len-300, len+300,-1,1])
fig.PaperPosition = [0.25 0.25 6 2];
print('AlteredSampleLoopedZoom','-dpng','-r300')


fig = figure(3); hold on; grid on;
plot(frequencyBinsShort,mag2db(abs(RandomSustain)))
% legend({'this'})
xlabel('Frequency [Hz]')
ylabel('Mangitude [dB]')
axis([0 800 0 60])
fig.PaperPosition = [0.25 0.25 4 2];
print('MagnitudeResponse','-dpng','-r300')

fig = figure(4); hold on; grid on;
plot(frequencyBinsShort,phaseShort)
plot(frequencyBinsShort,randomPhaseShort)
legend({'Original Phase', 'Randomized Phase'})
xlabel('Frequency [Hz]')
ylabel('Phase [radians]')
axis([0 800 -pi pi])
fig.PaperPosition = [0.25 0.25 4 2];
print('PhaseResponse','-dpng','-r300')


fig = figure(10); hold on; grid on;
plot([windowedSustain])
% legend({'this'})
xlabel('Time [samples]')
ylabel('Amplitude [linear]')
axis tight
fig.PaperPosition = [0.25 0.25 4 2];
print('WindowedOrignalSample','-dpng','-r300')

fig = figure(12); hold on; grid on;
plot(0:lenLong,[windowedLongSustain;windowedLongSustain(1)]);
plot((0:lenLong)+lenLong,[windowedLongSustain;windowedLongSustain(1)]);
% legend({'this'})
xlabel('Time [samples]')
ylabel('Amplitude [linear]')
axis([lenLong-3000, lenLong+3000,-0.2,0.2])
fig.PaperPosition = [0.25 0.25 6 2];
print('WindowedSampleLoopedZoom','-dpng','-r300')



%% sounds

audiowrite('OriginalRepeated.wav',rescale(repmat(sustain,100,1),-0.9,0.9),fs);
audiowrite('AlteredRepeated.wav',rescale(repmat(randomSustain,100,1),-0.9,0.9),fs);
audiowrite('StretchedRepeated.wav',rescale(repmat(longSustain,4,1),-0.9,0.9),fs);
audiowrite('WindowedOriginalRepeated.wav',rescale(repmat(windowedSustain,100,1),-0.9,0.9),fs);
audiowrite('WindowedStretchedRepeated.wav',rescale(repmat(windowedLongSustain,4,1),-0.9,0.9),fs);

