Merge branch 'main' into DarellsAnnex

This commit is contained in:
darrll27 2021-12-06 15:26:58 -08:00 committed by GitHub
commit 8b76754943
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 287 additions and 39 deletions

View File

@ -2,18 +2,56 @@
Audio synthesizer project created by ECE 45 students, written using the MATLAB language and MATLAB GUI
## Contributors
Will add member names shortly
## Function Prototypes
Templates to create your own functions.
function x = generate_wave(amplitude, frequency, phase, fs, duration, duty)
### Wave generating function
```
function x = generate_WAVENAME(amplitude, frequency, phase, fs, duration, duty)
% GENERATE_WAVENAME: returns a matrix of sampled WAVENAME wave
fuction x = envelope(input, fs, period, attack , decay, sustain, release)
% CONTRIBUTORS:
% Person1: how you contributed
% Person2: how you contributed
% etc
% 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
YOUR CODE HERE
end
end
```
NOTE: duty does not apply to some functions (such as sinusoids)
### Envelope function
```
function x = envelope(input, fs, period, attack , decay, sustain, release)
```
where attack, decay, release are percentages between 0 to 1 of the period
sustain is the percentage of the amplitude it should sustain for
**envelope can be pitch or amplitude envelope**
### Filter function
```
function output_timedomain = Filter(input_soundin_timedomain, Fs, LOW, MED, HIGH)
```
where LOW, MED, HIGH are user-selected variables of any value.
**output should be in time domain for all functions (new sound)**

BIN
src/.DS_Store vendored

Binary file not shown.

View File

@ -40,4 +40,3 @@ x = DarellAmplitudeEnvelope(x, fs, attack,decay,sustain,release); %output new so
%play over 5 counts, should only hear 200hz
playtime = 5;
play_continuous(x, fs, playtime)

34
src/add_sine.m Normal file
View File

@ -0,0 +1,34 @@
function x = add_sine(amplitude, fundamental, harmonics, fs, duration)
% ADD_SINE: Additive sine wave synthesis
%CONTRIBUTORS:
%Benjamin Liou: Original author
% DOCUMENTATION:
% harmonics should ideally be a 1D matrix of:
% overtones: positive integers
% undertones: 1/ positive integers
% example: [1/2, 1, 2, 3]
% NOTE: pitch of the fundamental frequency will still be perceived even
% when the fundamental itself is missing. ex. [4,5,6]
% NOTE: it seems like when MATLAB's built in sound() takes in values,
% magnitudes over 1 get distorted.
% initialize local variables from input arguments
n = fs * duration; % number of samples (length of matrix)
% initialize a one dimensional zero matrix to be populated
x = zeros(1, n);
% populate matrix by adding sine waves
for harmonic = harmonics
x = x + generate_sine(1, fundamental * harmonic, 0, fs, duration);
end
% scale to amplitude
scalar = max(abs(x));
x = x / scalar * amplitude;
end

8
src/amplify.m Normal file
View File

@ -0,0 +1,8 @@
function output = amplify(input, multiplier)
%input: a 1D array representing the sound signal in the time domain
%multiplier: a scalar that multiplier all values in the input array to
% amplify or decrease the volume.
%Returns: input signal scaled by the multiplier in the time domain.
%Author: Conner Hsu
output = input*multiplier;
end

23
src/amplifyFreqRange.m Normal file
View File

@ -0,0 +1,23 @@
function output = amplifyFreqRange(input, fs, low, high, multiplier)
%Amplifies frequencies within a specified range, leaves all other
%frequencies the same.
%By Conner Hsu
%input: 1D array representing the sound signal in the time domain
%fs: sampling frequency
%low: a scalar representing the lower bound of frequencies to be amplified
%high: a scalar representing the upper bound of frequencies to be amplified
%multiplier: a scalar that multiplies frequencies between low and high
%Returns modified signal in the time domain.
len = length(input);
f = fs*(-len/2:len/2-1)/len;
outputW = fftshift(fft(input));
for i = 1:length(outputW)
if (low < abs(f(i)) && abs(f(i)) < high)
outputW(i) = outputW(i)*multiplier;
end
end
output = real(ifft(fftshift(outputW)));
end

40
src/generate_sawtooth.m Normal file
View File

@ -0,0 +1,40 @@
function x = generate_sawtooth(amplitude, frequency, phase, fs, duration, duty)
% generate_sawtooth: returns a matrix of sampled sawtooth wave
% CONTRIBUTORS:
% Ben Zhang: Function 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 is a number between 0 and 1
%duty does not apply for sawtooth wave
% 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
period = 1 / frequency; % period of the wave
% initialize a one dimensional zero matrix to be populated
x = zeros(1, n);
% populate the matrix
for i = 1:n
t = i * dt; % time of the i'th sample
st = mod(frequency * t - phase, 1); % Progression through cycle
slope = 2 * amplitude / period; % the incline slope from start to amplitude
mid = period / 2;
%part before the straght vertical line
if(st < mid)
x(i) = slope * st; % amplitude from start to +amplitude
%part after the straght vertical line
else
x(i) = slope * (st - 0.5) - amplitude; %amplitude from -amplitude to start
end
end

View File

@ -1,15 +1,28 @@
function x = generate_sine(amplitude, frequency, phase, fs, duration, duty)
%GENERATE_SINE:Arthur Lu returns a matrix of sampled sine wave, where the
% GENERATE_SINE: returns a matrix of sampled sine wave
% CONTRIBUTORS:
% Arthur Lu: Original author
% Benjamin Liou: refactoring and annotations
% DOCUMENTATION:
% phase shift is in number of periods
x = zeros(1, fs * duration);
A = amplitude;
f = frequency;
p = phase;
n = fs * duration;
dt = 1 / fs;
% fs is the sampling frequency: how many sample points per second
% duration is time in seconds
% duty does not apply for sinusoids
% 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) = A * sin(2 * pi * f * t - p);
t = i * dt; % time at the i'th sample
x(i) = amplitude * sin(2 * pi * frequency * t - phase);
end
end

View File

@ -1,19 +1,40 @@
function x = generate_square(amplitude, frequency, phase, fs, duration, duty)
%GENERATE_SINE:Arthur Lu returns a matrix of sampled sine wave, where the
% GENERATE_SQUARE: returns a matrix of sampled square wave
% CONTRIBUTORS:
% Arthur Lu: Original author
% Benjamin Liou: refactoring and annotations
% DOCUMENTATION:
% phase shift is in number of periods
x = zeros(1, fs * duration);
A = amplitude;
f = frequency;
p = phase;
n = fs * duration;
dt = 1 / fs;
% 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 or less would return -amplitude for all sample points
% duty of 0.25 would return +amplitude for first quarter of each cycle
% then return -amplitude for the remaining three-fourths
% duty of 1 would return all +amplitude
% 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;
st = mod(f * t - p, 1);
t = i * dt; % time at the i'th sample
% periodic ramp from 0 to 1
% progression through a cycle
st = mod(frequency * t - phase, 1);
if(st < duty)
x(i) = A;
x(i) = amplitude;
else
x(i) = -A;
x(i) = -amplitude;
end
end
end

View File

@ -1,19 +1,43 @@
function x = generate_triangle(amplitude, frequency, phase, fs, duration, duty)
%GENERATE_SINE:Arthur Lu returns a matrix of sampled sine wave, where the
% GENERATE_TRIANGLE: returns a matrix of sampled square wave
% CONTRIBUTORS:
% Arthur Lu: Original author
% Benjamin Liou: refactoring and annotations
% DOCUMENTATION:
% phase shift is in number of periods
x = zeros(1, fs * duration);
A = amplitude;
f = frequency;
p = phase;
n = fs * duration;
dt = 1 / fs;
% 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.25 would have positive slope for first quarter of each cycle
% then have negative slope for the remaining three-fourths
% 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;
st = mod(f * t - p, 1);
% periodic ramp from 0 to 1
% progression through a cycle
st = mod(frequency * t - phase, 1);
if(st < duty)
x(i) = A*(1/duty * st - 0.5);
slope = amplitude / duty;
intercept = -0.5 * amplitude;
x(i) = slope * st + intercept;
else
x(i) = A*(-(1/(1-duty))*st + (duty/(1-duty)) + 1 - 0.5);
slope = -amplitude / (1 - duty);
intercept = amplitude*( duty/(1-duty) + 0.5);
x(i) = slope * st + intercept;
end
end
end

13
src/generate_white.m Normal file
View File

@ -0,0 +1,13 @@
function x = generate_white(amplitude, fs, duration)
%GENERATE_WHITE: returns a matrix of sampled white noise
%CONTRIBUTORS:
%Benjamin Liou: Original author
%DOCUMENTATION:
% white noise can then be filtered to produce different hues of noises
%time domain matrix of random sample points between +-amplitude
x = amplitude * 2 * (rand(1, fs * duration) - 0.5);
end

29
src/lfo_sine.m Normal file
View File

@ -0,0 +1,29 @@
function x = lfo_sine(amplitude, frequency, phase, fs, duration, input)
% LFO_SINE: modulates an input matrix
% CONTRIBUTORS:
% Benjamin Liou: Original author
% DOCUMENTATION:
% frequency is typically below 20Hz (according to wikipedia)
% fs and duration should be 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 lfo, which will be used to modulate the input
lfo = zeros(1, n);
% populate lfo matrix
for i = 1:n
t = i * dt; % time at the i'th sample
lfo(i) = amplitude * sin(2 * pi * frequency * t - phase);
end
% modulate input
x = lfo .* input;
end

6
src/reverse.m Normal file
View File

@ -0,0 +1,6 @@
function output = reverse(input)
%input: a 1D array representing the sound signal in the time domain
%returns: the input signal with its elements in reverse order.
%By Conner Hsu
output = flip(input);
end