Merge branch 'main' into DarellsAnnex

This commit is contained in:
Darell Chua Yun Da 2021-12-13 09:31:34 +08:00
commit f1428720c0
44 changed files with 1235 additions and 52 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -6,7 +6,7 @@
Will add member names shortly Will add member names shortly
## Function Prototypes ## Function Prototypes
Templates to create your own functions. Templates to create your own functions. Please commit code in either src/ (the base directopry) or src/NotWorking (please dont commit in any other subfolder).
### Wave generating function ### Wave generating function
``` ```
@ -57,10 +57,10 @@ where LOW, MED, HIGH are user-selected variables of any value.
## Useful websites ## Useful websites
- https://learningsynths.ableton.com - [Learning Synths](https://learningsynths.ableton.com)
- https://learningsynths.ableton.com/en/playground - [Learning Synths Playground](https://learningsynths.ableton.com/en/playground)
- https://blog.demofox.org/diy-synthesizer/ - [DIY Synthesisers](https://blog.demofox.org/diy-synthesizer/)
- http://portaudio.com/ - [Port Audio (audio I/O library)](http://portaudio.com/)
- https://ccrma.stanford.edu/software/stk/ - [Synthesis ToolKit in C++](https://ccrma.stanford.edu/software/stk/)
- https://cycling74.com/products/max - [Max](https://cycling74.com/products/max)
- http://msp.ucsd.edu/software.html - [Software by Miller Puckette](http://msp.ucsd.edu/software.html)

BIN
src/.DS_Store vendored

Binary file not shown.

View File

@ -0,0 +1,33 @@
function output_x = AnuragDampenTarget(x, Fs,LOW, MID, HIGH)
%Dampen a range of frequencies a percentage around the target frequency
%Also maintain the other frequencies so that the target is muted
%percentage is expressed as a number between 0 and 1.
%target is the midpoint of the frequency range to dampen
%x and Fs are the signal and frequency
% CONTRIBUTORS:
% Anurag Jadhav: function creator
% Detailed explanation goes here
TARGET = MID;
AreaPercentage = 0.15;
len = length(x); %get length of the input
F = Fs * ((-len/2) : ((len/2) - 1)) / len;
lenf = length(F);
Mod_Freq = fftshift(fft(x)); %Fourier Transform of the input signal
output = zeros([1,lenf]); % zero array of size Mod_freq
%set the bounds
lowerBound = (1-AreaPercentage) * TARGET;
upperBound = (1+AreaPercentage) * TARGET;
%% Dampen the target frequencies and maintain the others
for n = 1:lenf
if ((lowerBound < abs(F(n))) && abs(F(n)) < upperBound)
output(n) = 0.5;
else
output(n) = 1;
end
end
%%Filter the original signal and transform
filtered_Mod_Freq = fftshift(Mod_Freq .* output);
output_x = real(ifft(filtered_Mod_Freq));
end

View File

@ -0,0 +1,34 @@
function output_x = AnuragEnchanceTarget(x, Fs,LOW, MID, HIGH)
%Amplify a range of frequencies a percentage around the target frequency
%Also damnpen the other frequencies so that the target is easier to hear
%percentage is expressed as a number between 0 and 1.
%target is the midpoint of the frequency range to amplify
%x and Fs are the signal and frequency
% CONTRIBUTORS:
% Anurag Jadhav: function creator
% Detailed explanation goes here
TARGET = MID;
AreaPercentage = 0.15;
len = length(x); %get length of the input
F = Fs * ((-len/2) : ((len/2) - 1)) / len;
lenf = length(F);
Mod_Freq = fftshift(fft(x)); %Fourier Transform of the input signal
output = zeros([1,lenf]); % zero array of size Mod_freq
%set the bounds
lowerBound = (1-AreaPercentage) * TARGET;
upperBound = (1+AreaPercentage) * TARGET;
%% Amplify the target frequencies and dampen the others
for n = 1:lenf
if ((lowerBound < abs(F(n))) && abs(F(n)) < upperBound)
output(n) = 2;
else
output(n) = 0.75;
end
end
%%Filter the original signal and transform
filtered_Mod_Freq = fftshift(Mod_Freq .* output);
output_x = real(ifft(filtered_Mod_Freq));
end

View File

@ -1,4 +1,4 @@
function output_y = bandreject_filter(Input, Fs, Low, High) function Output = bandreject_filter(Input, Fs, Low, High)
% A filter that lets through most frequencies unaltered % A filter that lets through most frequencies unaltered
% but attentuates the frequencies in the specified range to % but attentuates the frequencies in the specified range to
% very low levels % very low levels

View File

@ -15,13 +15,22 @@ function output = epic_effect_schluep(input, Fs, LOW, MED, HIGH)
% HIGH: The maximum frequency the filter will amplify. A typical value for % HIGH: The maximum frequency the filter will amplify. A typical value for
% this variable is 1000 Hz. % this variable is 1000 Hz.
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound n = size(input, 2);
% by just taking the first column of data.
Len = length(non_stereophonic); non_stereophonic = input;
if (n == 1) || (n == 2)
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
% by just taking the first column of data.
non_stereophonic = transpose(non_stereophonic);
end
modified_input = non_stereophonic(1, :);
Len = length(modified_input);
F = Fs * ((-Len/2) : ((Len/2) - 1)) / Len; % Creating the array of frequencies 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. % which the FFT Shifted version of the signal can be plotted against.
inputFreq = fftshift(fft(non_stereophonic)); % Creates the Fourier Transform of the inputFreq = fftshift(fft(modified_input)); % Creates the Fourier Transform of the
% input signal. fftshift() makes it such that the zero frequency is at the % input signal. fftshift() makes it such that the zero frequency is at the
% center of the array. % center of the array.
lowAmplifyFilter = zeros(1, length(inputFreq)); lowAmplifyFilter = zeros(1, length(inputFreq));
@ -35,7 +44,8 @@ for i = 1:length(lowAmplifyFilter)
end end
end end
lowPassedInput = inputFreq .* transpose(lowAmplifyFilter); %Apply the "lowAmplifyFilter". lowPassedInput = inputFreq .* lowAmplifyFilter; %Apply the "lowAmplifyFilter".
lowPassedInput = transpose(lowPassedInput);
% Adding the chorus effect. % Adding the chorus effect.
realOutput = real(ifft(fftshift(lowPassedInput))); realOutput = real(ifft(fftshift(lowPassedInput)));
@ -53,3 +63,7 @@ for i = 1:100
end end
output = output ./ 100; % Divide by 100 to decrease the amplitude of the sound to a normal level. output = output ./ 100; % Divide by 100 to decrease the amplitude of the sound to a normal level.
output = transpose(output);
end

View File

@ -13,13 +13,22 @@ function output = muffled_effect_schluep(input, Fs, LOW, MED, HIGH)
% HIGH: The maximum frequency that the low-pass filter will let pass. A % HIGH: The maximum frequency that the low-pass filter will let pass. A
% typical value for this variable is 1000 Hz. % typical value for this variable is 1000 Hz.
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound n = size(input, 2);
% by just taking the first column of data.
Len = length(non_stereophonic); non_stereophonic = input;
if (n == 1) || (n == 2)
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
% by just taking the first column of data.
non_stereophonic = transpose(non_stereophonic);
end
modified_input = non_stereophonic(1, :);
Len = length(modified_input);
F = Fs * ((-Len/2) : ((Len/2) - 1)) / Len; % Creating the array of frequencies 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. % which the FFT Shifted version of the signal can be plotted against.
inputFreq = fftshift(fft(non_stereophonic)); % Creates the Fourier Transform of the inputFreq = fftshift(fft(modified_input)); % Creates the Fourier Transform of the
% input signal. fftshift() makes it such that the zero frequency is at the % input signal. fftshift() makes it such that the zero frequency is at the
% center of the array. % center of the array.
lowPassFilter = zeros(1, length(inputFreq)); lowPassFilter = zeros(1, length(inputFreq));
@ -33,7 +42,8 @@ for i = 1:length(lowPassFilter)
end end
end end
lowPassedInput = inputFreq .* transpose(lowPassFilter); %Apply the low-pass filter. lowPassedInput = inputFreq .* lowPassFilter; %Apply the low-pass filter.
lowPassedInput = transpose(lowPassedInput);
% Adding a slight reverb effect. % Adding a slight reverb effect.
realOutput = real(ifft(fftshift(lowPassedInput))); realOutput = real(ifft(fftshift(lowPassedInput)));
@ -50,6 +60,10 @@ output = (realOutput + delayedOutput) ./ 2.0; % Adds the "realOutput" and "de
% vectors to create a reverb effect. Divides by 2 to avoid clipping % vectors to create a reverb effect. Divides by 2 to avoid clipping
% effects. % effects.
output = transpose(output);
end

View File

@ -14,13 +14,22 @@ function output = seperate_prevalent_schluep(input, Fs, LOW, MED, HIGH)
% not be attenuated. A good range of values is usually 250-500 Hz, but it % not be attenuated. A good range of values is usually 250-500 Hz, but it
% depends on the input sound. % depends on the input sound.
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound n = size(input, 2);
% by just taking the first column of data.
Len = length(non_stereophonic); non_stereophonic = input;
if (n == 1) || (n == 2)
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
% by just taking the first column of data.
non_stereophonic = transpose(non_stereophonic);
end
modified_input = non_stereophonic(1, :);
Len = length(modified_input);
F = Fs * ((-Len/2) : ((Len/2) - 1)) / Len; % Creating the array of frequencies 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. % which the FFT Shifted version of the signal can be plotted against.
inputFreq = fftshift(fft(non_stereophonic)); % Creates the Fourier Transform of the inputFreq = fftshift(fft(modified_input)); % Creates the Fourier Transform of the
% input signal. fftshift() makes it such that the zero frequency is at the % input signal. fftshift() makes it such that the zero frequency is at the
% center of the array. % center of the array.
bandPassFilter = zeros(1, length(inputFreq)); bandPassFilter = zeros(1, length(inputFreq));
@ -53,10 +62,12 @@ for i = 1:length(bandPassFilter)
end end
end end
bandPassedInput = inputFreq .* transpose(bandPassFilter); %Apply the Band-Pass Filter. bandPassedInput = inputFreq .* bandPassFilter; %Apply the Band-Pass Filter.
output = real(ifft(fftshift(bandPassedInput))); output = real(ifft(fftshift(bandPassedInput)));
end

View File

@ -0,0 +1,25 @@
function x = generate_cosine(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_WAVENAME: returns a matrix of sampled WAVENAME wave
% CONTRIBUTORS:
% Mekhi Ellington: Original Creator
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty is a number between 0 and 1
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
% initialize a one dimensional zero matrix to be populated
x = zeros(1, n);
% populate the matrix
for i = 1:n
t = i * dt;
x(i) = amplitude * cos(2*pi*frequency*t-phase);
end
end

View File

@ -0,0 +1,46 @@
function x = generate_heartbeat(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_SINE: returns a matrix of sampled heart monitor wave
% CONTRIBUTORS:
% Alex Nguyen: Original Author
% Conner Hsu: Reviewed Code and Assisted in polishing
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty cycle should be a number between 0 and 0.5.
% duty of 0 or less would return 0 for all sample points
% duty of 0.5 or less would return a heartbeat signal since there would be
% equal amount of space within 1 period to have the right and left sides be equal
% duty of greater than 0.5 but less than 1 would return a slope starting at that duty i.e.
% the left side but leaving little room to the right side
% duty of between 1 and 2 would give a sawtooth wave in the +amplitude.
% duty greater than 2 would return 0 for all sample points
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
% initialize a one dimensional zero matrix to be populated
x = zeros(1, n);
% populate the matrix
for i = 1:n
t = i * dt; % time at the i'th sample
st = mod(frequency * t - phase, 1);
if (duty-(duty / 2) < st && st < duty)
slope = amplitude / duty;
intercept = -0.5 * amplitude;
x(i) = slope * st + intercept;
elseif (duty < st && st < duty+(duty / 2))
slope = amplitude / duty;
intercept = -amplitude;
x(i) = slope * st + (1.5 * intercept);
else
x(i) = 0;
end
end

View File

@ -0,0 +1,33 @@
function x = generate_pulse(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_puse: returns a matrix of sampled pulse wave
% CONTRIBUTORS:
% Brian Tran: Created the wave
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty is a number between 0 and 1
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
% initialize a one dimensional zero matrix to be populated
x = zeros(1, n);
f0=1e+6; % 1MHz
Fs=3e+6;
Tf=0.001; % 1 millisecond
t=0:1/Fs:Tf-1/Fs;
td=0.1; % duty cycle
A0=10; % 10 Volts
F=0;
N=1000; % Number of points
% populate the matrix
for n = 1:N
F=F+(1/n)*cos(n*2*pi*f0*t).*sin(n*pi*td);
end
F=F*(2*A0/pi);
F=F+A0*td;
end

View File

@ -0,0 +1,58 @@
function x = generate_trapezoid(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_TRAPEZOID: returns a matrix of sampled square wave
% CONTRIBUTORS:
% Daniel Doan: Author
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty cycle should be a number between 0 and 1.
% duty of 0.5 would have 2 trapezoids in first half of each cycle
% example of wave with duty of 0.5, where the peaks are amplitude/2:
%
% ____
% / \
% / \ ________________
% \ /
% \____/
%
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
% initialize a one dimensional zero matrix to be populated
x = zeros(1, n);
% populate the matrix
for i = 1:n
t = i * dt;
% periodic ramp from 0 to 1
% progression through a cycle
st = mod(frequency * t - phase, 1);
slope = (amplitude/2) / (duty/8);
if(st < duty)
if(st <= duty/8)
x(i) = slope * st;
else
if(st <= 5*duty/8)
x(i) = amplitude/2 - slope * (st-(3*duty/8));
end
if(st <= 3*duty/8)
x(i) = amplitude/2;
end
if(st >= 5*duty/8)
x(i) = -amplitude/2;
end
end
if(st >= 7* duty/8)
x(i) = -amplitude/2 + slope*(st-(7*duty/8));
end
end
end
end

View File

@ -1,6 +1,6 @@
function output = MIDIDarell(dur,Fs) function output = MIDIDarell(dur,Fs)
%Darell Chua Yun Da %Darell Chua Yun Da
% Detailed explanation goes here % Use Qwerty Keys for each sound frequency.
freq = [330 350 370 392 415 440 466 494 523 554]; freq = [330 350 370 392 415 440 466 494 523 554];
charls = ["q" "w" "e" "r" "t" "y" "u" "i" "o" "p"]; charls = ["q" "w" "e" "r" "t" "y" "u" "i" "o" "p"];

View File

@ -12,16 +12,30 @@ function output = fade_in(input, time)
len = length(input); len = length(input);
% need to use whole number for time
time = round(time);
% if time parameter longer than signal, treat time as % if time parameter longer than signal, treat time as
% the duration of original signal % the duration of original signal
if time > len if time > len
time = len time = len;
end
% in order to create array, time >=1
% if not, it's arbitrarily set to 1
% in which case the fade_in effect
% is virtually nonexistent
if time < 1
time = 1;
end end
% set multiplier as 1D array % set multiplier as 1D array
% fade in effect: from no volume to full volume of signal % fade in effect: from no volume to full volume of signal
multiplier = (1 : time) / time; multiplier = (1 : time) / time;
while length(multiplier) < len
multiplier = [multiplier 1];
end
% the resulting fade-in output % the resulting fade-in output
output = input .* multiplier; output = input .* multiplier;
end end

View File

@ -11,18 +11,33 @@ function output = fade_out(input, time)
len = length(input); len = length(input);
% need to use time as a whole number
time = round(time);
% if time parameter longer than signal, treat time as % if time parameter longer than signal, treat time as
% the duration of original signal % the duration of original signal
if time > len if time > len
time = len time = len
end end
% in order to create array, time >=1
% if not, it's arbitrarily set to 1
% in which case the fade_in effect
% is virtually nonexistent
if time < 1
time = 1;
end
% set multiplier as 1D array % set multiplier as 1D array
multiplier = (1 : time) / time; multiplier = (1 : time) / time;
% fade out effect: from full volume of signal to no volume % fade out effect: from full volume of signal to no volume
multiplier = flip(multiplier) multiplier = flip(multiplier);
while length(multiplier) < len
multiplier = [multiplier 0];
end
% the resulting fade-in output % the resulting fade-in output
output = input .* multiplier; output = input .* multiplier;

View File

@ -0,0 +1,41 @@
function x = generate_arcoStrings(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_ARCOSTRINGS: returns a matrix of sampled waveform similar to
% strings played arco.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale
t = [1:n].*dt - phase;
f = frequency .* (1 + 0.0002 .* sin(10.*pi.*t)./t); %frequency vibrato
% generate proper fundamental and overtones
x = (amplitude .* sin(2.*pi.*f.*t)) ... %fundamental (first partial)
+ (0.237992723.*amplitude .* sin(4.*pi.*f.*t)) ... %second partial
+ (0.0523347308.*amplitude .* sin(6.*pi.*f.*t)) ... %third partial
+ (0.124586119.*amplitude .* sin(8.*pi.*f.*t)) ... %fourth partial
+ (0.0854326396.*amplitude .* sin(10.*pi.*f.*t)) ... %fifth partial
+ (0.0578741297.*amplitude .* sin(12.*pi.*f.*t)) ... %sixth partial
+ (0.0291070237.*amplitude .* sin(14.*pi.*f.*t)) ... %seventh partial
+ (0.0270171595.*amplitude .* sin(16.*pi.*f.*t)) ... %eighth partial
+ (0.0290818446.*amplitude .* sin(18.*pi.*f.*t)) ... %ninth partial
+ (0.0356787652.*amplitude .* sin(20.*pi.*f.*t)) ... %tenth partial
+ (0.0112928202.*amplitude .* sin(22.*pi.*f.*t)) ... %eleventh partial
+ (0.00547645126.*amplitude .* sin(24.*pi.*f.*t)) ... %twelth partial
+ (0.00800694943.*amplitude .* sin(26.*pi.*f.*t)) ... %thirteenth partial
+ (0.00463295187.*amplitude .* sin(28.*pi.*f.*t)); %fourteenth partial
x = x .* (1 + 0.1 .* sin(10.*pi.*t)); %volume vibrato
end

View File

@ -0,0 +1,45 @@
function x = generate_bassoon(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_BASSOON: returns a matrix of sampled waveform similar to
% a bassoon.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale
t = [1:n].*dt - phase;
f = frequency .* (1 + 0.0001 .* sin(4.*pi.*t)./t); %frequency vibrato
% generate proper fundamental and overtones
x = (0.0934091627.*amplitude .* sin(2.*pi.*f.*t)) ... %fundamental (first partial)
+ (0.0257187994.*amplitude .* sin(4.*pi.*f.*t)) ... %second partial
+ (0.120530806.*amplitude .* sin(6.*pi.*f.*t)) ... %third partial
+ (amplitude .* sin(8.*pi.*f.*t)) ... %fourth partial
+ (0.216745656.*amplitude .* sin(10.*pi.*f.*t)) ... %fifth partial
+ (0.0561137441.*amplitude .* sin(12.*pi.*f.*t)) ... %sixth partial
+ (0.0300031596.*amplitude .* sin(14.*pi.*f.*t)) ... %seventh partial
+ (0.0863949447.*amplitude .* sin(16.*pi.*f.*t)) ... %eighth partial
+ (0.0574533965.*amplitude .* sin(18.*pi.*f.*t)) ... %ninth partial
+ (0.0337819905.*amplitude .* sin(20.*pi.*f.*t)) ... %tenth partial
+ (0.0576176935.*amplitude .* sin(22.*pi.*f.*t)) ... %eleventh partial
+ (0.0107298578.*amplitude .* sin(24.*pi.*f.*t)) ... %twelth partial
+ (0.00582622433.*amplitude .* sin(26.*pi.*f.*t)) ... %thirteenth partial
+ (0.00540916272.*amplitude .* sin(28.*pi.*f.*t)) ... %fourteenth partial
+ (0.00615481833.*amplitude .* sin(30.*pi.*f.*t)) ... %fifteenth partial
+ (0.00480252765.*amplitude .* sin(32.*pi.*f.*t)) ... %sixteenth partial
+ (0.0100473934.*amplitude .* sin(34.*pi.*f.*t)) ... %seventeenth partial
+ (0.00528278041.*amplitude .* sin(36.*pi.*f.*t)); %eighteenth partial
x = x .* (1 + 0.1 .* sin(4.*pi.*t)); %volume vibrato
end

View File

@ -0,0 +1,38 @@
function x = generate_clarinet(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_CLARINET: returns a matrix of sampled waveform similar to
% a clarinet.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale
t = [1:n].*dt - phase;
f = frequency; %clarinets play without vibrato
% generate proper fundamental and overtones. Note that the clarinet has
% heavily suppressed odd-numbered partials
x = (amplitude .* sin(2.*pi.*f.*t)) ... %fundamental (first partial)
+ (0.00290397158.*amplitude .* sin(4.*pi.*f.*t)) ... %second partial
+ (0.368654023.*amplitude .* sin(6.*pi.*f.*t)) ... %third partial
+ (0.0733323309.*amplitude .* sin(8.*pi.*f.*t)) ... %fourth partial
+ (0.299729339.*amplitude .* sin(10.*pi.*f.*t)) ... %fifth partial
+ (0.0483901284.*amplitude .* sin(12.*pi.*f.*t)) ... %sixth partial
+ (0.0941300303.*amplitude .* sin(14.*pi.*f.*t)) ... %seventh partial
+ (0.033165423.*amplitude .* sin(16.*pi.*f.*t)) ... %eighth partial
+ (0.00803526117.*amplitude .* sin(18.*pi.*f.*t)) ... %ninth partial
+ (0.0131383569.*amplitude .* sin(20.*pi.*f.*t)); %tenth partial
x = x .* (1 + 0.05 .* sin(10.*pi.*t)); %slight volume vibrato added for character
end

View File

@ -0,0 +1,34 @@
function x = generate_flute(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_FLUTE: returns a matrix of sampled waveform similar to
% a flute.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale and frequency
t = [1:n].*dt - phase;
f = frequency .* (1 + 0.0002 .* sin(7.*pi.*t)./t); %frequency vibrato
% generate proper fundamental and overtones
x = (amplitude .* sin(4.*pi.*f.*t)) ... %fundamental (first partial)
+ (0.396821591.*amplitude .* sin(4.*pi.*f.*t)) ... %second partial
+ (0.157568887.*amplitude .* sin(6.*pi.*f.*t)) ... %third partial
+ (0.151279648.*amplitude .* sin(8.*pi.*f.*t)) ... %fourth partial
+ (0.106818975.*amplitude .* sin(10.*pi.*f.*t)) ... %fifth partial
+ (0.0138755668.*amplitude .* sin(12.*pi.*f.*t)) ... %sixth partial
+ (0.0100279037.*amplitude .* sin(14.*pi.*f.*t)); %seventh partial
x = x .* (1 + 0.25 .* sin(7.*pi.*t)); %volume vibrato
end

View File

@ -0,0 +1,41 @@
function x = generate_horn(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_HORN: returns a matrix of sampled waveform similar to
% a horn.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale
t = [1:n].*dt - phase;
f = frequency .* (1 + 0.0002 .* sin(4.*pi.*t)./t); %frequency vibrato
% generate proper fundamental and overtones
x = (0.21707879.*amplitude .* sin(2.*pi.*f.*t)) ... %fundamental (first partial)
+ (amplitude .* sin(4.*pi.*f.*t)) ... %second partial
+ (0.234667056.*amplitude .* sin(6.*pi.*f.*t)) ... %third partial
+ (0.088606568.*amplitude .* sin(8.*pi.*f.*t)) ... %fourth partial
+ (0.0864485981.*amplitude .* sin(10.*pi.*f.*t)) ... %fifth partial
+ (0.0275181724.*amplitude .* sin(12.*pi.*f.*t)) ... %sixth partial
+ (0.0472968588.*amplitude .* sin(14.*pi.*f.*t)) ... %seventh partial
+ (0.0246462876.*amplitude .* sin(16.*pi.*f.*t)) ... %eighth partial
+ (0.00816134476.*amplitude .* sin(18.*pi.*f.*t)) ... %ninth partial
+ (0.00691199377.*amplitude .* sin(20.*pi.*f.*t)) ... %tenth partial
+ (0.00494872793.*amplitude .* sin(22.*pi.*f.*t)) ... %eleventh partial
+ (0.0048026999.*amplitude .* sin(24.*pi.*f.*t)) ... %twelth partial
+ (0.00335864486.*amplitude .* sin(26.*pi.*f.*t)) ... %thirteenth partial
+ (0.00262850467.*amplitude .* sin(28.*pi.*f.*t)); %fourteenth partial
x = x .* (1 + 0.05 .* sin(2.*pi.*t)); %volume vibrato
end

View File

@ -0,0 +1,37 @@
function x = generate_oboe(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_OBOE: returns a matrix of sampled waveform similar to
% an oboe.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale
t = [1:n].*dt - phase;
f = frequency .* (1 + 0.0001 .* sin(10.*pi.*t)./t); %frequency vibrato
% generate proper fundamental and overtones
x = (0.274577037.*amplitude .* sin(2.*pi.*f.*t)) ... %fundamental (first partial)
+ (0.612336031.*amplitude .* sin(4.*pi.*f.*t)) ... %second partial
+ (amplitude .* sin(6.*pi.*f.*t)) ... %third partial
+ (0.105870314.*amplitude .* sin(8.*pi.*f.*t)) ... %fourth partial
+ (0.00825325944.*amplitude .* sin(10.*pi.*f.*t)) ... %fifth partial
+ (0.0767380354.*amplitude .* sin(12.*pi.*f.*t)) ... %sixth partial
+ (0.0381430831.*amplitude .* sin(14.*pi.*f.*t)) ... %seventh partial
+ (0.010765121.*amplitude .* sin(16.*pi.*f.*t)) ... %eighth partial
+ (0.0024454102.*amplitude .* sin(18.*pi.*f.*t)) ... %ninth partial
+ (0.00963544782.*amplitude .* sin(20.*pi.*f.*t)); %tenth partial
x = x .* (1 + 0.1 .* sin(10.*pi.*t)); %volume vibrato
end

View File

@ -0,0 +1,44 @@
function x = generate_organ(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_ORGAN: returns a matrix of sampled waveform similar to
% an organ.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale
t = [1:n].*dt - phase;
f = frequency; %no frequency vibrato
% generate proper fundamental and overtones
x = (0.605975181.*amplitude .* sin(2.*pi.*f.*t)) ... %fundamental (first partial)
+ (0.96669476.*amplitude .* sin(4.*pi.*f.*t)) ... %second partial
+ (0.509982853.*amplitude .* sin(6.*pi.*f.*t)) ... %third partial
+ (amplitude .* sin(8.*pi.*f.*t)) ... %fourth partial
+ (0.138074341.*amplitude .* sin(10.*pi.*f.*t)) ... %fifth partial
+ (0.397744776.*amplitude .* sin(12.*pi.*f.*t)) ... %sixth partial
+ (0.00348745968.*amplitude .* sin(14.*pi.*f.*t)) ... %seventh partial
+ (0.350983754.*amplitude .* sin(16.*pi.*f.*t)) ... %eighth partial
+ (0.0326368101.*amplitude .* sin(18.*pi.*f.*t)) ... %ninth partial
+ (0.0121770467.*amplitude .* sin(20.*pi.*f.*t)) ... %tenth partial
+ (0.000406870296.*amplitude .* sin(22.*pi.*f.*t)) ... %eleventh partial
+ (0.0440001162.*amplitude .* sin(24.*pi.*f.*t)) ... %twelth partial
+ (0.00299340289.*amplitude .* sin(26.*pi.*f.*t)) ... %thirteenth partial
+ (0.00767241129.*amplitude .* sin(28.*pi.*f.*t)) ... %fourteenth partial
+ (0.00337121102.*amplitude .* sin(30.*pi.*f.*t)) ... %fifteenth partial
+ (0.0389432997.*amplitude .* sin(32.*pi.*f.*t)) ... %sixteenth partial
+ (0.00496963004.*amplitude .* sin(64.*pi.*f.*t)); %thirty-second partial
%no volume vibrato
end

View File

@ -0,0 +1,46 @@
function x = generate_saxophone(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_SAXOPHONE: returns a matrix of sampled waveform similar to
% a saxophone.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale
t = [1:n].*dt - phase;
f = frequency .* (1 + 0.0001 .* sin(9.*pi.*t)./t); %frequency vibrato
% generate proper fundamental and overtones
x = (0.64011635.*amplitude .* sin(2.*pi.*f.*t)) ... %fundamental (first partial)
+ (0.558462369.*amplitude .* sin(4.*pi.*f.*t)) ... %second partial
+ (amplitude .* sin(6.*pi.*f.*t)) ... %third partial
+ (0.156636999.*amplitude .* sin(8.*pi.*f.*t)) ... %fourth partial
+ (0.102886106.*amplitude .* sin(10.*pi.*f.*t)) ... %fifth partial
+ (0.289185376.*amplitude .* sin(12.*pi.*f.*t)) ... %sixth partial
+ (0.21277411.*amplitude .* sin(14.*pi.*f.*t)) ... %seventh partial
+ (0.108250745.*amplitude .* sin(16.*pi.*f.*t)) ... %eighth partial
+ (0.077212478.*amplitude .* sin(18.*pi.*f.*t)) ... %ninth partial
+ (0.285980527.*amplitude .* sin(20.*pi.*f.*t)) ... %tenth partial
+ (0.167644958.*amplitude .* sin(22.*pi.*f.*t)) ... %eleventh partial
+ (0.115479073.*amplitude .* sin(24.*pi.*f.*t)) ... %twelth partial
+ (0.0345740512.*amplitude .* sin(26.*pi.*f.*t)) ... %thirteenth partial
+ (0.0192987651.*amplitude .* sin(28.*pi.*f.*t)) ... %fourteenth partial
+ (0.0140386324.*amplitude .* sin(30.*pi.*f.*t)) ... %fifteenth partial
+ (0.0102938359.*amplitude .* sin(32.*pi.*f.*t)) ... %sixteenth partial
+ (0.0166338634.*amplitude .* sin(34.*pi.*f.*t)) ... %seventeenth partial
+ (0.0128019786.*amplitude .* sin(36.*pi.*f.*t)) ... %eighteenth partial
+ (0.00442408514.*amplitude .* sin(38.*pi.*f.*t)); %nineteenth partial
x = x .* (1 + 0.1 .* sin(9.*pi.*t)); %volume vibrato
end

View File

@ -0,0 +1,27 @@
function x = generate_shepardsCarillon(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_SHEPARDSCARILLON: returns a matrix of sampled waveform similar to
% tubular bells, doubled at octaves.
% Calls generate_tubularBells
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% generate proper tone
x = generate_tubularBells(amplitude/5, frequency/16, phase, fs, duration, duty) ... %4 octaves below
+ generate_tubularBells(amplitude/4, frequency/8, phase, fs, duration, duty) ... %3 octaves below
+ generate_tubularBells(amplitude/3, frequency/4, phase, fs, duration, duty) ... %2 octaves below
+ generate_tubularBells(amplitude/2, frequency/2, phase, fs, duration, duty) ... %1 octave below
+ generate_tubularBells(amplitude, frequency, phase, fs, duration, duty) ... %unison
+ generate_tubularBells(amplitude/2, frequency*2, phase, fs, duration, duty) ... %1 octave above
+ generate_tubularBells(amplitude/3, frequency*4, phase, fs, duration, duty) ... %2 octaves above
+ generate_tubularBells(amplitude/4, frequency*8, phase, fs, duration, duty) ... %3 octaves above
+ generate_tubularBells(amplitude/5, frequency*16, phase, fs, duration, duty); %4 octaves above
end

View File

@ -0,0 +1,33 @@
function x = generate_shepardsOrgan(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_SHEPARDSORGAN: returns a matrix of sampled waveform similar to
% an organ, doubled at octaves.
% Calls generate_organ
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% generate proper tone
x = generate_organ(amplitude/8, frequency/128, phase, fs, duration, duty) ... %7 octaves below
+ generate_organ(amplitude/7, frequency/64, phase, fs, duration, duty) ... %6 octaves below
+ generate_organ(amplitude/6, frequency/32, phase, fs, duration, duty) ... %5 octaves below
+ generate_organ(amplitude/5, frequency/16, phase, fs, duration, duty) ... %4 octaves below
+ generate_organ(amplitude/4, frequency/8, phase, fs, duration, duty) ... %3 octaves below
+ generate_organ(amplitude/3, frequency/4, phase, fs, duration, duty) ... %2 octaves below
+ generate_organ(amplitude/2, frequency/2, phase, fs, duration, duty) ... %1 octave below
+ generate_organ(amplitude, frequency, phase, fs, duration, duty) ... %unison
+ generate_organ(amplitude/2, frequency*2, phase, fs, duration, duty) ... %1 octave above
+ generate_organ(amplitude/3, frequency*4, phase, fs, duration, duty) ... %2 octaves above
+ generate_organ(amplitude/4, frequency*8, phase, fs, duration, duty) ... %3 octaves above
+ generate_organ(amplitude/5, frequency*16, phase, fs, duration, duty) ... %4 octaves above
+ generate_organ(amplitude/6, frequency*32, phase, fs, duration, duty) ... %5 octaves above
+ generate_organ(amplitude/7, frequency*64, phase, fs, duration, duty) ... %6 octaves above
+ generate_organ(amplitude/8, frequency*128, phase, fs, duration, duty); %7 octaves above
end

View File

@ -0,0 +1,33 @@
function x = generate_shepardsStrings(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_SHEPARDSSTRINGS: returns a matrix of sampled waveform similar to
% arco strings, doubled at octaves.
% Calls generate_arcoStrings
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% generate proper tone
x = generate_arcoStrings(amplitude/8, frequency/128, phase, fs, duration, duty) ... %7 octaves below
+ generate_arcoStrings(amplitude/7, frequency/64, phase, fs, duration, duty) ... %6 octaves below
+ generate_arcoStrings(amplitude/6, frequency/32, phase, fs, duration, duty) ... %5 octaves below
+ generate_arcoStrings(amplitude/5, frequency/16, phase, fs, duration, duty) ... %4 octaves below
+ generate_arcoStrings(amplitude/4, frequency/8, phase, fs, duration, duty) ... %3 octaves below
+ generate_arcoStrings(amplitude/3, frequency/4, phase, fs, duration, duty) ... %2 octaves below
+ generate_arcoStrings(amplitude/2, frequency/2, phase, fs, duration, duty) ... %1 octave below
+ generate_arcoStrings(amplitude, frequency, phase, fs, duration, duty) ... %unison
+ generate_arcoStrings(amplitude/2, frequency*2, phase, fs, duration, duty) ... %1 octave above
+ generate_arcoStrings(amplitude/3, frequency*4, phase, fs, duration, duty) ... %2 octaves above
+ generate_arcoStrings(amplitude/4, frequency*8, phase, fs, duration, duty) ... %3 octaves above
+ generate_arcoStrings(amplitude/5, frequency*16, phase, fs, duration, duty) ... %4 octaves above
+ generate_arcoStrings(amplitude/6, frequency*32, phase, fs, duration, duty) ... %5 octaves above
+ generate_arcoStrings(amplitude/7, frequency*64, phase, fs, duration, duty) ... %6 octaves above
+ generate_arcoStrings(amplitude/8, frequency*128, phase, fs, duration, duty); %7 octaves above
end

View File

@ -0,0 +1,49 @@
function x = generate_trumpet(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_TRUMPET: returns a matrix of sampled waveform similar to
% a trumpet.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale
t = [1:n].*dt - phase;
f = frequency .* (1 + 0.00005 .* sin(10.*pi.*t)./t); %frequency vibrato
% generate proper fundamental and overtones
x = (0.802698298.*amplitude .* sin(2.*pi.*f.*t)) ... %fundamental (first partial)
+ (amplitude .* sin(4.*pi.*f.*t)) ... %second partial
+ (0.700319932.*amplitude .* sin(6.*pi.*f.*t)) ... %third partial
+ (0.748098515.*amplitude .* sin(8.*pi.*f.*t)) ... %fourth partial
+ (0.909272003.*amplitude .* sin(10.*pi.*f.*t)) ... %fifth partial
+ (0.471477725.*amplitude .* sin(12.*pi.*f.*t)) ... %sixth partial
+ (0.200863214.*amplitude .* sin(14.*pi.*f.*t)) ... %seventh partial
+ (0.264578051.*amplitude .* sin(16.*pi.*f.*t)) ... %eighth partial
+ (0.282234698.*amplitude .* sin(18.*pi.*f.*t)) ... %ninth partial
+ (0.128787879.*amplitude .* sin(20.*pi.*f.*t)) ... %tenth partial
+ (0.100688156.*amplitude .* sin(22.*pi.*f.*t)) ... %eleventh partial
+ (0.0874984909.*amplitude .* sin(24.*pi.*f.*t)) ... %twelth partial
+ (0.0488047809.*amplitude .* sin(26.*pi.*f.*t)) ... %thirteenth partial
+ (0.0261680551.*amplitude .* sin(28.*pi.*f.*t)) ... %fourteenth partial
+ (0.0186224798.*amplitude .* sin(30.*pi.*f.*t)) ... %fifteenth partial
+ (0.0255342267.*amplitude .* sin(32.*pi.*f.*t)) ... %sixteenth partial
+ (0.0111674514.*amplitude .* sin(34.*pi.*f.*t)) ... %seventeenth partial
+ (0.010020524.*amplitude .* sin(36.*pi.*f.*t)) ... %eighteenth partial
+ (0.00694192925.*amplitude .* sin(38.*pi.*f.*t)) ... %nineteenth partial
+ (0.00307859471.*amplitude .* sin(40.*pi.*f.*t)) ... %twentieth partial
+ (0.00338041772.*amplitude .* sin(42.*pi.*f.*t)) ... %twentyfirst partial
+ (0.0026862248.*amplitude .* sin(44.*pi.*f.*t)); %twentysecond partial
x = x .* (1 + 0.02 .* sin(10.*pi.*t)); %volume vibrato
end

View File

@ -0,0 +1,38 @@
function x = generate_tubularBells(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_TUBULARBELLS: returns a matrix of sampled waveform similar to
% a tubular bell.
% CONTRIBUTORS:
% Brandon Roberts: Original author
% MuseScore: Reference source for overtone information
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for instruments
% amplitude decays exponentially at varying rates for different paritals
% setup needed variables
n = fs * duration; % total data points
dt = 1 / fs; % space between samples
% initialize template time scale
t = [1:n].*dt - phase;
f = frequency; %no frequency vibrato
% generate proper fundamental and overtones
x = (0.105668016.*amplitude .* sin(pi.*f.*t))./(2.^(t./10)) ... %hum tone
+ (0.143724696.*amplitude .* sin(2.*pi.*f.*t))./(2.^(t./5)) ... %strike tone
+ (0.12.*amplitude .* sin(12./5.*pi.*f.*t))./(2.^(t./3)) ... %minor third overtone
+ (0.10.*amplitude .* sin(3.*pi.*f.*t))./(2.^(t./2.5)) ... %perfect fifth overtone
+ (0.8.*amplitude .* sin(4.*pi.*f.*t))./(2.^(t./2)) ... %perfect octave overtone
+ (0.6.*amplitude .* sin(5.*pi.*f.*t))./(2.^(t./1.5)) ... %major third overtone
+ (0.4.*amplitude .* sin(8.*pi.*f.*t))./(2.^(t)) ... %second perfect fifth overtone
+ (0.4.*amplitude .* sin(2.2.*pi.*f.*t))./(2.^(4.*t)) ... %transient 1
+ (0.4.*amplitude .* sin(1.8.*pi.*f.*t))./(2.^(8.*t)) ... %transient 2
+ (0.4.*amplitude .* sin(2.7.*pi.*f.*t))./(2.^(10.*t));%transient 3
x = x .* (1 + 0.02 .* sin(10.*pi.*t)); %volume vibrato
end

38
src/LFO/lfo_freq_saw.m Normal file
View File

@ -0,0 +1,38 @@
function output = lfo_freq_saw(amplitude, frequency, phase, fs, duration, input)
%LFO_FREQ_SAW Modulates the frequency of an input with a saw LFO
% CONTRIBUTORS:
% Neelay Joglekar: Original author
% SOURCES:
% Code inspired by Benjamin Liou's lfo functions
% Code also inspired by Darren and Anne's pitch envelopes
% Source for frequency modulation equation:
% https://dsp.stackexchange.com/questions/2349/help-with-algorithm-for-modulating-oscillator-pitch-using-lfo
% DOCUMENTATION:
% Frequency is modulated by saw wave with given amplitude (in octaves, not Hz)
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
% create output array
output = zeros([1, n]);
x = 0.0; % the theoretical input index if the input were not discrete
% populate output
for i = 1:n
t = i * dt; % time at the i'th sample
% Increment x based off of saw wave output
omega_ratio = 2 ^ (amplitude * (2 * mod((t - phase / (2*pi)) * frequency, 1) - 1));
x = mod(x + omega_ratio, n);
% Linearly interpolate the actual indicies adjacent to x
% to get an output value
x_0 = floor(x) + 1;
x_1 = mod(x_0 + 1, n) + 1;
output(i) = (input(x_1) - input(x_0)) * (x - x_0) + input(x_0);
end
end

39
src/LFO/lfo_freq_sine.m Normal file
View File

@ -0,0 +1,39 @@
function output = lfo_freq_sine(amplitude, frequency, phase, fs, duration, input)
%LFO_FREQ_SINE Modulates the frequency of an input with a sine LFO
% CONTRIBUTORS:
% Neelay Joglekar: Original author
% SOURCES:
% Code inspired by Benjamin Liou's lfo functions
% Code also inspired by Darren and Anne's pitch envelopes
% Source for frequency modulation equation:
% https://dsp.stackexchange.com/questions/2349/help-with-algorithm-for-modulating-oscillator-pitch-using-lfo
% DOCUMENTATION:
% Frequency is modulated by sine wave with given amplitude (in octaves, not Hz)
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
% create output array
output = zeros([1, n]);
x = 0.0; % the theoretical input index if the input were not discrete
% populate output
for i = 1:n
t = i * dt; % time at the i'th sample
% Increment x based off of sine wave output
omega_ratio = 2 ^ (amplitude * sin(2 * pi * frequency * t - phase));
x = mod(x + omega_ratio, n);
% Linearly interpolate the actual indicies adjacent to x
% to get an output value
x_0 = floor(x) + 1;
x_1 = mod(x_0 + 1, n) + 1;
output(i) = (input(x_1) - input(x_0)) * (x - x_0) + input(x_0);
end
end

38
src/LFO/lfo_freq_square.m Normal file
View File

@ -0,0 +1,38 @@
function output = lfo_freq_square(amplitude, frequency, phase, fs, duration, input)
%LFO_FREQ_SQUARE Modulates the frequency of an input with a square LFO
% CONTRIBUTORS:
% Neelay Joglekar: Original author
% SOURCES:
% Code inspired by Benjamin Liou's lfo functions
% Code also inspired by Darren and Anne's pitch envelopes
% Source for frequency modulation equation:
% https://dsp.stackexchange.com/questions/2349/help-with-algorithm-for-modulating-oscillator-pitch-using-lfo
% DOCUMENTATION:
% Frequency is modulated by square wave with given amplitude (in octaves, not Hz)
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
% create output array
output = zeros([1, n]);
x = 0.0; % the theoretical input index if the input were not discrete
% populate output
for i = 1:n
t = i * dt; % time at the i'th sample
% Increment x based off of square wave output
omega_ratio = 2 ^ (amplitude * (2 * round(mod((t - phase / (2*pi)) * frequency, 1)) - 1));
x = mod(x + omega_ratio, n);
% Linearly interpolate the actual indicies adjacent to x
% to get an output value
x_0 = floor(x) + 1;
x_1 = mod(x_0 + 1, n) + 1;
output(i) = (input(x_1) - input(x_0)) * (x - x_0) + input(x_0);
end
end

View File

@ -0,0 +1,23 @@
function y = distortion_filter(input, fs, LOW, MED, HIGH)
%Author: Jason Liang
%input: 1D array representing the sound signal in the time domain
%fs: sampling frequency
%low: lower bound of frequencies
%med: median of all frequencies
%high: upper bound of frequencies
%y: output signal
%This function distorts a signal based on the constant LOW; all
%frequencies in between the specified range are clipped by the constant
%LOW.
len = length(input);
f = fs*(-len/2:len/2-1)/len;
outputW = fftshift(fft(input));
for i = 1:length(outputW)
if ((LOW < abs(F(n))) && HIGH > abs(F(n)))
outputW(i) = outputW(i) / LOW;
end
end
y = real(ifft(fftshift(outputW)));
end

44
src/NotWorking/flanger.m Normal file
View File

@ -0,0 +1,44 @@
function output = flanger(input, time_delay, osc_freq, amp, Fs)
% DOCUMENTATION:
% FLANGER combines a single oscillating delayed signal with the original signal
% Interference between original and delayed signals create "flanging" effect
% Rocommedned delay time: 0-15 ms
% Recommended oscilating fequency: 0.1 - 5 Hz
% input: 1D array containing audio signal
% time_delay: maxinum value of the oscillating signal
% osc_freq: frequence of oscillation
% amp: amplitude of output signal
% fs: sampling frequency
% CONTRIBUTORS:
% Lance Zhu: Function Author
% SOURCES:
% Code inspired by information provided in:
% https://users.cs.cf.ac.uk/Dave.Marshall/CM0268/PDF/10_CM0268_Audio_FX.pdf
% create index array
len=length(input);
index=1:len;
% create reference wave to create oscillation
% taking only absoluted value for the reference wave
osc_wave = abs(sin(2*pi*index*(osc_freq/Fs)));
% convert delay in time to delay in samples
sample_delay=round(time_delay*Fs);
% create empty output array
output = zeros(len,1);
% Generating delay for each sample from reference oscillation wave
% start loop at sample_delay to make sure delayed sample is from t>=0
for i=sample_delay:len
% i_delay: delay for current sample
i_delay=round(osc_wave(i)*sample_delay);
% combine delayed sample with original sample
output(i) = (amp*input(i))+amp*(input(i-i_delay));
end

View File

@ -0,0 +1,49 @@
function x = generate_keyboard(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_KEYBOARD: returns a matrix of a sum of sine waves
% CONTRIBUTORS:
% Ryan Goh: author
% DOCUMENTATION:
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% amplitude, phase, and duty are not used in this function
% This function's purpose is to generate a wave that can simulate the sound of a digital keyboard.
% Sound is best suited for frequencies near the middle octave of the
% piano(261.6 - 523.2). Frequencies too high or too low do not sound
% similar to the intended sound.
% Referenced Arthur Lu and Benjamin Liou's generate sine function. Also
% adapted wave model from https://dsp.stackexchange.com/questions/46598/mathematical-equation-for-the-sound-wave-that-a-piano-makes
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
% initialize a one dimensional zero matrix to be populated
x = zeros(1, n);
% populate the matrix
for i = 1:n
t = i * dt; % time at the i'th sample
%wave model of keyboard sound.
%Original version from https://dsp.stackexchange.com/questions/46598/mathematical-equation-for-the-sound-wave-that-a-piano-makes
y = sin(2 * pi * frequency * t) * exp(-0.002 * 2 * pi * frequency * t) ...
+ (sin(3*2*pi*frequency*t)*exp(-0.002 * 2 * pi * frequency * t)) / 2 ...
+ (sin(4*2*pi*frequency*t)*exp(-0.002 * 2 * pi * frequency * t)) / 8 ...
+ (sin(5 * 2 * pi * frequency * t) * exp(-0.002 * 2 * pi * frequency * t)) / 16 ...
+ (sin(6 * 2 * pi * frequency * t) * exp(-0.002 * 2 * pi * frequency * t)) / 25 ...
+ (sin(7 * 2 * pi * frequency * t) * exp(-0.002 * 2 * pi * frequency * t)) / 50 ...
+ (sin(8 * 2 * pi * frequency * t) * exp(-0.002 * 2 * pi * frequency * t)) / 100 ...
+ (sin(9 * 2 * pi * frequency * t) * exp(-0.002 * 2 * pi * frequency * t)) / 200;
%Further adjustments to improve sound
y = y + y * y * y;
y = y * (1 + 16*t*exp(-1000*t));
x(i) = 0.15 * y;%multiplied by fixed amplitude value of 0.15
end
end

View File

@ -0,0 +1,66 @@
function x = generate_lullaby(amplitude, frequency, phase, fs, duration, duty)
% Generates sine waves that play 'twinkle twinkle little star'
% by using the frequency parameter as the root note for the melody.
% Currently the duty and duration parameters are not used within the
% function as there is no need for the former and it is currently
% difficult to constrain the melody duration based on user input.
% A function such as this one could be useful as a demo for what a
% melody sounds like on a synthesizer, and could even find use
% in toys designed to help small children sleep.
% CONTRIBUTORS:
% generate_lullaby created by Gabriel Diaz
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty is a number between 0 and 1
%NOTE: whatever's passed as the duration parameter doesn't get used at
%the moment, since it's currently difficult to sync every note in the
%melody to play in shorter duartions such that the entire song lasts about
%as long as 'duration'
duration = 0;
duty = 0; %duty also isn't used in this function
%current durations that the song will work with
note_duration = 0.4;
song_duration = note_duration * 48;
%frequency multiples for all notes in melody, assuming that frequency is
%the root note of this chord:
maj_second_freq = frequency * 1.125;
maj_third_freq = frequency * 1.25;
fourth_freq = frequency * 1.33;
fifth_freq = frequency * 1.5;
maj_sixth_freq = frequency * 1.7;
% initialize local variables from input arguments
n = fs * note_duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
t = [1:n].*dt - phase; %initialize time scale template
%sine waves for every note in 'frequency's' respective major scale:
first = amplitude * sin(2 * pi * frequency * t - phase);
second = amplitude * sin(2 * pi * maj_second_freq * t - phase);
third = amplitude * sin(2 * pi * maj_third_freq * t - phase);
fourth = amplitude * sin(2 * pi * fourth_freq * t - phase);
fifth = amplitude * sin(2 * pi * fifth_freq * t - phase);
sixth = amplitude * sin(2 * pi * maj_sixth_freq * t - phase);
%each one of the three melodies making up the song:
melody1 = [first,first,fifth,fifth,sixth,sixth,fifth,fifth]; %size 8 notes
melody2 = [fourth,fourth,third,third,second,second,first,first]; %size 8 notes
melody3 = [fifth,fifth,fourth,fourth,third,third,second,second]; %size 8 notes
% populate the matrix(total size is 44 notes wide, which means the song's
% duration must fit within the specified duration parameter
x = [melody1,melody2,melody3,melody3,melody1,melody2];
%For testing
%t = 0:dt:song_duration;
%t(n) = [];
%plot(t, x);
%sound(x, fs);
end

View File

@ -0,0 +1,37 @@
function x = lfo_square(amplitude, frequency, phase, fs, duration, input)
% LFO_SQUARE: modulates an input matrix to a square
% CONTRIBUTORS:
% Aleksandra Desens: Author
% DOCUMENTATION:
% phase shift is in number of periods
% fs is the sampling frequency - below 20 Hz
% duration - same as input
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
dt = 1 / fs; % sampling period: time between two sample points
% initialize a one dimensional zero matrix to be populated
lfo = zeros(1, n);
% populate the matrix
for i = 1:n
t = i * dt;
duty = 0.5; % duty of 0.5 generates a square wave
st = mod((frequency * t - phase), 1);
if (st < duty)
lfo(i) = amplitude;
else
lfo(i) = -amplitude;
end
% modulate input
x = lfo .* input;
end

View File

@ -7,7 +7,7 @@
%Pass-through function used by app %Pass-through function used by app
function output = AmpEnvelopeSelect(input, Fs, attack,decay,sustain,release,number) function output = AmpEnvelopeSelect(input, Fs, attack,decay,sustain,release,number)
if(number == "Option 1") if(number == "Linear")
output = DarellAmplitudeEnvelope(input, Fs, attack,decay,sustain,release); output = DarellAmplitudeEnvelope(input, Fs, attack,decay,sustain,release);
else else
output = input; output = input;

View File

@ -7,18 +7,22 @@
%Pass-through function used by app %Pass-through function used by app
function output = FilterSelect(input,Fs,LOW,MED,HIGH,number) function output = FilterSelect(input,Fs,LOW,MED,HIGH,number)
if(number == "Option 1") if(number == "IdealBandPass")
output = DarellbandpassFilter(input,Fs,LOW,MED,HIGH); output = DarellbandpassFilter(input,Fs,LOW,MED,HIGH);
elseif(number == "Option 2") elseif(number == "AmplifyRange")
output = amplifyFreqRange(input, Fs, LOW, MED, HIGH); output = amplifyFreqRange(input, Fs, LOW, MED, HIGH);
elseif(number == "Option 3") elseif(number == "EpicEffect")
output = epic_effect_schluep(input, Fs, LOW, MED, HIGH); output = epic_effect_schluep(input, Fs, LOW, MED, HIGH);
elseif(number == "Option 4") elseif(number == "MuffledEffect")
output = muffled_effect_schluep(input, Fs, LOW, MED, HIGH); output = muffled_effect_schluep(input, Fs, LOW, MED, HIGH);
elseif(number == "Option 5") elseif(number == "SeparatePrevalent")
output = seperate_prevalent_schluep(input, Fs, LOW, MED, HIGH); output = seperate_prevalent_schluep(input, Fs, LOW, MED, HIGH);
elseif(number == "Option 6") elseif(number == "IdealBandReject")
output = bandreject_filter(input, Fs, LOW, HIGH); output = bandreject_filter(input, Fs, LOW, HIGH);
elseif(number == "EnchanceTarget")
output = AnuragEnhanceTarget(input, Fs, LOW, MED, HIGH);
elseif(number == "DampenTarget")
output = AnuragDampenTarget(input, Fs, LOW, MED, HIGH);
else else
output = input; output = input;
end end

View File

@ -9,10 +9,16 @@
function output = LFOSelect(amplitude, frequency, phase, fs, duration, input,number) function output = LFOSelect(amplitude, frequency, phase, fs, duration, input,number)
%UNTITLED Summary of this function goes here %UNTITLED Summary of this function goes here
% Detailed explanation goes here % Detailed explanation goes here
if(number == "Option 1") if(number == "AmplitudeSawtooth")
output = lfo_sawtooth(amplitude, frequency, phase, fs, duration, input); output = lfo_sawtooth(amplitude, frequency, phase, fs, duration, input);
elseif(number == "Option 2") elseif(number == "AmplitudeSine")
output = lfo_sine(amplitude, frequency, phase, fs, duration, input); output = lfo_sine(amplitude, frequency, phase, fs, duration, input);
elseif(number == "FrequencySine")
output = lfo_freq_sine(amplitude, frequency, phase, fs, duration, input);
elseif(number == "FrequencySquare")
output = lfo_freq_square(amplitude, frequency, phase, fs, duration, input);
elseif(number == "FrequencySawtooth")
output = lfo_freq_saw(amplitude, frequency, phase, fs, duration, input);
else else
output = input; output = input;
end end

View File

@ -7,9 +7,9 @@
%Pass-through function used by app %Pass-through function used by app
function output = OffsetSelect(input,value,number) function output = OffsetSelect(input,value,number)
if(number == "Option 1") if(number == "Echo")
output = Meghaj_Echo(input, value); output = Meghaj_Echo(input, value);
elseif(number == "Option 2") elseif(number == "PitchOffset")
output = Petha_Hsu_PitchOffset(input, value); output = Petha_Hsu_PitchOffset(input, value);
else else
output = input; output = input;

View File

@ -7,9 +7,9 @@
%Pass-through function used by app %Pass-through function used by app
function output = PitchEnvelopeSelect(input, Fs, attack,decay,sustain,release,number) function output = PitchEnvelopeSelect(input, Fs, attack,decay,sustain,release,number)
if(number == "Option 1") if(number == "Logarithmic")
output = DarellAnnePitchEnvelope(input, Fs, attack,decay,sustain,release); output = DarellAnnePitchEnvelope(input, Fs, attack,decay,sustain,release);
elseif(number == "Option 2") elseif(number == "Linear")
output = DarellAnneLinearPitchEnvelope(input, Fs, attack,decay,sustain,release); output = DarellAnneLinearPitchEnvelope(input, Fs, attack,decay,sustain,release);
else else
output = input; output = input;

View File

@ -1,26 +1,62 @@
%Written by Darell %Written by Darell, edited by Arthur Lu
% CONTRIBUTORS: % CONTRIBUTORS:
% Person1: Darell % Person1: Darell
% Person2: Arthur Lu
% DOCUMENTATION: % DOCUMENTATION:
%Pass-through function used by app %Pass-through function used by app
function output = SoundGeneratorSelect(amplitude, frequency, phase, fs, duration, duty,number) function output = SoundGeneratorSelect(amplitude, frequency, phase, fs, duration, duty,number)
if(number == "Option 1") if(number == "Sine")
output = generate_sine(amplitude, frequency, phase, fs, duration, duty); output = generate_sine(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Option 2") elseif(number == "Square")
output = generate_square(amplitude, frequency, phase, fs, duration, duty); output = generate_square(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Option 3") elseif(number == "Triangle")
output = generate_triangle(amplitude, frequency, phase, fs, duration, duty); output = generate_triangle(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Option 4") elseif(number == "Sawtooth")
output = generate_sawtooth(amplitude, frequency, phase, fs, duration, duty); output = generate_sawtooth(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Option 5") elseif(number == "WhiteNoise")
output = generate_white(amplitude, fs, duration); output = generate_white(amplitude, fs, duration);
elseif(number == "Option 6") elseif(number == "HalfCircle")
output = generate_halfCircles(amplitude, frequency, phase, fs, duration, duty); output = generate_halfCircles(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Trapezoid")
output = generate_trapezoid(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Pulse")
output = generate_pulse(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Cosine")
output = generate_cosine(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Heartbeat")
output = generate_heartbeat(amplitude, frequency, phase, fs, duration, duty);
% instruments:
elseif(number == "ArcoStrings")
output = generate_arcoStrings(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Bassoon")
output = generate_bassoon(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Clarinet")
output = generate_clarinet(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Flute")
output = generate_flute(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Horn")
output = generate_horn(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Oboe")
output = generate_oboe(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Organ")
output = generate_organ(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Saxophone")
output = generate_saxophone(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "ShepardsCarillon")
output = generate_shepardsCarillon(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "ShepardsOrgan")
output = generate_shepardsOrgan(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "ShepardsStrings")
output = generate_shepardsStrings(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "Trumpet")
output = generate_trumpet(amplitude, frequency, phase, fs, duration, duty);
elseif(number == "TubularBells")
output = generate_tubularBells(amplitude, frequency, phase, fs, duration, duty);
else else
output = 0; output = zeros(1, fs * duration);
end end
end end