我试图在我的程序中读取 wav 文件(与媒体播放器一起使用的 wav 文件)的标头, 但我只找到无效值(采样率、通道数等)
pub const WavObject = struct {
riff_identifier: *[4]u8, // Chunk identifier: "RIFF"
riff_chunk_size: u32, // Chunk size (file size - 8 bytes)
riff_format: *[4]u8, // Format identifier: "WAVE"
fmt_identifier: *[4]u8, // Format subchunk identifier: "fmt "
fmt_subchunk_size: u32, // Subchunk size (16 for PCM)
fmt_audio_format: u16, // Audio format (1 for PCM)
fmt_num_channels: u16, // Number of channels (1 for mono, 2 for stereo)
fmt_sample_rate: u32, // Sample rate (samples per second)
fmt_byte_rate: u32, // Byte rate (sample rate * block size)
fmt_block_size: u16, // Block size (channels * bits per sample 8)
fmt_bits_per_sample: u16, //Bits per sample (8 or 16)
data_identifier: *[4]u8, // Data subchunk identifier: "data"
data_size: u32, // Data subchunk size (size of the raw audio data)
pub fn deserializeHeader(wavBytes: []u8, allocator: std.mem.Allocator) !*WavObject {
var wavObj = try allocator.create(WavObject);
if (wavBytes.len < 44) return error.InvalidWav;
const riffChunku32: u32 = undefined;
const subChunkSize: u32 = undefined;
const audioFormat: u16 = undefined;
const numChannels: u16 = undefined;
const sampleRate: u32 = undefined;
const byteRate: u32 = undefined;
const blockSize: u16 = undefined;
const bitsPerSample: u16 = undefined;
const dataSize: u32 = undefined;
// Parse individual fields from the wavBytes array
std.mem.writeInt(u32, wavBytes[4..8], riffChunku32, .little);
std.mem.writeInt(u32, wavBytes[16..20], subChunkSize, .little);
std.mem.writeInt(u16, wavBytes[20..22], audioFormat, .little);
std.mem.writeInt(u16, wavBytes[22..24], numChannels, .little);
std.mem.writeInt(u32, wavBytes[24..28], sampleRate, .little);
std.mem.writeInt(u32, wavBytes[28..32], byteRate, .little);
std.mem.writeInt(u16, wavBytes[32..34], blockSize, .little);
std.mem.writeInt(u16, wavBytes[34..36], bitsPerSample, .little);
std.mem.writeInt(u32, wavBytes[40..44], dataSize, .little);
wavObj.riff_identifier = wavBytes[0..4];
wavObj.riff_chunk_size = riffChunku32;
wavObj.riff_format = wavBytes[8..12];
wavObj.fmt_identifier = wavBytes[12..16];
wavObj.fmt_subchunk_size = subChunkSize;
wavObj.fmt_audio_format = audioFormat;
wavObj.fmt_num_channels = numChannels;
wavObj.fmt_sample_rate = sampleRate;
wavObj.fmt_byte_rate = byteRate;
wavObj.fmt_block_size = blockSize;
wavObj.fmt_bits_per_sample = bitsPerSample;
wavObj.data_identifier = wavBytes[36..40];
wavObj.data_size = dataSize;
return wavObj;
}
// test code
test "basic play wav" {
const start = std.time.microTimestamp();
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
// reads header and prints values
const buffer = try allocator.alloc(u8, 2048 * 100000);
const file = try std.fs.cwd().openFile("./samples/hip_hop_kick.wav", .{ .mode = std.fs.File.OpenMode.read_only });
const reader = file.reader();
_ = try reader.read(buffer);
const wavObj = try wav.WavObject.deserializeHeader(buffer[0..44], allocator);
wavObj.PrintHeader();
std.debug.print("{d}", .{buffer[0..44]});
const end = std.time.microTimestamp();
std.debug.print("time {d} \n", .{end - start});
}