• Remix
  • Share
  • New Entry

on 21 Oct 2024
  • 17
  • 114
  • 2
  • 1
  • 1266
Cite your audio source here (if applicable):
drawframe(1);
Write your drawframe function below
function drawframe(f)
persistent rect balls c
if f == 1
axis([-1 1 -1 1]);
axis off
% set ball properties
s1 = 0.03 * 5;
s2 = 0.02 * 5;
c.silver = '#c0c0c0';
c.gold = '#ffd700';
balls = [
struct('pos', [-0.5, 0], 'vel', [s1, s2], 'color', [1.0, 0.84, 0.0], 'size', 40);
struct('pos', [0, 0], 'vel', [s2, s1], 'color', [0.75, 0.75, 0.75], 'size', 30);
struct('pos', [0.5, 0], 'vel', [s1, -s2], 'color', [0.72, 0.45, 0.20], 'size', 20)
];
rect = gobjects(4);
rect(4) = rectangle('Position', [-1, -1, 2, 2], 'EdgeColor', c.silver, 'LineWidth', 4);
hold on
for i = 1:3
bSize = balls(i).size / 100;
x = balls(i).pos(1) - bSize/2;
y = balls(i).pos(2) - 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 = 4;
rect(4).EdgeColor = c.silver;
for i = 1:3
bSize = balls(i).size / 100;
r = bSize/2;
% renew position
balls(i).pos = balls(i).pos + balls(i).vel;
% collision detection - left/right
if balls(i).pos(1) > (1 - r) || balls(i).pos(1) < -(1 - r)
balls(i).vel(1) = -balls(i).vel(1);
rect(4).LineWidth = 1;
rect(4).EdgeColor = c.gold;
end
% collision detection - top/bottom
if balls(i).pos(2) > (1 - r) || balls(i).pos(2) < -(1 - r)
balls(i).vel(2) = -balls(i).vel(2);
rect(4).LineWidth = 1;
rect(4).EdgeColor = c.gold;
end
% move to new position
x = balls(i).pos(1) - bSize/2;
y = balls(i).pos(2) - bSize/2;
rect(i).Position(1) = x;
rect(i).Position(2) = y;
end
end
end
function drawframe_sound(f)
persistent rect balls c stOut
fs = 44100;
fps = 24;
duration = 4;
lipSyncOffset = (fs / fps) * 0;
if f == 1
clf
% 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
% set ball properties
s1 = 0.03 * 4;
s2 = 0.02 * 4;
c.silver = '#c0c0c0';
c.gold = '#ffd700';
balls = [
struct('pos', [-0.5, 0], 'vel', [s1, s2], 'color', [1.0, 0.84, 0.0], 'size', 40, 'fx', ls);
struct('pos', [0, 0], 'vel', [s2, s1], 'color', [0.75, 0.75, 0.75], 'size', 30, 'fx', ms);
struct('pos', [0.5, 0], 'vel', [s1, -s2], 'color', [0.72, 0.45, 0.20], 'size', 20, 'fx', hs)
];
% border box
rect = gobjects(4);
rect(4) = rectangle('Position', [-1, -1, 2, 2], 'EdgeColor', c.silver, 'LineWidth', 4);
hold on
for i = 1:3
bSize = balls(i).size / 100;
x = balls(i).pos(1) - bSize/2;
y = balls(i).pos(2) - 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 = 4;
rect(4).EdgeColor = c.silver;
for i = 1:3
bSize = balls(i).size / 100;
r = bSize/2;
% renew position
balls(i).pos = balls(i).pos + balls(i).vel;
% collision detection - left/right
if balls(i).pos(1) > (1 - r) || balls(i).pos(1) < -(1 - r)
balls(i).vel(1) = -balls(i).vel(1);
rect(4).LineWidth = 1;
rect(4).EdgeColor = c.gold;
fx = balls(i).fx;
st = ceil((f-1) * fs / fps + lipSyncOffset) + 1;
ed = st + length(fx) - 1;
if (ed <= length(stOut))
pan = (balls(i).pos(1) + 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;
stOut(st:ed, 2) = stOut(st:ed, 2) + R;
end
end
% collision detection - top/bottom
if balls(i).pos(2) > (1 - r) || balls(i).pos(2) < -(1 - r)
balls(i).vel(2) = -balls(i).vel(2);
rect(4).LineWidth = 1;
rect(4).EdgeColor = c.gold;
fx = balls(i).fx;
st = ceil((f-1) * fs / fps + lipSyncOffset) + 1;
ed = st + length(fx) - 1;
if (ed <= length(stOut))
pan = (balls(i).pos(1) + 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;
stOut(st:ed, 2) = stOut(st:ed, 2) + R;
end
end
% move to new position
x = balls(i).pos(1) - bSize/2;
y = balls(i).pos(2) - bSize/2;
w = bSize;
h = bSize;
rect(i).Position = [x, y, w, h];
end
end
if f == 96
audiowrite('metalFX_g_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;
phase = mod(phase, 2*pi);
end
peak_time = 0.00;
std_dev = 0.05;
env = exp(-((t - peak_time).^2) / (2 * std_dev^2));
% LPF
n = 11;
fc = 8e3;
Wn = fc / (fs / 2);
b = fir1(n, Wn, 'low');
fx = filter(b, 1, fx);
fx = fx .* env;
fx = fx' / max(abs(fx));
end
Movie
Audio
Remix Tree