sonnum/zigsonnum/sonnum.zig

121 lines
No EOL
2.7 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: u16, t: u64) f64 {
const ft: f64 = @floatFromInt(t);
const fr: f64 = @floatFromInt(freq);
return math.sin(st.sine_multiplier * fr * ft);
//return math.sin(st.sine_multiplier * @as(f64, freq) * ft);
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
var settings: SoundSettings = SoundSettings{};
const start_tick: u64 = 0;
const end_tick: u64 = 44100 * 2;
var sn1: SoundNode = try SoundNode.init(allocator, "sine");
defer sn1.deinit();
var a = Activity{
.start_tick = 0,
.end_tick = 0,
.opcode = 1,
.soundnode = &sn1,
.operands = undefined,
};
try sn1.activities.append(&a);
var soundnodes = ArrayList(*SoundNode).init(allocator);
defer soundnodes.deinit();
try soundnodes.append(&sn1);
var tick: u64 = 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(
u64,
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(
u64,
end_tick * 2 * settings.sample_width,
Endian.little,
);
var sample: i24 = 0.0;
while (tick < end_tick) {
for (soundnodes.items, 0..) |soundnode, i| {
for (soundnode.activities.items, 0..) |activity, j| {
try activity.do();
_ = j;
}
var amp: f64 = 0;
var it = soundnode.freqmap.iterator();
while (it.next()) |entry| {
amp += entry.value_ptr.* * singleSineTick(&settings, @as(u16, entry.key_ptr.*), tick);
}
sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp)));
try stdout.writeInt(i24, sample, Endian.little);
try stdout.writeInt(i24, sample, Endian.little);
_ = i;
}
tick += 1;
}
try bw.flush();
}