139 lines
3.4 KiB
Zig
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();
|
|
}
|