- /
-
make bouncing sound(Chase)
on 25 Oct 2024
- 11
- 110
- 0
- 1
- 1672
Cite your audio source here (if applicable):
drawframe(1);
Write your drawframe function below
function drawframe(f)
persistent rect balls c col A B wX wY duration ballN
total_frames = 96;
if f == 1
axis([-1 1 -1 1]);
axis off
cla
A = 1;
B = 1;
duration = 4;
wX = 4 * pi / duration;
wY = 6 * pi / duration;
c.silver = '#c0c0c0';
c.gold = '#ffd700';
c.slateblue = '#6a5acd';
col = [1.0, 0.84, 0.0; 0.75, 0.75, 0.75; 0.72, 0.45, 0.20];
balls = [
struct('color', [1.0, 0.84, 0.0], 'size', 20);
struct('color', [0.75, 0.75, 0.75], 'size', 15);
struct('color', [0.72, 0.45, 0.20], 'size', 10)
];
ballN = length(balls);
rect = gobjects(4);
rect(4) = rectangle('Position', [-1, -1, 2, 2], 'EdgeColor', c.slateblue, 'LineWidth', 1);
hold on;
t = f * (duration / total_frames);
for i = 1:3
bSize = balls(i).size / 100;
posx = A * sin(wX * t + (i - 1) * (2 * pi / ballN));
posy = B * sin(wY * t + (i - 1) * (2 * pi / ballN));
x = posx - bSize / 2;
y = posy - bSize / 2;
w = bSize;
h = bSize;
rect(i) = rectangle('Position', [x, y, w, h], ...
'Curvature', 1, ...
'FaceColor', balls(i).color, ...
'EdgeColor', 'none');
end
hold off;
else
rect(4).LineWidth = 1;
rect(4).EdgeColor = c.slateblue;
t = f * (duration / total_frames);
for i = 1:3
bSize = balls(i).size / 100;
r = bSize / 2;
% Lissajous
posx = A * sin(wX * t + (i - 1) * (2 * pi / ballN));
posy = B * sin(wY * t + (i - 1) * (2 * pi / ballN));
% renew position
x = posx - bSize / 2;
y = posy - bSize / 2;
% rect(i).Position(1) = x;
% rect(i).Position(2) = y;
if (i == 3)
rect(i).Position(1) = x;
rect(i).Position(2) = y;
end
if ((i == 2) && (f >= 32))
rect(i).Position(1) = x;
rect(i).Position(2) = y;
end
if ((i == 1) && (f >= 64))
rect(i).Position(1) = x;
rect(i).Position(2) = y;
end
% collision detection - left/right
if ((rect(i).Position(1) + bSize) > 1 || rect(i).Position(1) < -1)
rect(4).LineWidth = 4;
rect(4).EdgeColor = col(i,:);
end
% collision detection - top/bottom
if ((rect(i).Position(2) + bSize) > 1 || rect(i).Position(2) < -1)
rect(4).LineWidth = 4;
rect(4).EdgeColor = col(i,:);
end
end
end
end
function drawframe_sound(f)
persistent rect balls c col A B wX wY duration stOut ballN
fs = 44100;
fps = 24;
duration = 4;
total_frames = fps * duration; % 96
if f == 1
% make L/M/H metal sound
stOut = zeros(fs * duration, 2);
low_freq = 440; % Large Ball
mid_freq = 880; % Medium Ball
high_freq = 1760; % Small Ball
gain = 0.2;
ls = genFX(low_freq, fs, 0.4) * gain;
ms = genFX(mid_freq, fs, 0.4) * gain;
hs = genFX(high_freq, fs, 0.4) * gain;
axis([-1 1 -1 1]);
axis off
cla
A = 1;
B = 1;
duration = 4;
wX = 4 * pi / duration;
wY = 6 * pi / duration;
c.silver = '#c0c0c0';
c.gold = '#ffd700';
c.slateblue = '#6a5acd';
col = [1.0, 0.84, 0.0; 0.75, 0.75, 0.75; 0.72, 0.45, 0.20];
balls = [
struct('color', col(1,:), 'size', 20, 'fx', ls);
struct('color', col(2,:), 'size', 15, 'fx', ms);
struct('color', col(3,:), 'size', 10, 'fx', hs)
];
ballN = length(balls);
rect = gobjects(4);
rect(4) = rectangle('Position', [-1, -1, 2, 2], 'EdgeColor', c.slateblue, 'LineWidth', 1);
hold on;
t = f * (duration / total_frames);
for i = 1:3
bSize = balls(i).size / 100;
posx = A * sin(wX * t + (i - 1) * (2 * pi / ballN));
posy = B * sin(wY * t + (i - 1) * (2 * pi / ballN));
x = posx - bSize / 2;
y = posy - bSize / 2;
w = bSize;
h = bSize;
rect(i) = rectangle('Position', [x, y, w, h], ...
'Curvature', 1, ...
'FaceColor', balls(i).color, ...
'EdgeColor', 'none');
end
hold off;
else
rect(4).LineWidth = 1;
rect(4).EdgeColor = c.slateblue;
t = f * (duration / total_frames);
for i = 1:3
bSize = balls(i).size / 100;
r = bSize / 2;
% Lissajous
posx = A * sin(wX * t + (i - 1) * (2 * pi / ballN));
posy = B * sin(wY * t + (i - 1) * (2 * pi / ballN));
% renew position
x = posx - bSize / 2;
y = posy - bSize / 2;
% rect(i).Position(1) = x;
% rect(i).Position(2) = y;
if (i == 3)
rect(i).Position(1) = x;
rect(i).Position(2) = y;
end
if ((i == 2) && (f >= 32))
rect(i).Position(1) = x;
rect(i).Position(2) = y;
end
if ((i == 1) && (f >= 64))
rect(i).Position(1) = x;
rect(i).Position(2) = y;
end
% collision detection - left/right
if ((rect(i).Position(1) + bSize) > 1 || rect(i).Position(1) < -1)
rect(4).LineWidth = 4;
rect(4).EdgeColor = col(i,:);
fx = balls(i).fx;
st = ceil((f-1) * fs / fps) + 1;
ed = st + length(fx) - 1;
ed = min(ed,length(stOut));
fxLen = ed - st + 1;
pan = (posx + 1) / 2;
L = fx * sin (0.5 * pi * (1.0 - pan));
R = fx * sin (0.5 * pi * pan);
stOut(st:ed, 1) = stOut(st:ed, 1) + L(1:fxLen);
stOut(st:ed, 2) = stOut(st:ed, 2) + R(1:fxLen);
end
% collision detection - top/bottom
if ((rect(i).Position(2) + bSize) > 1 || rect(i).Position(2) < -1)
rect(4).LineWidth = 4;
rect(4).EdgeColor = col(i,:);
fx = balls(i).fx;
st = ceil((f-1) * fs / fps) + 1;
ed = st + length(fx) - 1;
ed = min(ed,length(stOut));
fxLen = ed - st + 1;
pan = (posx + 1) / 2;
L = fx * sin (0.5 * pi * (1.0 - pan));
R = fx * sin (0.5 * pi * pan);
stOut(st:ed, 1) = stOut(st:ed, 1) + L(1:fxLen);
stOut(st:ed, 2) = stOut(st:ed, 2) + R(1:fxLen);
end
end
end
if f == 96
audiowrite('metalFX2_rm1_LPF.wav', stOut, fs);
end
end
function fx = genFX(fo, fs, duration)
t = linspace(0, duration, fs * duration);
op_freq = [1, 2, 3, 4] * fo;
mod_index = [1, 2, 2, 4];
phase = zeros(4, 1);
fx = zeros(size(t));
for n = 1:length(t)
phase(1) = phase(1) + 2 * pi * op_freq(1) / fs;
carrier1 = sin(phase(1));
phase(2) = phase(2) + 2 * pi * op_freq(2) / fs + mod_index(2) * carrier1;
carrier2 = sin(phase(2));
phase(3) = phase(3) + 2 * pi * op_freq(3) / fs + mod_index(3) * carrier2;
carrier3 = sin(phase(3));
phase(4) = phase(4) + 2 * pi * op_freq(4) / fs + mod_index(4) * carrier3;
carrier4 = sin(phase(4));
% fx(n) = carrier1 + carrier2 + carrier3 + carrier4;
fx(n) = carrier1 + carrier2;
% fx(n) = carrier1; % clean sound
phase = mod(phase, 2*pi);
end
% LPF
n = 11;
fc = 8e3;
Wn = fc / (fs / 2);
b = fir1(n, Wn, 'low');
fx = filter(b, 1, fx);
env = exp(-10 * t);
fx = fx .* env;
fx = fx' / max(abs(fx));
end