this repo has no description
at main 52 lines 1.8 kB view raw
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}