189 lines
No EOL
4.2 KiB
Zig
189 lines
No EOL
4.2 KiB
Zig
const std = @import("std");
|
|
const math = std.math;
|
|
const print = std.debug.print;
|
|
|
|
const ArrayList = std.ArrayList;
|
|
const Endian = std.builtin.Endian;
|
|
|
|
const SoundNode = @import("soundnode.zig").SoundNode;
|
|
const Activity = @import("activity.zig").Activity;
|
|
const SoundSettings = @import("settings.zig").SoundSettings;
|
|
|
|
|
|
pub fn singleSineTick(st: *SoundSettings, freq: f16, t: u32) f64 {
|
|
const ft: f64 = @floatFromInt(t);
|
|
return math.sin(st.sine_multiplier * @as(f64, freq) * ft);
|
|
}
|
|
|
|
|
|
pub fn main() !void {
|
|
|
|
//var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
//const allocator = gpa.allocator();
|
|
|
|
const allocator = std.heap.c_allocator;
|
|
|
|
var settings: SoundSettings = SoundSettings{};
|
|
|
|
const start_tick: u32 = 0;
|
|
const end_tick: u32 = 44100 * 10;
|
|
|
|
var left: SoundNode = try SoundNode.init(allocator, "left_sink");
|
|
defer left.deinit();
|
|
left.location.x = -0.15;
|
|
|
|
var right: SoundNode = try SoundNode.init(allocator, "right_sink");
|
|
defer right.deinit();
|
|
right.location.x = 0.15;
|
|
|
|
var sine: SoundNode = try SoundNode.init(allocator, "sine");
|
|
defer sine.deinit();
|
|
|
|
var a = Activity{
|
|
.start_tick = 0,
|
|
.end_tick = 0,
|
|
.opcode = 1,
|
|
.soundnode = &sine,
|
|
};
|
|
|
|
a.operands[0] = 410.0;
|
|
a.operands[1] = 0.8;
|
|
|
|
var sine2: SoundNode = try SoundNode.init(allocator, "sine2");
|
|
defer sine2.deinit();
|
|
|
|
var a4 = Activity{
|
|
.start_tick = 0,
|
|
.end_tick = end_tick,
|
|
.opcode = 3,
|
|
.soundnode = &sine2,
|
|
};
|
|
|
|
a4.operands[0] = 410.0;
|
|
a4.operands[1] = 820.0;
|
|
a4.operands[2] = 0.5;
|
|
|
|
try sine.activities.append(&a);
|
|
try sine2.activities.append(&a4);
|
|
|
|
var a2 = Activity{
|
|
.start_tick = 0,
|
|
.end_tick = end_tick,
|
|
.opcode = 2,
|
|
.soundnode = &left,
|
|
};
|
|
try left.activities.append(&a2);
|
|
|
|
var a3 = Activity{
|
|
.start_tick = 0,
|
|
.end_tick = end_tick,
|
|
.opcode = 2,
|
|
.soundnode = &right,
|
|
};
|
|
try right.activities.append(&a3);
|
|
|
|
var soundnodes = ArrayList(*SoundNode).init(allocator);
|
|
defer soundnodes.deinit();
|
|
|
|
//Preset sink nodes
|
|
try soundnodes.append(&sine);
|
|
try soundnodes.append(&sine2);
|
|
try soundnodes.append(&left);
|
|
try soundnodes.append(&right);
|
|
|
|
try left.wire_in.append(&sine2);
|
|
try right.wire_in.append(&sine2);
|
|
|
|
var tick: u32 = start_tick;
|
|
|
|
//STARTING WAV
|
|
const stdout_file = std.io.getStdOut().writer();
|
|
var bw = std.io.bufferedWriter(stdout_file);
|
|
const stdout = bw.writer();
|
|
|
|
//WRITING WAV HEADER
|
|
try stdout.writeAll("RIFF");
|
|
|
|
try stdout.writeInt(
|
|
u32,
|
|
36 + (end_tick * 2 * settings.sample_width),
|
|
Endian.little,
|
|
);
|
|
|
|
try stdout.writeAll("WAVE");
|
|
try stdout.writeAll("fmt ");
|
|
|
|
try stdout.writeInt(u32, 16, Endian.little);
|
|
try stdout.writeInt(u16, 1, Endian.little);
|
|
try stdout.writeInt(u16, 2, Endian.little);
|
|
try stdout.writeInt(u32, settings.sample_rate, Endian.little);
|
|
|
|
const block_align: u16 = @intCast(2 * settings.sample_width);
|
|
|
|
try stdout.writeInt(u32, @as(u32, block_align) * settings.sample_rate, Endian.little);
|
|
try stdout.writeInt(u16, block_align, Endian.little);
|
|
try stdout.writeInt(u16, settings.bit_depth, Endian.little);
|
|
|
|
try stdout.writeAll("data");
|
|
try stdout.writeInt(
|
|
u32,
|
|
end_tick * 2 * settings.sample_width,
|
|
Endian.little,
|
|
);
|
|
|
|
var sample: i24 = 0.0;
|
|
|
|
while (tick < end_tick) {
|
|
|
|
if (tick%44100 == 0) {
|
|
print("TICK {d}\n", .{tick});
|
|
}
|
|
|
|
for (soundnodes.items, 0..) |soundnode, i| {
|
|
|
|
for (soundnode.activities.items, 0..) |activity, j| {
|
|
|
|
if (tick <= activity.end_tick and tick >= activity.start_tick) {
|
|
try activity.do();
|
|
}
|
|
|
|
_ = j;
|
|
|
|
}
|
|
|
|
|
|
soundnode.freqamp.increment_tick();
|
|
_ = i;
|
|
}
|
|
|
|
var amp: f64 = 0;
|
|
|
|
const current_index = left.freqamp.current_index();
|
|
|
|
const clist_left = left.freqamp.freqamps[current_index];
|
|
|
|
for (clist_left.lst.items) |freqamp| {
|
|
amp += freqamp.r_amp * singleSineTick(&settings, freqamp.freq, tick);
|
|
}
|
|
|
|
sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp)));
|
|
try stdout.writeInt(i24, sample, Endian.little);
|
|
|
|
amp = 0;
|
|
|
|
const clist_right = right.freqamp.freqamps[current_index];
|
|
|
|
for (clist_right.lst.items) |freqamp| {
|
|
amp += freqamp.r_amp * singleSineTick(&settings, freqamp.freq, tick);
|
|
}
|
|
|
|
sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp)));
|
|
try stdout.writeInt(i24, sample, Endian.little);
|
|
|
|
tick += 1;
|
|
|
|
}
|
|
|
|
try bw.flush();
|
|
|
|
} |