diff --git a/DarellsAnnex/app.mlapp b/DarellsAnnex/app.mlapp index 3fb8dca..763205b 100644 Binary files a/DarellsAnnex/app.mlapp and b/DarellsAnnex/app.mlapp differ diff --git a/src/DarellAnnePitchEnvelope.m b/src/DarellAnnePitchEnvelope.m new file mode 100644 index 0000000..dc147f6 --- /dev/null +++ b/src/DarellAnnePitchEnvelope.m @@ -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 \ No newline at end of file diff --git a/src/FilterSelect.m b/src/FilterSelect.m new file mode 100644 index 0000000..abe6325 --- /dev/null +++ b/src/FilterSelect.m @@ -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 + diff --git a/src/Main_test.m b/src/Main_test.m index 31f53eb..1ebd646 100644 --- a/src/Main_test.m +++ b/src/Main_test.m @@ -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; diff --git a/src/Petha_Hsu_PitchOffset.m b/src/Petha_Hsu_PitchOffset.m index 908accf..feaa922 100644 --- a/src/Petha_Hsu_PitchOffset.m +++ b/src/Petha_Hsu_PitchOffset.m @@ -1,50 +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); - +% 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 \ No newline at end of file diff --git a/src/PitchEnvelopeSelect.m b/src/PitchEnvelopeSelect.m index 1cbe9d8..91bc91c 100644 --- a/src/PitchEnvelopeSelect.m +++ b/src/PitchEnvelopeSelect.m @@ -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