Merge branch 'main' into DarellsAnnex
This commit is contained in:
commit
f1428720c0
16
README.md
16
README.md
@ -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
BIN
src/.DS_Store
vendored
Binary file not shown.
33
src/Filter/AnuragDampenTarget.m
Normal file
33
src/Filter/AnuragDampenTarget.m
Normal 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
|
34
src/Filter/AnuragEnhanceTarget.m
Normal file
34
src/Filter/AnuragEnhanceTarget.m
Normal 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
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
n = size(input, 2);
|
||||||
|
|
||||||
|
non_stereophonic = input;
|
||||||
|
|
||||||
|
if (n == 1) || (n == 2)
|
||||||
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
|
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
|
||||||
% by just taking the first column of data.
|
% by just taking the first column of data.
|
||||||
|
non_stereophonic = transpose(non_stereophonic);
|
||||||
|
end
|
||||||
|
|
||||||
Len = length(non_stereophonic);
|
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
|
@ -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.
|
||||||
|
|
||||||
|
n = size(input, 2);
|
||||||
|
|
||||||
|
non_stereophonic = input;
|
||||||
|
|
||||||
|
if (n == 1) || (n == 2)
|
||||||
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
|
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
|
||||||
% by just taking the first column of data.
|
% by just taking the first column of data.
|
||||||
|
non_stereophonic = transpose(non_stereophonic);
|
||||||
|
end
|
||||||
|
|
||||||
Len = length(non_stereophonic);
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
n = size(input, 2);
|
||||||
|
|
||||||
|
non_stereophonic = input;
|
||||||
|
|
||||||
|
if (n == 1) || (n == 2)
|
||||||
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
|
non_stereophonic = input(:, 1); % Removes the sterophonic property of the input sound
|
||||||
% by just taking the first column of data.
|
% by just taking the first column of data.
|
||||||
|
non_stereophonic = transpose(non_stereophonic);
|
||||||
|
end
|
||||||
|
|
||||||
Len = length(non_stereophonic);
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
25
src/Generators/generate_cosine.m
Normal file
25
src/Generators/generate_cosine.m
Normal 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
|
46
src/Generators/generate_heartbeat.m
Normal file
46
src/Generators/generate_heartbeat.m
Normal 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
|
33
src/Generators/generate_pulse.m
Normal file
33
src/Generators/generate_pulse.m
Normal 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
|
58
src/Generators/generate_trapezoid.m
Normal file
58
src/Generators/generate_trapezoid.m
Normal 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
|
@ -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"];
|
||||||
|
@ -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
|
@ -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;
|
41
src/Instruments/generate_arcoStrings.m
Normal file
41
src/Instruments/generate_arcoStrings.m
Normal 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
|
||||||
|
|
45
src/Instruments/generate_bassoon.m
Normal file
45
src/Instruments/generate_bassoon.m
Normal 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
|
||||||
|
|
38
src/Instruments/generate_clarinet.m
Normal file
38
src/Instruments/generate_clarinet.m
Normal 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
|
||||||
|
|
34
src/Instruments/generate_flute.m
Normal file
34
src/Instruments/generate_flute.m
Normal 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
|
||||||
|
|
41
src/Instruments/generate_horn.m
Normal file
41
src/Instruments/generate_horn.m
Normal 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
|
||||||
|
|
37
src/Instruments/generate_oboe.m
Normal file
37
src/Instruments/generate_oboe.m
Normal 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
|
||||||
|
|
44
src/Instruments/generate_organ.m
Normal file
44
src/Instruments/generate_organ.m
Normal 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
|
||||||
|
|
46
src/Instruments/generate_saxophone.m
Normal file
46
src/Instruments/generate_saxophone.m
Normal 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
|
||||||
|
|
27
src/Instruments/generate_shepardsCarillon.m
Normal file
27
src/Instruments/generate_shepardsCarillon.m
Normal 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
|
||||||
|
|
33
src/Instruments/generate_shepardsOrgan.m
Normal file
33
src/Instruments/generate_shepardsOrgan.m
Normal 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
|
||||||
|
|
33
src/Instruments/generate_shepardsStrings.m
Normal file
33
src/Instruments/generate_shepardsStrings.m
Normal 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
|
||||||
|
|
49
src/Instruments/generate_trumpet.m
Normal file
49
src/Instruments/generate_trumpet.m
Normal 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
|
||||||
|
|
38
src/Instruments/generate_tubularBells.m
Normal file
38
src/Instruments/generate_tubularBells.m
Normal 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
38
src/LFO/lfo_freq_saw.m
Normal 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
39
src/LFO/lfo_freq_sine.m
Normal 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
38
src/LFO/lfo_freq_square.m
Normal 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
|
23
src/NotWorking/distortion_filter.m
Normal file
23
src/NotWorking/distortion_filter.m
Normal 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
44
src/NotWorking/flanger.m
Normal 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
|
49
src/NotWorking/generate_keyboard.m
Normal file
49
src/NotWorking/generate_keyboard.m
Normal 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
|
66
src/NotWorking/generate_lullaby.m
Normal file
66
src/NotWorking/generate_lullaby.m
Normal 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
|
37
src/NotWorking/lfo_square.m
Normal file
37
src/NotWorking/lfo_square.m
Normal 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
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
else
|
elseif(number == "Trapezoid")
|
||||||
output = 0;
|
output = generate_trapezoid(amplitude, frequency, phase, fs, duration, duty);
|
||||||
end
|
elseif(number == "Pulse")
|
||||||
end
|
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
|
||||||
|
output = zeros(1, fs * duration);
|
||||||
|
end
|
||||||
|
end
|
Reference in New Issue
Block a user