Merge branch 'main' of https://github.com/ltcptgeneral/ece45-project
This commit is contained in:
commit
cef36db11f
BIN
App/app.mlapp
BIN
App/app.mlapp
Binary file not shown.
14
README.md
14
README.md
@ -57,10 +57,10 @@ where LOW, MED, HIGH are user-selected variables of any value.
|
||||
|
||||
## Useful websites
|
||||
|
||||
- https://learningsynths.ableton.com
|
||||
- https://learningsynths.ableton.com/en/playground
|
||||
- https://blog.demofox.org/diy-synthesizer/
|
||||
- http://portaudio.com/
|
||||
- https://ccrma.stanford.edu/software/stk/
|
||||
- https://cycling74.com/products/max
|
||||
- http://msp.ucsd.edu/software.html
|
||||
- [Learning Synths](https://learningsynths.ableton.com)
|
||||
- [Learning Synths Playground](https://learningsynths.ableton.com/en/playground)
|
||||
- [DIY Synthesisers](https://blog.demofox.org/diy-synthesizer/)
|
||||
- [Port Audio (audio I/O library)](http://portaudio.com/)
|
||||
- [Synthesis ToolKit in C++](https://ccrma.stanford.edu/software/stk/)
|
||||
- [Max](https://cycling74.com/products/max)
|
||||
- [Software by Miller Puckette](http://msp.ucsd.edu/software.html)
|
||||
|
BIN
src/.DS_Store
vendored
BIN
src/.DS_Store
vendored
Binary file not shown.
@ -1,3 +1,14 @@
|
||||
%Written by Darell
|
||||
%Creates a Linear Amplitude Envelope
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
|
||||
% DOCUMENTATION:
|
||||
% fs is the sampling frequency
|
||||
% attack, decay, release are in percentages of the period
|
||||
% sustain is in the percentage of amplitude
|
||||
|
||||
function output = DarellAmplitudeEnvelope(input, Fs, attack,decay,sustain,release) %percentages for attack, decay, sustain, release
|
||||
len = length(input);
|
||||
T = (len-1)/Fs;
|
@ -1,3 +1,15 @@
|
||||
%Written by Darell
|
||||
%uses fourier transform to get the series of all signals
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
|
||||
% DOCUMENTATION:
|
||||
% fs is the sampling frequency
|
||||
% y is the signal input
|
||||
% LOW and HIGH are used for the band of frequency
|
||||
% MEDIUM IS NOT USED
|
||||
|
||||
function output_y = DarellbandpassFilter(y,Fs,LOW,MED,HIGH)
|
||||
Len = length(y);
|
||||
F = Fs * (-Len/2 : (Len/2 - 1))/Len ;
|
@ -1,10 +0,0 @@
|
||||
function output = FilterSelect(input,Fs,LOW,MED,HIGH,number)
|
||||
if(number == "Option 1")
|
||||
output = DarellbandpassFilter(input,Fs,LOW,MED,HIGH);
|
||||
elseif(number == "Option 2")
|
||||
output = amplifyFreqRange(input, Fs, LOW, MED, HIGH);
|
||||
else
|
||||
output = input;
|
||||
end
|
||||
end
|
||||
|
BIN
src/Helper/.DS_Store
vendored
Normal file
BIN
src/Helper/.DS_Store
vendored
Normal file
Binary file not shown.
20
src/Helper/Equalizer_Darell.m
Normal file
20
src/Helper/Equalizer_Darell.m
Normal file
@ -0,0 +1,20 @@
|
||||
%Written by Darell
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
|
||||
% DOCUMENTATION:
|
||||
% fs is the sampling frequency
|
||||
% input is the signal input
|
||||
% EQplot is the curve generated by the EQ in the app. it should look like /----\ when everthing is set to 1
|
||||
|
||||
|
||||
function output = Equalizer_Darell(input,EQplot,Fs)
|
||||
%It's an EQ written by Darell
|
||||
% Split into frequencies and multiply by EQ
|
||||
Mod_Freq = fftshift(fft(input));
|
||||
filtered_Mod_Freq = fftshift(Mod_Freq .* EQplot);
|
||||
output = real(ifft(filtered_Mod_Freq));
|
||||
%plot(output);
|
||||
end
|
||||
|
92
src/Helper/MIDIDarell.m
Normal file
92
src/Helper/MIDIDarell.m
Normal file
@ -0,0 +1,92 @@
|
||||
function output = MIDIDarell(dur,Fs)
|
||||
%Darell Chua Yun Da
|
||||
% Detailed explanation goes here
|
||||
|
||||
freq = [330 350 370 392 415 440 466 494 523 554];
|
||||
charls = ["q" "w" "e" "r" "t" "y" "u" "i" "o" "p"];
|
||||
bytedur = 0.5;
|
||||
x = 0:1/Fs:bytedur;
|
||||
yz0 = zeros([1,(length(x)-1)]);
|
||||
y = [yz0
|
||||
yz0
|
||||
yz0
|
||||
yz0
|
||||
yz0
|
||||
yz0
|
||||
yz0
|
||||
yz0
|
||||
yz0
|
||||
yz0];
|
||||
|
||||
for c = 1:length(freq)
|
||||
for i=1:length(x)
|
||||
y(c,i) = 0.5*sin(2*pi*freq(c)*x(i));
|
||||
end
|
||||
end
|
||||
Len = dur*Fs;
|
||||
output = zeros([1,Len]);
|
||||
|
||||
|
||||
|
||||
set(gcf,'CurrentCharacter', '@');
|
||||
figure(1)
|
||||
|
||||
tStart = tic;
|
||||
tEnd = toc(tStart);
|
||||
figure(1)
|
||||
|
||||
while(tEnd <= dur)
|
||||
title("Midi Popup")
|
||||
drawnow
|
||||
char = get(gcf,'CurrentCharacter');
|
||||
while (char == '@' && tEnd <= dur)
|
||||
figure(1)
|
||||
char = get(gcf,'CurrentCharacter');
|
||||
tEnd = toc(tStart);
|
||||
drawnow
|
||||
end
|
||||
|
||||
n = round((tEnd/dur)*Len);
|
||||
|
||||
endt = tEnd + bytedur;
|
||||
overt = tEnd + bytedur/3;
|
||||
if overt> dur
|
||||
endt = dur;
|
||||
end
|
||||
if endt > dur
|
||||
endt = dur;
|
||||
end
|
||||
endn = round(endt*Fs);
|
||||
|
||||
charno = 0;
|
||||
for i=1:length(freq)
|
||||
if char == charls(i)
|
||||
charno = i;
|
||||
end
|
||||
end
|
||||
if charno > 0
|
||||
sound(y(charno,:),Fs);
|
||||
oldout = output(n:endn);
|
||||
output(n:endn) = oldout + y(charno,1:(endn-n+1));
|
||||
while(tEnd < overt)
|
||||
tEnd = toc(tStart);
|
||||
drawnow
|
||||
end
|
||||
figure(1)
|
||||
plot(output);
|
||||
title("Midi Popup")
|
||||
drawnow
|
||||
set(gcf,'CurrentCharacter', '@')
|
||||
else
|
||||
figure(1)
|
||||
drawnow
|
||||
set(gcf,'CurrentCharacter', '@')
|
||||
end
|
||||
tEnd = toc(tStart);
|
||||
end
|
||||
figure(1)
|
||||
plot(output);
|
||||
sound(output,Fs);
|
||||
drawnow();
|
||||
end
|
||||
|
BIN
src/NotWorking/.DS_Store
vendored
Normal file
BIN
src/NotWorking/.DS_Store
vendored
Normal file
Binary file not shown.
103
src/PitchEnvelope/DarellAnneLinearPitchEnvelope.m
Normal file
103
src/PitchEnvelope/DarellAnneLinearPitchEnvelope.m
Normal file
@ -0,0 +1,103 @@
|
||||
%Written by Darell and Anne
|
||||
%If there is a frequency of 200Hz:
|
||||
%1. it needs to ramp up a frequency from 0Hz to the 200Hz over the attack time
|
||||
%2. It needs to ramp down to a set sustained frequency over the decay time e.g. 160Hz < 200Hz
|
||||
%3. It maintains this 160Hz until the release time
|
||||
%4. Release time: It decays from 160Hz further all the way back to 0Hz.
|
||||
%This envelope uses linear calculations
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
% Person2: Anne
|
||||
|
||||
% DOCUMENTATION:
|
||||
% fs is the sampling frequency
|
||||
% attack, decay, release are in percentages of the period
|
||||
% sustain is in the percentage of amplitude
|
||||
|
||||
function output = DarellAnneLinearPitchEnvelope(input, Fs, attack,decay,sustain,release) %percentages for attack, decay, sustain, release
|
||||
len = length(input);
|
||||
T = (len-1)/Fs;
|
||||
attacktime = attack * T * Fs;
|
||||
decaytime = attacktime + decay * T * Fs;
|
||||
sustaintime = (T - (release * T)) * Fs;
|
||||
|
||||
output = zeros([1,len]);
|
||||
|
||||
tcounter = 1;
|
||||
%attack phase
|
||||
curr = attacktime;
|
||||
x = 1:len;
|
||||
y = x .* 0;
|
||||
g = x .* 0;
|
||||
while tcounter <= curr
|
||||
ncount = round((tcounter^2)/(2*curr)+ curr/2);
|
||||
y(tcounter) = ncount; %For Debug Purposes
|
||||
output(tcounter) = input(ncount);
|
||||
tcounter = tcounter+1;
|
||||
end
|
||||
|
||||
%decay phase
|
||||
prevcur = curr;
|
||||
tcounter = prevcur;
|
||||
curr = decaytime;
|
||||
while tcounter <= curr
|
||||
|
||||
t = round(tcounter-prevcur);
|
||||
dur = round(curr-prevcur);
|
||||
dsus = (1-sustain);
|
||||
|
||||
dn = (1 - (dsus)*t/(2*dur))*t;
|
||||
ncount = round(prevcur + dn);
|
||||
tcounter = round(tcounter);
|
||||
|
||||
y(tcounter) = ncount; %For Debug Purposes
|
||||
output(tcounter) = input(ncount);
|
||||
tcounter = tcounter+1;
|
||||
end
|
||||
hold on
|
||||
plot(x,y)
|
||||
plot(x,g)
|
||||
hold off
|
||||
%sustain phase
|
||||
prevncount = ncount;
|
||||
prevcur = curr;
|
||||
tcounter = prevcur;
|
||||
curr = sustaintime;
|
||||
while tcounter <= curr
|
||||
t = round(tcounter-prevcur);
|
||||
ncount = round(sustain*(t) + prevncount);
|
||||
tcounter = round(tcounter);
|
||||
|
||||
y(tcounter) = ncount; %For Debug Purposes
|
||||
output(tcounter) = input(ncount);
|
||||
tcounter = tcounter+1;
|
||||
end
|
||||
|
||||
%release phase
|
||||
prevncount = ncount;
|
||||
prevcur = curr;
|
||||
tcounter = prevcur;
|
||||
curr = Fs;
|
||||
while tcounter <= curr
|
||||
t = round(tcounter-prevcur);
|
||||
dur = round(curr-prevcur);
|
||||
|
||||
dn = (sustain - (sustain)*t/(2*dur))*t;
|
||||
ncount = round(prevncount + dn);
|
||||
|
||||
%ncount = round(prevncount + ((curr-prevcur)*(tcounter-prevcur)/(curr))*(1-log(tcounter+1-prevcur)/log(curr-prevcur)));
|
||||
|
||||
%ncount = round(curr*(1-log(tcounter)/log(prevcur)) + prevncount);
|
||||
|
||||
tcounter = round(tcounter);
|
||||
y(tcounter) = ncount; %For Debug Purposes
|
||||
if ncount > len
|
||||
output(tcounter) = 0;
|
||||
else
|
||||
output(tcounter) = input(ncount);
|
||||
end
|
||||
tcounter = tcounter+1;
|
||||
end
|
||||
plot(x,y) %For Debug Purposes
|
||||
end
|
@ -4,6 +4,7 @@
|
||||
%2. It needs to ramp down to a set sustained frequency over the decay time e.g. 160Hz < 200Hz
|
||||
%3. It maintains this 160Hz until the release time
|
||||
%4. Release time: It decays from 160Hz further all the way back to 0Hz.
|
||||
%This envelope uses logarithmic calculations
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
@ -1,3 +1,11 @@
|
||||
%Written by Darell
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
|
||||
% DOCUMENTATION:
|
||||
%Pass-through function used by app
|
||||
|
||||
function output = AmpEnvelopeSelect(input, Fs, attack,decay,sustain,release,number)
|
||||
if(number == "Option 1")
|
||||
output = DarellAmplitudeEnvelope(input, Fs, attack,decay,sustain,release);
|
26
src/Select/FilterSelect.m
Normal file
26
src/Select/FilterSelect.m
Normal file
@ -0,0 +1,26 @@
|
||||
%Written by Darell
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
|
||||
% DOCUMENTATION:
|
||||
%Pass-through function used by app
|
||||
|
||||
function output = FilterSelect(input,Fs,LOW,MED,HIGH,number)
|
||||
if(number == "Option 1")
|
||||
output = DarellbandpassFilter(input,Fs,LOW,MED,HIGH);
|
||||
elseif(number == "Option 2")
|
||||
output = amplifyFreqRange(input, Fs, LOW, MED, HIGH);
|
||||
elseif(number == "Option 3")
|
||||
output = epic_effect_schluep(input, Fs, LOW, MED, HIGH);
|
||||
elseif(number == "Option 4")
|
||||
output = muffled_effect_schluep(input, Fs, LOW, MED, HIGH);
|
||||
elseif(number == "Option 5")
|
||||
output = seperate_prevalent_schluep(input, Fs, LOW, MED, HIGH);
|
||||
elseif(number == "Option 6")
|
||||
output = bandreject_filter(input, Fs, LOW, HIGH);
|
||||
else
|
||||
output = input;
|
||||
end
|
||||
end
|
||||
|
20
src/Select/LFOSelect.m
Normal file
20
src/Select/LFOSelect.m
Normal file
@ -0,0 +1,20 @@
|
||||
%Written by Darell
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
|
||||
% DOCUMENTATION:
|
||||
%Pass-through function used by app
|
||||
|
||||
function output = LFOSelect(amplitude, frequency, phase, fs, duration, input,number)
|
||||
%UNTITLED Summary of this function goes here
|
||||
% Detailed explanation goes here
|
||||
if(number == "Option 1")
|
||||
output = lfo_sawtooth(amplitude, frequency, phase, fs, duration, input);
|
||||
elseif(number == "Option 2")
|
||||
output = lfo_sine(amplitude, frequency, phase, fs, duration, input);
|
||||
else
|
||||
output = input;
|
||||
end
|
||||
end
|
||||
|
19
src/Select/OffsetSelect.m
Normal file
19
src/Select/OffsetSelect.m
Normal file
@ -0,0 +1,19 @@
|
||||
%Written by Darell
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
|
||||
% DOCUMENTATION:
|
||||
%Pass-through function used by app
|
||||
|
||||
function output = OffsetSelect(input,value,number)
|
||||
if(number == "Option 1")
|
||||
output = Meghaj_Echo(input, value);
|
||||
elseif(number == "Option 2")
|
||||
output = Petha_Hsu_PitchOffset(input, value);
|
||||
else
|
||||
output = input;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,6 +1,16 @@
|
||||
%Written by Darell
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
|
||||
% DOCUMENTATION:
|
||||
%Pass-through function used by app
|
||||
|
||||
function output = PitchEnvelopeSelect(input, Fs, attack,decay,sustain,release,number)
|
||||
if(number == "Option 1")
|
||||
output = DarellAnnePitchEnvelope(input, Fs, attack,decay,sustain,release);
|
||||
elseif(number == "Option 2")
|
||||
output = DarellAnneLinearPitchEnvelope(input, Fs, attack,decay,sustain,release);
|
||||
else
|
||||
output = input;
|
||||
end
|
@ -1,3 +1,11 @@
|
||||
%Written by Darell
|
||||
|
||||
% CONTRIBUTORS:
|
||||
% Person1: Darell
|
||||
|
||||
% DOCUMENTATION:
|
||||
%Pass-through function used by app
|
||||
|
||||
function output = SoundGeneratorSelect(amplitude, frequency, phase, fs, duration, duty,number)
|
||||
if(number == "Option 1")
|
||||
output = generate_sine(amplitude, frequency, phase, fs, duration, duty);
|
||||
@ -8,7 +16,9 @@ function output = SoundGeneratorSelect(amplitude, frequency, phase, fs, duration
|
||||
elseif(number == "Option 4")
|
||||
output = generate_sawtooth(amplitude, frequency, phase, fs, duration, duty);
|
||||
elseif(number == "Option 5")
|
||||
output = generate_white(amplitude, frequency, phase, fs, duration, duty);
|
||||
output = generate_white(amplitude, fs, duration);
|
||||
elseif(number == "Option 6")
|
||||
output = generate_halfCircles(amplitude, frequency, phase, fs, duration, duty);
|
||||
else
|
||||
output = 0;
|
||||
end
|
46
src/generate_heartbeat.m
Normal file
46
src/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
|
Reference in New Issue
Block a user