Cleaned up tone generation

- added sharp tones
- made octave customizable
This commit is contained in:
Hypercube
2026-08-17 16:04:33 +02:00
parent cd05d33842
commit 7251e8bd50

View File

@@ -16,21 +16,27 @@ const Note = struct {
key_id: u32 = 0, key_id: u32 = 0,
}; };
fn semitoneFreq(n: f64) f64 { const Tone = enum {
return 440 * std.math.pow(f64, 2, (n - 49) / 12.0); c,
} C,
d,
// TODO: add other octaves D,
const Tones = struct { e,
const C4: f64 = semitoneFreq(40); f,
const D4: f64 = semitoneFreq(42); F,
const E4: f64 = semitoneFreq(44); g,
const F4: f64 = semitoneFreq(45); G,
const G4: f64 = semitoneFreq(47); a,
const A4: f64 = semitoneFreq(49); A,
const H4: f64 = semitoneFreq(51); b,
}; };
fn toneFreq(tone: Tone, octave: i32) f64 {
const tone_val = 12 * (octave - 1) + @intFromEnum(tone);
const tone_val_f: f64 = @floatFromInt(tone_val);
return 440 * std.math.pow(f64, 2, (tone_val_f - 45.0) / 12.0);
}
fn sine_fn(t: f64) f64 { fn sine_fn(t: f64) f64 {
return std.math.sin(t * std.math.pi * 2); return std.math.sin(t * std.math.pi * 2);
} }
@@ -146,49 +152,75 @@ pub fn main(init: std.process.Init) !void {
.base_fn = &sine_fn, .base_fn = &sine_fn,
.start = userdata.frame, .start = userdata.frame,
.end = ~@as(usize, 0), .end = ~@as(usize, 0),
.frequency = Tones.A4, .frequency = toneFreq(.a, 4),
.attack = 48000 * 0.2, .attack = 48000 * 0.2,
.decay = 48000 * 0.2, .decay = 48000 * 0.2,
.decay_value = 0.6, .decay_value = 0.6,
.release = 48000, .release = 48000,
.volume = 0.2, .volume = 0.05,
.key_id = 0, .key_id = 0,
}; };
switch (event.key.key) { switch (event.key.key) {
sdl.SDLK_C => { sdl.SDLK_Z => {
try userdata.notes.append(allocator, simple_note); try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_C; userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_Z;
userdata.notes.items[userdata.notes.items.len - 1].frequency = Tones.C4; userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.c, 4);
},
sdl.SDLK_S => {
try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_S;
userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.C, 4);
},
sdl.SDLK_X => {
try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_X;
userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.d, 4);
}, },
sdl.SDLK_D => { sdl.SDLK_D => {
try userdata.notes.append(allocator, simple_note); try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_D; userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_D;
userdata.notes.items[userdata.notes.items.len - 1].frequency = Tones.D4; userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.D, 4);
}, },
sdl.SDLK_E => { sdl.SDLK_C => {
try userdata.notes.append(allocator, simple_note); try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_E; userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_C;
userdata.notes.items[userdata.notes.items.len - 1].frequency = Tones.E4; userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.e, 4);
}, },
sdl.SDLK_F => { sdl.SDLK_V => {
try userdata.notes.append(allocator, simple_note); try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_F; userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_V;
userdata.notes.items[userdata.notes.items.len - 1].frequency = Tones.F4; userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.f, 4);
}, },
sdl.SDLK_G => { sdl.SDLK_G => {
try userdata.notes.append(allocator, simple_note); try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_G; userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_G;
userdata.notes.items[userdata.notes.items.len - 1].frequency = Tones.G4; userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.F, 4);
}, },
sdl.SDLK_A => { sdl.SDLK_B => {
try userdata.notes.append(allocator, simple_note); try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_A; userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_B;
userdata.notes.items[userdata.notes.items.len - 1].frequency = Tones.A4; userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.g, 4);
}, },
sdl.SDLK_H => { sdl.SDLK_H => {
try userdata.notes.append(allocator, simple_note); try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_H; userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_H;
userdata.notes.items[userdata.notes.items.len - 1].frequency = Tones.H4; userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.G, 4);
},
sdl.SDLK_N => {
try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_N;
userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.a, 4);
},
sdl.SDLK_J => {
try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_J;
userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.A, 4);
},
sdl.SDLK_M => {
try userdata.notes.append(allocator, simple_note);
userdata.notes.items[userdata.notes.items.len - 1].key_id = sdl.SDLK_M;
userdata.notes.items[userdata.notes.items.len - 1].frequency = toneFreq(.b, 4);
}, },
else => {}, else => {},
@@ -203,9 +235,9 @@ pub fn main(init: std.process.Init) !void {
}, },
else => {}, else => {},
} }
}
_ = sdl.SDL_RenderClear(renderer); _ = sdl.SDL_RenderClear(renderer);
_ = sdl.SDL_RenderPresent(renderer); _ = sdl.SDL_RenderPresent(renderer);
sdl.SDL_Delay(10); sdl.SDL_Delay(10);
} }
}
} }