Created a Pitch Envelope
App updated to work with pitch envelope. Works with Harmonic Offset. Added Equalizer GUI elements. Still does not work with LFO and does not work with Equalizer.
This commit is contained in:
parent
ef5b43b354
commit
0984b75d36
Binary file not shown.
57
src/DarellAnnePitchEnvelope.m
Normal file
57
src/DarellAnnePitchEnvelope.m
Normal file
@ -0,0 +1,57 @@
|
||||
%Written by Darell and Anne
|
||||
|
||||
function output = DarellAnnePitchEnvelope(input, Fs, attack,decay,sustain,release) %percentages for attack, decay, sustain, release
|
||||
len = length(input);
|
||||
T = (len-1)/Fs;
|
||||
attacktime = attack * T * Fs;
|
||||
decaytime = attacktime + decay * T * Fs;
|
||||
sustaintime = (T - (release * T)) * Fs;
|
||||
|
||||
output = zeros([1,len]);
|
||||
|
||||
tcounter = 1;
|
||||
%attack phase
|
||||
curr = attacktime;
|
||||
while tcounter <= curr
|
||||
ncount = round(curr*log(tcounter)/log(curr)+1);
|
||||
output(tcounter) = input(ncount);
|
||||
tcounter = tcounter+1;
|
||||
end
|
||||
|
||||
%decay phase
|
||||
prevcur = curr;
|
||||
tcounter = prevcur;
|
||||
curr = decaytime;
|
||||
while tcounter <= curr
|
||||
ncount = round(sustain*curr*(1-log(tcounter)/log(prevcur)) + prevcur);
|
||||
tcounter = round(tcounter);
|
||||
output(tcounter)
|
||||
output(tcounter) = input(ncount);
|
||||
tcounter = tcounter+1;
|
||||
end
|
||||
|
||||
%sustain phase
|
||||
prevncount = ncount;
|
||||
prevcur = curr;
|
||||
tcounter = prevcur;
|
||||
curr = sustaintime;
|
||||
while tcounter <= curr
|
||||
ncount = round(sustain*(tcounter - prevcur) + prevncount);
|
||||
tcounter = round(tcounter);
|
||||
output(tcounter) = input(ncount);
|
||||
tcounter = tcounter+1;
|
||||
end
|
||||
|
||||
%release phase
|
||||
prevncount = ncount;
|
||||
prevcur = curr;
|
||||
tcounter = prevcur;
|
||||
curr = Fs;
|
||||
while tcounter <= Fs
|
||||
ncount = round(curr*(1-log(tcounter)/log(prevcur)) + prevncount);
|
||||
tcounter = round(tcounter);
|
||||
output(tcounter) = input(ncount);
|
||||
tcounter = tcounter+1;
|
||||
end
|
||||
|
||||
end
|
8
src/FilterSelect.m
Normal file
8
src/FilterSelect.m
Normal file
@ -0,0 +1,8 @@
|
||||
function output = FilterSelect(input,Fs,LOW,MED,HIGH,number)
|
||||
if(number == "Option 1")
|
||||
output = DarellbandpassFilter(input,Fs,LOW,MED,HIGH);
|
||||
else
|
||||
output = input;
|
||||
end
|
||||
end
|
||||
|
@ -13,7 +13,7 @@ x = x + generate_sine(amplitude, (frequency+5), phase, fs, duration, duty);
|
||||
|
||||
%play over 5 counts, should hear both frequencies, 5 beats per second between the 2 frequencies
|
||||
playtime = 5;
|
||||
play_continuous(x, fs, playtime)
|
||||
%play_continuous(x, fs, playtime)
|
||||
|
||||
LOW = 0;
|
||||
HIGH = frequency + 1;
|
||||
@ -22,7 +22,14 @@ x = DarellbandpassFilter(x,fs,LOW,MED,HIGH);
|
||||
|
||||
%play over 5 counts, should only hear 200hz
|
||||
playtime = 5;
|
||||
play_continuous(x, fs, playtime)
|
||||
%play_continuous(x, fs, playtime)
|
||||
|
||||
attack = 0.2;
|
||||
decay = 0.1;
|
||||
sustain = 0.8;
|
||||
release = 0.4;
|
||||
|
||||
x = DarellAnnePitchEnvelope(x, Fs, attack,decay,sustain,release);
|
||||
|
||||
attack = 0.2;
|
||||
decay = 0.2;
|
||||
|
50
src/Petha_Hsu_PitchOffset.m
Normal file
50
src/Petha_Hsu_PitchOffset.m
Normal file
@ -0,0 +1,50 @@
|
||||
% Petha_Hsu_PitchOffset: input a wave and pitch offset (in percentage)
|
||||
% This function takes a input sound signal and increases the pitch by the
|
||||
% offset percentage. The output is not 100% accurate. It is only an
|
||||
% estimation as the information we the function works with is very limited.
|
||||
% If 100% output is expected, more information like the frequency and type
|
||||
% of wave would be required. And the estimation only works for
|
||||
% f_offset > 0.5. Below 0.5, the output is problematic. Again, the output
|
||||
% is just a good estimation.
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Pethaperumal Natarajan: I figured a way to increase the pitch of input
|
||||
% signal by using fourier transform and shifting the frequency using a for
|
||||
% loop. Then I used inverse transform to get a sound signal back in the time
|
||||
% domain.
|
||||
% Wesley Hsu: I helped solve the problem of being unable to lower frequency
|
||||
% for the loop using the floor function. This allowed rounding to maintain
|
||||
% the lower signals that were needed when the code returned the signal back
|
||||
% into the time domain.
|
||||
|
||||
function y = Petha_Hsu_PitchOffset(x, f_offset)
|
||||
len = length(x);
|
||||
X = fft(x);
|
||||
X = fftshift(X); %Fourier transform the input wave
|
||||
Y = zeros(1, len);
|
||||
|
||||
midpoint = len/2;
|
||||
for i = 1:len
|
||||
%Shifting the Fourier transform in frequency domain to adjust the
|
||||
%frequency of signal.
|
||||
%Floor function is used as signals must be integers and not
|
||||
%doubles.
|
||||
if floor((i - midpoint) / f_offset + midpoint) < 1 || floor((i - midpoint) / f_offset + midpoint) > len
|
||||
continue;
|
||||
end
|
||||
Y(i) = X(floor((i - midpoint) / f_offset + midpoint));
|
||||
end
|
||||
|
||||
%Plotted graphs to troubleshoot the problem.
|
||||
%Fs = 44800;
|
||||
%f = Fs *(-len/2 : len/2 -1) / len;
|
||||
%tiledlayout(1,3); nexttile;
|
||||
%plot(f, abs(X)); title("input"); nexttile;
|
||||
%plot(f, abs(Y)); title("output"); nexttile;
|
||||
|
||||
|
||||
Y = fftshift(Y);
|
||||
y = ifft(Y);
|
||||
y = real(y);
|
||||
|
||||
end
|
@ -1,6 +1,6 @@
|
||||
function output = PitchEnvelopeSelect(input, Fs, attack,decay,sustain,release,number)
|
||||
if(number == "Option 1")
|
||||
output = DarellAmplitudeEnvelope(input, Fs, attack,decay,sustain,release);
|
||||
output = DarellAnnePitchEnvelope(input, Fs, attack,decay,sustain,release);
|
||||
else
|
||||
output = input;
|
||||
end
|
||||
|
Reference in New Issue
Block a user