OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 } riff; | 52 } riff; |
53 FmtSubchunk fmt; | 53 FmtSubchunk fmt; |
54 struct { | 54 struct { |
55 ChunkHeader header; | 55 ChunkHeader header; |
56 } data; | 56 } data; |
57 }; | 57 }; |
58 static_assert(sizeof(WavHeader) == kWavHeaderSize, "no padding in header"); | 58 static_assert(sizeof(WavHeader) == kWavHeaderSize, "no padding in header"); |
59 | 59 |
60 } // namespace | 60 } // namespace |
61 | 61 |
62 bool CheckWavParameters(int num_channels, | 62 bool CheckWavParameters(size_t num_channels, |
63 int sample_rate, | 63 int sample_rate, |
64 WavFormat format, | 64 WavFormat format, |
65 size_t bytes_per_sample, | 65 size_t bytes_per_sample, |
66 size_t num_samples) { | 66 size_t num_samples) { |
67 // num_channels, sample_rate, and bytes_per_sample must be positive, must fit | 67 // num_channels, sample_rate, and bytes_per_sample must be positive, must fit |
68 // in their respective fields, and their product must fit in the 32-bit | 68 // in their respective fields, and their product must fit in the 32-bit |
69 // ByteRate field. | 69 // ByteRate field. |
70 if (num_channels <= 0 || sample_rate <= 0 || bytes_per_sample == 0) | 70 if (num_channels == 0 || sample_rate <= 0 || bytes_per_sample == 0) |
71 return false; | 71 return false; |
72 if (static_cast<uint64_t>(sample_rate) > std::numeric_limits<uint32_t>::max()) | 72 if (static_cast<uint64_t>(sample_rate) > std::numeric_limits<uint32_t>::max()) |
73 return false; | 73 return false; |
74 if (static_cast<uint64_t>(num_channels) > | 74 if (num_channels > std::numeric_limits<uint16_t>::max()) |
75 std::numeric_limits<uint16_t>::max()) | |
76 return false; | 75 return false; |
77 if (static_cast<uint64_t>(bytes_per_sample) * 8 > | 76 if (static_cast<uint64_t>(bytes_per_sample) * 8 > |
78 std::numeric_limits<uint16_t>::max()) | 77 std::numeric_limits<uint16_t>::max()) |
79 return false; | 78 return false; |
80 if (static_cast<uint64_t>(sample_rate) * num_channels * bytes_per_sample > | 79 if (static_cast<uint64_t>(sample_rate) * num_channels * bytes_per_sample > |
81 std::numeric_limits<uint32_t>::max()) | 80 std::numeric_limits<uint32_t>::max()) |
82 return false; | 81 return false; |
83 | 82 |
84 // format and bytes_per_sample must agree. | 83 // format and bytes_per_sample must agree. |
85 switch (format) { | 84 switch (format) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 } | 128 } |
130 #else | 129 #else |
131 #error "Write be-to-le conversion functions" | 130 #error "Write be-to-le conversion functions" |
132 #endif | 131 #endif |
133 | 132 |
134 static inline uint32_t RiffChunkSize(size_t bytes_in_payload) { | 133 static inline uint32_t RiffChunkSize(size_t bytes_in_payload) { |
135 return static_cast<uint32_t>( | 134 return static_cast<uint32_t>( |
136 bytes_in_payload + kWavHeaderSize - sizeof(ChunkHeader)); | 135 bytes_in_payload + kWavHeaderSize - sizeof(ChunkHeader)); |
137 } | 136 } |
138 | 137 |
139 static inline uint32_t ByteRate(int num_channels, int sample_rate, | 138 static inline uint32_t ByteRate(size_t num_channels, int sample_rate, |
140 size_t bytes_per_sample) { | 139 size_t bytes_per_sample) { |
141 return static_cast<uint32_t>(num_channels * sample_rate * bytes_per_sample); | 140 return static_cast<uint32_t>(num_channels * sample_rate * bytes_per_sample); |
142 } | 141 } |
143 | 142 |
144 static inline uint16_t BlockAlign(int num_channels, size_t bytes_per_sample) { | 143 static inline uint16_t BlockAlign(size_t num_channels, |
| 144 size_t bytes_per_sample) { |
145 return static_cast<uint16_t>(num_channels * bytes_per_sample); | 145 return static_cast<uint16_t>(num_channels * bytes_per_sample); |
146 } | 146 } |
147 | 147 |
148 void WriteWavHeader(uint8_t* buf, | 148 void WriteWavHeader(uint8_t* buf, |
149 int num_channels, | 149 size_t num_channels, |
150 int sample_rate, | 150 int sample_rate, |
151 WavFormat format, | 151 WavFormat format, |
152 size_t bytes_per_sample, | 152 size_t bytes_per_sample, |
153 size_t num_samples) { | 153 size_t num_samples) { |
154 RTC_CHECK(CheckWavParameters(num_channels, sample_rate, format, | 154 RTC_CHECK(CheckWavParameters(num_channels, sample_rate, format, |
155 bytes_per_sample, num_samples)); | 155 bytes_per_sample, num_samples)); |
156 | 156 |
157 WavHeader header; | 157 WavHeader header; |
158 const size_t bytes_in_payload = bytes_per_sample * num_samples; | 158 const size_t bytes_in_payload = bytes_per_sample * num_samples; |
159 | 159 |
(...skipping 14 matching lines...) Expand all Loading... |
174 | 174 |
175 WriteFourCC(&header.data.header.ID, 'd', 'a', 't', 'a'); | 175 WriteFourCC(&header.data.header.ID, 'd', 'a', 't', 'a'); |
176 WriteLE32(&header.data.header.Size, static_cast<uint32_t>(bytes_in_payload)); | 176 WriteLE32(&header.data.header.Size, static_cast<uint32_t>(bytes_in_payload)); |
177 | 177 |
178 // Do an extra copy rather than writing everything to buf directly, since buf | 178 // Do an extra copy rather than writing everything to buf directly, since buf |
179 // might not be correctly aligned. | 179 // might not be correctly aligned. |
180 memcpy(buf, &header, kWavHeaderSize); | 180 memcpy(buf, &header, kWavHeaderSize); |
181 } | 181 } |
182 | 182 |
183 bool ReadWavHeader(ReadableWav* readable, | 183 bool ReadWavHeader(ReadableWav* readable, |
184 int* num_channels, | 184 size_t* num_channels, |
185 int* sample_rate, | 185 int* sample_rate, |
186 WavFormat* format, | 186 WavFormat* format, |
187 size_t* bytes_per_sample, | 187 size_t* bytes_per_sample, |
188 size_t* num_samples) { | 188 size_t* num_samples) { |
189 WavHeader header; | 189 WavHeader header; |
190 if (readable->Read(&header, kWavHeaderSize - sizeof(header.data)) != | 190 if (readable->Read(&header, kWavHeaderSize - sizeof(header.data)) != |
191 kWavHeaderSize - sizeof(header.data)) | 191 kWavHeaderSize - sizeof(header.data)) |
192 return false; | 192 return false; |
193 | 193 |
194 const uint32_t fmt_size = ReadLE32(header.fmt.header.Size); | 194 const uint32_t fmt_size = ReadLE32(header.fmt.header.Size); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 if (ReadLE16(header.fmt.BlockAlign) != | 234 if (ReadLE16(header.fmt.BlockAlign) != |
235 BlockAlign(*num_channels, *bytes_per_sample)) | 235 BlockAlign(*num_channels, *bytes_per_sample)) |
236 return false; | 236 return false; |
237 | 237 |
238 return CheckWavParameters(*num_channels, *sample_rate, *format, | 238 return CheckWavParameters(*num_channels, *sample_rate, *format, |
239 *bytes_per_sample, *num_samples); | 239 *bytes_per_sample, *num_samples); |
240 } | 240 } |
241 | 241 |
242 | 242 |
243 } // namespace webrtc | 243 } // namespace webrtc |
OLD | NEW |