sonnum/zigsonnum/soundnode.zig
2025-09-07 23:11:51 +03:00

139 lines
3.4 KiB
Zig

const std = @import("std");
const print = std.debug.print;
const math = std.math;
const Endian = std.builtin.Endian;
const ArrayList = std.ArrayList;
const AutoHashMap = std.AutoHashMap;
const Allocator = std.mem.Allocator;
const Pnt = @import("point.zig").Pnt;
const Activity = @import("activity.zig").Activity;
const SoundSettings = @import("settings.zig").SoundSettings;
const FreqAmpBuffer = @import("freqamp.zig").FreqAmpBuffer;
const utility = @import("utility.zig");
const prnt = utility.prnt;
pub const SoundNode = struct {
allocator: Allocator,
name: []const u8 = "soundnode",
location: Pnt = Pnt{.x = 0, .y = 0, .z = 0},
air_in: ArrayList(*SoundNode),
wire_in: ArrayList(*SoundNode),
activities: ArrayList(*Activity),
freqmap: AutoHashMap(u16, f16),
freqamp: FreqAmpBuffer,
pub fn init(allocator: Allocator, name: []const u8) SoundNode {
const air_in = ArrayList(*SoundNode).init(allocator);
const wire_in = ArrayList(*SoundNode).init(allocator);
const activities = ArrayList(*Activity).init(allocator);
const freqmap = AutoHashMap(u16, f16).init(allocator); //REDO THIS TO INCORPORATE TICKS
const freqamp = FreqAmpBuffer.init(allocator);
return .{
.allocator = allocator,
.name = name,
.air_in = air_in,
.wire_in = wire_in,
.activities = activities,
.freqmap = freqmap,
.freqamp = freqamp,
};
}
pub fn deinit(self: *SoundNode) void {
self.air_in.deinit();
self.wire_in.deinit();
self.activities.deinit();
self.freqmap.deinit();
}
};
pub fn singleSineTick(st: *SoundSettings, freq: f16, t: u64) f64 {
const ft: f64 = @floatFromInt(t);
return math.sin(st.sine_multiplier * @as(f64, freq) * ft);
}
pub fn nmain() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
var sn1: SoundNode = SoundNode.init(allocator, "left_sink");
defer sn1.deinit();
var sn2: SoundNode = SoundNode.init(allocator, "right_sink");
defer sn2.deinit();
sn2.location.x = -5;
sn1.location.x = 4;
try sn1.air_in.append(&sn2);
var st = SoundSettings{};
st.printSettings();
const duration_in_sec: u32 = 5*60;
prnt("start");
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 + ((duration_in_sec * st.sample_rate) * 2 * st.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, st.sample_rate, Endian.little);
const block_align: u16 = @intCast(2 * st.sample_width);
try stdout.writeInt(u32, @as(u32, block_align) * st.sample_rate, Endian.little);
try stdout.writeInt(u16, block_align, Endian.little);
try stdout.writeInt(u16, st.bit_depth, Endian.little);
try stdout.writeAll("data");
try stdout.writeInt(
u32,
(duration_in_sec * st.sample_rate) * 2 * st.sample_width,
Endian.little,
);
var sample: i24 = 0.0;
var amp: f64 = undefined;
for (0 .. st.sample_rate * duration_in_sec) |t| {
amp = singleSineTick(&st, 440, t);
sample = @intFromFloat(amp * @as(f64, @floatFromInt(st.max_amp)));
try stdout.writeInt(i24, sample, Endian.little);
try stdout.writeInt(i24, sample, Endian.little);
}
prnt("done");
try bw.flush();
}