Merge branch 'main' into DarellsAnnex
This commit is contained in:
commit
8b76754943
42
README.md
42
README.md
@ -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
BIN
src/.DS_Store
vendored
Binary file not shown.
@ -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
34
src/add_sine.m
Normal 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
8
src/amplify.m
Normal 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
23
src/amplifyFreqRange.m
Normal 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
40
src/generate_sawtooth.m
Normal 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
|
@ -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
|
||||
%phase shift is in number of periods
|
||||
x = zeros(1, fs * duration);
|
||||
A = amplitude;
|
||||
f = frequency;
|
||||
p = phase;
|
||||
n = fs * duration;
|
||||
dt = 1 / fs;
|
||||
% 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
|
||||
% 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
|
||||
|
||||
|
@ -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
|
||||
%phase shift is in number of periods
|
||||
x = zeros(1, fs * duration);
|
||||
A = amplitude;
|
||||
f = frequency;
|
||||
p = phase;
|
||||
n = fs * duration;
|
||||
dt = 1 / fs;
|
||||
% 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
|
||||
% 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
|
||||
|
@ -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
|
||||
%phase shift is in number of periods
|
||||
x = zeros(1, fs * duration);
|
||||
A = amplitude;
|
||||
f = frequency;
|
||||
p = phase;
|
||||
n = fs * duration;
|
||||
dt = 1 / fs;
|
||||
% 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
|
||||
% 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
13
src/generate_white.m
Normal 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
29
src/lfo_sine.m
Normal 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
6
src/reverse.m
Normal 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
|
Reference in New Issue
Block a user