我是靠谱客的博主 腼腆枕头,这篇文章主要介绍webrtc中的wav文件格式解析,现在分享给大家,希望可以做个参考。

发现wav文件的格式解析有点小问题,原因就是不同的软件录制的wav文件里面有一些多余的头,这样就无法保证头的大小为44字节了,所以解析的代码需要注意这一点。我发现早前版本的webrtc里的源码就没有考虑到这一点,在解析ffmpeg转换后的wav文件和苹果录制的wav文件时,就出了问题。请看源码:webrtc/src/common_audio/wav_header.cc文件里的函数ReadWavHeader实现。

本人改写如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
bool ReadWavHeader(ReadableWav* readable, int* num_channels, int* sample_rate, WavFormat* format, size_t* bytes_per_sample, size_t* num_samples) { WavHeader header; #if 0 if (readable->Read(&header, kWavHeaderSize - sizeof(header.data)) != kWavHeaderSize - sizeof(header.data)) return false; const uint32_t fmt_size = ReadLE32(header.fmt.header.Size); if (fmt_size != kFmtSubchunkSize) { // There is an optional two-byte extension field permitted to be present // with PCM, but which must be zero. int16_t ext_size; if (kFmtSubchunkSize + sizeof(ext_size) != fmt_size) return false; if (readable->Read(&ext_size, sizeof(ext_size)) != sizeof(ext_size)) return false; if (ext_size != 0) return false; } if (readable->Read(&header.data, sizeof(header.data)) != sizeof(header.data)) return false; #else while (true) { ChunkHeader unknown_header; if (readable->Read(&unknown_header, sizeof(unknown_header)) != sizeof(unknown_header)) return false; std::string fourccID = ReadFourCC(unknown_header.ID); if (fourccID == "RIFF") { header.riff.header = unknown_header; if (readable->Read(&header.riff.Format, sizeof(header.riff.Format)) != sizeof(header.riff.Format)) return false; } else if (fourccID == "fmt ") { header.fmt.header = unknown_header; if (readable->Read(&header.fmt.info, sizeof(header.fmt.info)) != sizeof(header.fmt.info)) return false; const uint32_t fmt_size = ReadLE32(header.fmt.header.Size); if (fmt_size != kFmtSubchunkSize) { // There is an optional two-byte extension field permitted to be present // with PCM, but which must be zero. int16_t ext_size; if (kFmtSubchunkSize + sizeof(ext_size) != fmt_size) return false; if (readable->Read(&ext_size, sizeof(ext_size)) != sizeof(ext_size)) return false; if (ext_size != 0) return false; } } else if (fourccID == "data") { header.data.header = unknown_header; break;//until find data } else// if (fourccID == "LIST")//skip junk/list/fllr if exists { const size_t bytes_in_payload = ReadLE32(unknown_header.Size); if (readable->Seek(bytes_in_payload, SEEK_CUR) != 0) return false; } } #endif // Parse needed fields. *format = static_cast<WavFormat>(ReadLE16(header.fmt.AudioFormat)); *num_channels = ReadLE16(header.fmt.NumChannels); *sample_rate = ReadLE32(header.fmt.SampleRate); *bytes_per_sample = ReadLE16(header.fmt.BitsPerSample) / 8; const size_t bytes_in_payload = ReadLE32(header.data.header.Size); if (*bytes_per_sample == 0) return false; *num_samples = bytes_in_payload / *bytes_per_sample; // Sanity check remaining fields. if (ReadFourCC(header.riff.header.ID) != "RIFF") return false; if (ReadFourCC(header.riff.Format) != "WAVE") return false; if (ReadFourCC(header.fmt.header.ID) != "fmt ") return false; if (ReadFourCC(header.data.header.ID) != "data") return false; if (ReadLE32(header.riff.header.Size) < RiffChunkSize(bytes_in_payload)) return false; if (ReadLE32(header.fmt.ByteRate) != ByteRate(*num_channels, *sample_rate, *bytes_per_sample)) return false; if (ReadLE16(header.fmt.BlockAlign) != BlockAlign(*num_channels, *bytes_per_sample)) return false; return CheckWavParameters(*num_channels, *sample_rate, *format, *bytes_per_sample, *num_samples); }

 

 

最后

以上就是腼腆枕头最近收集整理的关于webrtc中的wav文件格式解析的全部内容,更多相关webrtc中内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部