Merge branch 'main' into alex
This commit is contained in:
commit
4fd1c6a119
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
|
10
src/FilterSelect.m
Normal file
10
src/FilterSelect.m
Normal file
@ -0,0 +1,10 @@
|
||||
function output = FilterSelect(input,Fs,LOW,MED,HIGH,number)
|
||||
if(number == "Option 1")
|
||||
output = DarellbandpassFilter(input,Fs,LOW,MED,HIGH);
|
||||
elseif(number == "Option 2")
|
||||
output = amplifyFreqRange(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;
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -5,7 +5,10 @@ function output = SoundGeneratorSelect(amplitude, frequency, phase, fs, duration
|
||||
output = generate_square(amplitude, frequency, phase, fs, duration, duty);
|
||||
elseif(number == "Option 3")
|
||||
output = generate_triangle(amplitude, frequency, phase, fs, duration, duty);
|
||||
|
||||
elseif(number == "Option 4")
|
||||
output = generate_sawtooth(amplitude, frequency, phase, fs, duration, duty);
|
||||
elseif(number == "Option 5")
|
||||
output = generate_white(amplitude, frequency, phase, fs, duration, duty);
|
||||
else
|
||||
output = 0;
|
||||
end
|
||||
|
BIN
src/Strong_Bassline.mp3
Normal file
BIN
src/Strong_Bassline.mp3
Normal file
Binary file not shown.
62
src/bandreject_filter.m
Normal file
62
src/bandreject_filter.m
Normal file
@ -0,0 +1,62 @@
|
||||
function output_y = bandreject_filter(Input, Fs, Low, High)
|
||||
% A filter that lets through most frequencies unaltered
|
||||
% but attentuates the frequencies in the specified range to
|
||||
% very low levels
|
||||
% (basically exliminates them)
|
||||
% By Yalu Ouyang
|
||||
|
||||
|
||||
% Input: the input signal in the time domain
|
||||
% Fs: the sampling frequency
|
||||
% Low: the lower limit of the specified range
|
||||
% High: the upper limit of the specified range
|
||||
% Returns Output: the filtered signal in the time domain
|
||||
|
||||
len = length(Input);
|
||||
|
||||
F = Fs * (-len/2 : (len/2 - 1)) / len ;
|
||||
|
||||
% modified signal in the frequency domain
|
||||
% using Fourier Transform
|
||||
mod_freq = fftshift(fft(Input));
|
||||
|
||||
len_f = length(mod_freq);
|
||||
|
||||
% use this array to record the frequencies
|
||||
% that should pass through
|
||||
% 0 indicates reject
|
||||
% 1 indicates pass
|
||||
multiplier = zeros([1,len_f]);
|
||||
|
||||
for index = 1 : len_f
|
||||
|
||||
% within range of band reject
|
||||
% so elminate these frequencies
|
||||
if ((Low < abs(F(index))) && (abs(F(index)) < High))
|
||||
multiplier(index) = 0;
|
||||
|
||||
% outside of specified range
|
||||
% so shoudln't be altered
|
||||
else
|
||||
multiplier(index) = 1;
|
||||
end
|
||||
end
|
||||
|
||||
% filtered signal in the frequency domain
|
||||
filtered_mod_freq = fftshift(mod_freq .* multiplier);
|
||||
|
||||
% convert signal back to the time domain
|
||||
Output = real(ifft(filtered_mod_freq));
|
||||
|
||||
end
|
||||
|
||||
% This function is useful for eliminating
|
||||
% unwanted signals that have frequencies close to the
|
||||
% median frequency of the original signal
|
||||
% (consider overall frequencies as one part,
|
||||
% this elminates the middle portion)
|
||||
|
||||
% Fourier transform is applied in this function
|
||||
% to make it easier to eliminate specified
|
||||
% frequencies of the signal
|
||||
% (easier to do so in the frequency domain)
|
55
src/epic_effect_schluep.m
Normal file
55
src/epic_effect_schluep.m
Normal file
@ -0,0 +1,55 @@
|
||||
function output = epic_effect_schluep(input, Fs, LOW, MED, HIGH)
|
||||
% epic_effect_schluep: Outputs a more "epic" version of the input sound.
|
||||
% This is done by amplifying low frequencies and by implementing a chorus
|
||||
% effect. A chorus effect is created when multiple copies of sound delayed
|
||||
% by a small, random amount are added to the original signal. Works best on
|
||||
% songs with a stronger bassline.
|
||||
% Try this function out with "Strong_Bassline.mp3".
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Nicolas Schluep: Function Author
|
||||
|
||||
% DOCUMENTATION:
|
||||
% input: The input sound in the time-domain.
|
||||
% Fs: The sampling rate of the input signal. A typical value is 44100 Hz.
|
||||
% HIGH: The maximum frequency the filter will amplify. A typical value for
|
||||
% this variable is 1000 Hz.
|
||||
|
||||
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
|
||||
% by just taking the first column of data.
|
||||
|
||||
Len = length(non_stereophonic);
|
||||
F = Fs * ((-Len/2) : ((Len/2) - 1)) / Len; % Creating the array of frequencies
|
||||
% which the FFT Shifted version of the signal can be plotted against.
|
||||
inputFreq = fftshift(fft(non_stereophonic)); % Creates the Fourier Transform of the
|
||||
% input signal. fftshift() makes it such that the zero frequency is at the
|
||||
% center of the array.
|
||||
lowAmplifyFilter = zeros(1, length(inputFreq));
|
||||
|
||||
% Creating a filter which amplifies lower frequencies.
|
||||
for i = 1:length(lowAmplifyFilter)
|
||||
if abs(F(i)) < HIGH
|
||||
lowAmplifyFilter(i) = 1.25;
|
||||
else
|
||||
lowAmplifyFilter(i) = 1.00;
|
||||
end
|
||||
end
|
||||
|
||||
lowPassedInput = inputFreq .* transpose(lowAmplifyFilter); %Apply the "lowAmplifyFilter".
|
||||
|
||||
% Adding the chorus effect.
|
||||
realOutput = real(ifft(fftshift(lowPassedInput)));
|
||||
output = realOutput;
|
||||
|
||||
% Adding 100 randomly delayed signals to the original signal which creates the chorus effect.
|
||||
for i = 1:100
|
||||
currentDelay = 0.003 * rand(); % The current delay of the sound in seconds.
|
||||
currentIndex = round(currentDelay * Fs); % Find the first index where the sound should start playing.
|
||||
delayedOutput = [zeros(currentIndex, 1); realOutput]; % Adds "currentIndex" zeros to the front of the
|
||||
% "realOutput" vector to create a slightly delayed version of the signal.
|
||||
delayedOutput = delayedOutput(1:length(realOutput)); % Truncates the "delayedOutput"
|
||||
% vector so that it can be added to the "realOutput" vector.
|
||||
output = output + delayedOutput;
|
||||
end
|
||||
|
||||
output = output ./ 100; % Divide by 100 to decrease the amplitude of the sound to a normal level.
|
29
src/fade_in.m
Normal file
29
src/fade_in.m
Normal file
@ -0,0 +1,29 @@
|
||||
function output = fade_in(input, time)
|
||||
% Creates a fade-in sound effect that lasts a given
|
||||
% time parameter of the input sound signal
|
||||
% By Yalu Ouyang
|
||||
|
||||
|
||||
% input: a 1D array that represents the sound signal in the time domain
|
||||
% time: how long the fade in effect should last
|
||||
% Shouldn't be longer than the input signal (in which case the function
|
||||
% treats it as the duration of the signal)
|
||||
% Returns modified signal in the time domain (output).
|
||||
|
||||
len = length(input);
|
||||
|
||||
% if time parameter longer than signal, treat time as
|
||||
% the duration of original signal
|
||||
if time > len
|
||||
time = len
|
||||
end
|
||||
|
||||
% set multiplier as 1D array
|
||||
% fade in effect: from no volume to full volume of signal
|
||||
multiplier = (1 : time) / time;
|
||||
|
||||
% the resulting fade-in output
|
||||
output = input .* multiplier;
|
||||
end
|
||||
|
||||
% This is useful for making videos, specifically the intro part
|
32
src/fade_out.m
Normal file
32
src/fade_out.m
Normal file
@ -0,0 +1,32 @@
|
||||
function output = fade_out(input, time)
|
||||
% Creates a fade-out sound effect that lasts a given
|
||||
% time parameter of the input sound signal
|
||||
% By Yalu Ouyang
|
||||
|
||||
% input: a 1D array that represents the sound signal in the time domain
|
||||
% time: how long the fade out effect should last
|
||||
% Shouldn't be longer than the input signal
|
||||
% (in which case the function treats it as the duration of the signal)
|
||||
% Returns modified signal in the time domain (output).
|
||||
|
||||
len = length(input);
|
||||
|
||||
% if time parameter longer than signal, treat time as
|
||||
% the duration of original signal
|
||||
if time > len
|
||||
time = len
|
||||
end
|
||||
|
||||
% set multiplier as 1D array
|
||||
|
||||
multiplier = (1 : time) / time;
|
||||
|
||||
% fade out effect: from full volume of signal to no volume
|
||||
multiplier = flip(multiplier)
|
||||
|
||||
% the resulting fade-in output
|
||||
output = input .* multiplier;
|
||||
end
|
||||
|
||||
|
||||
% This is useful for creating videos, specifically the outro part
|
56
src/muffled_effect_schluep.m
Normal file
56
src/muffled_effect_schluep.m
Normal file
@ -0,0 +1,56 @@
|
||||
function output = muffled_effect_schluep(input, Fs, LOW, MED, HIGH)
|
||||
% muffled_effect_schluep: Outputs a muffled version of the the original input
|
||||
% sound in the time domain. This makes it sound as if the audio is being
|
||||
% played in another room.
|
||||
% Try this function out with "Strong_Bassline.mp3".
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Nicolas Schluep: Function Author
|
||||
|
||||
% DOCUMENTATION:
|
||||
% input: The input sound in the time-domain.
|
||||
% Fs: The sampling rate of the input signal. A typical value is 44100 Hz.
|
||||
% HIGH: The maximum frequency that the low-pass filter will let pass. A
|
||||
% typical value for this variable is 1000 Hz.
|
||||
|
||||
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
|
||||
% by just taking the first column of data.
|
||||
|
||||
Len = length(non_stereophonic);
|
||||
F = Fs * ((-Len/2) : ((Len/2) - 1)) / Len; % Creating the array of frequencies
|
||||
% which the FFT Shifted version of the signal can be plotted against.
|
||||
inputFreq = fftshift(fft(non_stereophonic)); % Creates the Fourier Transform of the
|
||||
% input signal. fftshift() makes it such that the zero frequency is at the
|
||||
% center of the array.
|
||||
lowPassFilter = zeros(1, length(inputFreq));
|
||||
|
||||
% Creating Low Pass Filter
|
||||
for i = 1:length(lowPassFilter)
|
||||
if abs(F(i)) < HIGH
|
||||
lowPassFilter(i) = 1;
|
||||
else
|
||||
lowPassFilter(i) = 0;
|
||||
end
|
||||
end
|
||||
|
||||
lowPassedInput = inputFreq .* transpose(lowPassFilter); %Apply the low-pass filter.
|
||||
|
||||
% Adding a slight reverb effect.
|
||||
realOutput = real(ifft(fftshift(lowPassedInput)));
|
||||
|
||||
delay = 0.001; % The delay of the sound in seconds.
|
||||
index = round(delay*Fs); % Find the first index where sound should start playing
|
||||
% by multiplying the delay by the sampling frequency.
|
||||
delayedOutput = [zeros(index, 1); realOutput]; % Adds "index" zeros to the front of the
|
||||
% "realOutput" vector to create a slightly delayed version of the signal.
|
||||
delayedOutput = delayedOutput(1:length(realOutput)); % Truncates the "delayedOutput"
|
||||
% vector so that it can be added to the "realOutput" vector.
|
||||
|
||||
output = (realOutput + delayedOutput) ./ 2.0; % Adds the "realOutput" and "delayedOutput"
|
||||
% vectors to create a reverb effect. Divides by 2 to avoid clipping
|
||||
% effects.
|
||||
|
||||
|
||||
|
||||
|
||||
|
62
src/seperate_prevalent_schluep.m
Normal file
62
src/seperate_prevalent_schluep.m
Normal file
@ -0,0 +1,62 @@
|
||||
function output = seperate_prevalent_schluep(input, Fs, LOW, MED, HIGH)
|
||||
% seperate_prevalent_schluep: Attempts to seperate the most prevalent frequencies
|
||||
% from the input sound by finding the most prevalent frequencies and applying
|
||||
% a band-pass filter to a small region around those frequencies.
|
||||
% Try this function out with "Strong_Bassline.mp3".
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Nicolas Schluep: Function Author
|
||||
|
||||
% DOCUMENTATION:
|
||||
% input: The input sound in the time-domain.
|
||||
% Fs: The sampling rate of the input signal. A typical value is 44100 Hz.
|
||||
% HIGH: The maximum distance around the maximum frequency value that will
|
||||
% not be attenuated. A good range of values is usually 250-500 Hz, but it
|
||||
% depends on the input sound.
|
||||
|
||||
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
|
||||
% by just taking the first column of data.
|
||||
|
||||
Len = length(non_stereophonic);
|
||||
F = Fs * ((-Len/2) : ((Len/2) - 1)) / Len; % Creating the array of frequencies
|
||||
% which the FFT Shifted version of the signal can be plotted against.
|
||||
inputFreq = fftshift(fft(non_stereophonic)); % Creates the Fourier Transform of the
|
||||
% input signal. fftshift() makes it such that the zero frequency is at the
|
||||
% center of the array.
|
||||
bandPassFilter = zeros(1, length(inputFreq));
|
||||
|
||||
maxAmplitude = 0;
|
||||
mostPrevalentFrequency = 0;
|
||||
|
||||
% Finding the most prevalent frequency.
|
||||
for i = round(length(inputFreq)/2):length(inputFreq)
|
||||
if inputFreq(i) > maxAmplitude
|
||||
maxAmplitude = inputFreq(i);
|
||||
mostPrevalentFrequency = F(i);
|
||||
end
|
||||
end
|
||||
|
||||
% Determining maximum and minimum frequency values for the Band Pass filter.
|
||||
maxFrequency = mostPrevalentFrequency + HIGH;
|
||||
minFrequency = mostPrevalentFrequency - HIGH;
|
||||
|
||||
if minFrequency < 0.0
|
||||
minFrequency = 0.0;
|
||||
end
|
||||
|
||||
% Creating the Band-Pass filter.
|
||||
for i = 1:length(bandPassFilter)
|
||||
if (abs(F(i)) < maxFrequency) && (abs(F(i)) > minFrequency)
|
||||
bandPassFilter(i) = 1;
|
||||
else
|
||||
bandPassFilter(i) = 0;
|
||||
end
|
||||
end
|
||||
|
||||
bandPassedInput = inputFreq .* transpose(bandPassFilter); %Apply the Band-Pass Filter.
|
||||
|
||||
output = real(ifft(fftshift(bandPassedInput)));
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user