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: f64, t: u32) f64 { const ft: f64 = @floatFromInt(t); return math.sin(st.sine_multiplier * 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 * 3; 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.5; 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(&sine); 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(); }