this repo has no description
1//! wav file writing - just a header and raw samples.
2//!
3//! WAV is RIFF format: 44 bytes of header, then PCM data.
4
5const std = @import("std");
6
7pub const Header = extern struct {
8 riff: [4]u8 = "RIFF".*,
9 file_size: u32, // file size - 8
10 wave: [4]u8 = "WAVE".*,
11 fmt: [4]u8 = "fmt ".*,
12 fmt_size: u32 = 16, // PCM format chunk size
13 audio_format: u16 = 3, // 3 = IEEE float
14 channels: u16,
15 sample_rate: u32,
16 byte_rate: u32, // sample_rate * channels * bytes_per_sample
17 block_align: u16, // channels * bytes_per_sample
18 bits_per_sample: u16 = 32,
19 data: [4]u8 = "data".*,
20 data_size: u32, // num_samples * channels * bytes_per_sample
21
22 pub fn init(num_samples: u32, sample_rate: u32, channels: u16) Header {
23 const bytes_per_sample: u32 = 4; // f32
24 const data_size = num_samples * channels * bytes_per_sample;
25 return .{
26 .file_size = 36 + data_size,
27 .channels = channels,
28 .sample_rate = sample_rate,
29 .byte_rate = sample_rate * channels * bytes_per_sample,
30 .block_align = @intCast(channels * bytes_per_sample),
31 .data_size = data_size,
32 };
33 }
34
35 pub fn asBytes(self: *const Header) []const u8 {
36 return std.mem.asBytes(self);
37 }
38};
39
40comptime {
41 if (@sizeOf(Header) != 44) @compileError("WAV header must be 44 bytes");
42}
43
44test "header size" {
45 try std.testing.expectEqual(44, @sizeOf(Header));
46}
47
48test "header values" {
49 const h = Header.init(48000, 48000, 1); // 1 second mono
50 try std.testing.expectEqual(@as(u32, 192000), h.data_size); // 48000 * 1 * 4
51 try std.testing.expectEqual(@as(u32, 192036), h.file_size); // 36 + data_size
52}