Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: media/base/audio_buffer.cc

Issue 1854433002: Clamp AudioBuffer float to int{16,32} conversion (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reuse original AudioBus code Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/audio_buffer.h" 5 #include "media/base/audio_buffer.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "media/base/audio_bus.h" 10 #include "media/base/audio_bus.h"
11 #include "media/base/audio_sample_conversion.h"
11 #include "media/base/limits.h" 12 #include "media/base/limits.h"
12 #include "media/base/timestamp_constants.h" 13 #include "media/base/timestamp_constants.h"
13 14
14 namespace media { 15 namespace media {
15 16
16 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { 17 static base::TimeDelta CalculateDuration(int frames, double sample_rate) {
17 DCHECK_GT(sample_rate, 0); 18 DCHECK_GT(sample_rate, 0);
18 return base::TimeDelta::FromMicroseconds( 19 return base::TimeDelta::FromMicroseconds(
19 frames * base::Time::kMicrosecondsPerSecond / sample_rate); 20 frames * base::Time::kMicrosecondsPerSecond / sample_rate);
20 } 21 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 0, 159 0,
159 0, 160 0,
160 false, 161 false,
161 NULL, 162 NULL,
162 kNoTimestamp())); 163 kNoTimestamp()));
163 } 164 }
164 165
165 template <typename Target, typename Dest> 166 template <typename Target, typename Dest>
166 static inline Dest ConvertSample(Target value); 167 static inline Dest ConvertSample(Target value);
167 168
168 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0].
169 template <>
170 inline float ConvertSample<int16_t, float>(int16_t value) {
171 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min()
172 : 1.0f / std::numeric_limits<int16_t>::max());
173 }
174
175 // Specializations for int32_t 169 // Specializations for int32_t
176 template <> 170 template <>
177 inline int32_t ConvertSample<int16_t, int32_t>(int16_t value) { 171 inline int32_t ConvertSample<int16_t, int32_t>(int16_t value) {
DaleCurtis 2016/04/01 19:31:20 Do we still need the rest of these?
178 return static_cast<int32_t>(value) << 16; 172 return static_cast<int32_t>(value) << 16;
179 } 173 }
180 174
181 template <> 175 template <>
182 inline int32_t ConvertSample<int32_t, int32_t>(int32_t value) { 176 inline int32_t ConvertSample<int32_t, int32_t>(int32_t value) {
183 return value; 177 return value;
184 } 178 }
185 179
186 template <>
187 inline int32_t ConvertSample<float, int32_t>(float value) {
188 return static_cast<int32_t>(
189 value < 0 ? (-value) * std::numeric_limits<int32_t>::min()
190 : value * std::numeric_limits<int32_t>::max());
191 }
192
193 // Specializations for int16_t 180 // Specializations for int16_t
194 template <> 181 template <>
195 inline int16_t ConvertSample<int16_t, int16_t>(int16_t sample) { 182 inline int16_t ConvertSample<int16_t, int16_t>(int16_t sample) {
196 return sample; 183 return sample;
197 } 184 }
198 185
199 template <> 186 template <>
200 inline int16_t ConvertSample<int32_t, int16_t>(int32_t sample) { 187 inline int16_t ConvertSample<int32_t, int16_t>(int32_t sample) {
201 return sample >> 16; 188 return sample >> 16;
202 } 189 }
203 190
204 template <>
205 inline int16_t ConvertSample<float, int16_t>(float sample) {
206 return static_cast<int16_t>(
207 nearbyint(sample < 0 ? (-sample) * std::numeric_limits<int16_t>::min()
208 : sample * std::numeric_limits<int16_t>::max()));
209 }
210
211 void AudioBuffer::AdjustSampleRate(int sample_rate) { 191 void AudioBuffer::AdjustSampleRate(int sample_rate) {
212 DCHECK(!end_of_stream_); 192 DCHECK(!end_of_stream_);
213 sample_rate_ = sample_rate; 193 sample_rate_ = sample_rate;
214 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); 194 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
215 } 195 }
216 196
217 void AudioBuffer::ReadFrames(int frames_to_copy, 197 void AudioBuffer::ReadFrames(int frames_to_copy,
218 int source_frame_offset, 198 int source_frame_offset,
219 int dest_frame_offset, 199 int dest_frame_offset,
220 AudioBus* dest) { 200 AudioBus* dest) {
(...skipping 30 matching lines...) Expand all
251 } 231 }
252 232
253 if (sample_format_ == kSampleFormatPlanarS16) { 233 if (sample_format_ == kSampleFormatPlanarS16) {
254 // Format is planar signed16. Convert each value into float and insert into 234 // Format is planar signed16. Convert each value into float and insert into
255 // output channel data. 235 // output channel data.
256 for (int ch = 0; ch < channel_count_; ++ch) { 236 for (int ch = 0; ch < channel_count_; ++ch) {
257 const int16_t* source_data = 237 const int16_t* source_data =
258 reinterpret_cast<const int16_t*>(channel_data_[ch]) + 238 reinterpret_cast<const int16_t*>(channel_data_[ch]) +
259 source_frame_offset; 239 source_frame_offset;
260 float* dest_data = dest->channel(ch) + dest_frame_offset; 240 float* dest_data = dest->channel(ch) + dest_frame_offset;
261 for (int i = 0; i < frames_to_copy; ++i) { 241 DeinterleaveOneChannel<int16_t>(source_data, 0, frames_to_copy, dest_data,
262 dest_data[i] = ConvertSample<int16_t, float>(source_data[i]); 242 1, 0);
263 }
264 } 243 }
265 return; 244 return;
266 } 245 }
267 246
268 if (sample_format_ == kSampleFormatF32) { 247 if (sample_format_ == kSampleFormatF32) {
269 // Format is interleaved float32. Copy the data into each channel. 248 // Format is interleaved float32. Copy the data into each channel.
270 const float* source_data = reinterpret_cast<const float*>(data_.get()) + 249 const float* source_data = reinterpret_cast<const float*>(data_.get()) +
271 source_frame_offset * channel_count_; 250 source_frame_offset * channel_count_;
272 for (int ch = 0; ch < channel_count_; ++ch) { 251 for (int ch = 0; ch < channel_count_; ++ch) {
273 float* dest_data = dest->channel(ch) + dest_frame_offset; 252 float* dest_data = dest->channel(ch) + dest_frame_offset;
274 for (int i = 0, offset = ch; i < frames_to_copy; 253 DeinterleaveOneChannel<float>(source_data, 0, frames_to_copy, dest_data,
275 ++i, offset += channel_count_) { 254 channel_count_, ch);
276 dest_data[i] = source_data[offset];
277 }
278 } 255 }
279 return; 256 return;
280 } 257 }
281 258
282 // Remaining formats are integer interleaved data. Use the deinterleaving code 259 // Remaining formats are integer interleaved data. Use the deinterleaving code
283 // in AudioBus to copy the data. 260 // in AudioBus to copy the data.
284 DCHECK( 261 DCHECK(
285 sample_format_ == kSampleFormatU8 || sample_format_ == kSampleFormatS16 || 262 sample_format_ == kSampleFormatU8 || sample_format_ == kSampleFormatS16 ||
286 sample_format_ == kSampleFormatS24 || sample_format_ == kSampleFormatS32); 263 sample_format_ == kSampleFormatS24 || sample_format_ == kSampleFormatS32);
287 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); 264 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
(...skipping 12 matching lines...) Expand all
300 const Target* source_data = 277 const Target* source_data =
301 reinterpret_cast<const Target*>(channel_data[ch]) + trim_start; 278 reinterpret_cast<const Target*>(channel_data[ch]) + trim_start;
302 for (size_t i = 0, offset = ch; i < frames_to_copy; 279 for (size_t i = 0, offset = ch; i < frames_to_copy;
303 ++i, offset += channel_data.size()) { 280 ++i, offset += channel_data.size()) {
304 dest_data[offset] = ConvertSample<Target, Dest>(source_data[i]); 281 dest_data[offset] = ConvertSample<Target, Dest>(source_data[i]);
305 } 282 }
306 } 283 }
307 } 284 }
308 285
309 template <typename Dest> 286 template <typename Dest>
287 void InterleaveAndConvertFloat(const std::vector<uint8_t*>& channel_data,
288 size_t frames_to_copy,
289 int trim_start,
290 Dest* dest_data) {
291 for (size_t ch = 0; ch < channel_data.size(); ++ch) {
292 const float* source_data =
293 reinterpret_cast<const float*>(channel_data[ch]) + trim_start;
294 InterleaveOneChannel<Dest>(source_data, 0, frames_to_copy, dest_data,
295 channel_data.size(), ch);
296 }
297 }
298
299 template <typename Dest>
310 void ReadFramesInterleaved(const std::vector<uint8_t*>& channel_data, 300 void ReadFramesInterleaved(const std::vector<uint8_t*>& channel_data,
311 int channel_count, 301 int channel_count,
312 SampleFormat sample_format, 302 SampleFormat sample_format,
313 int frames_to_copy, 303 int frames_to_copy,
314 int trim_start, 304 int trim_start,
315 Dest* dest_data) { 305 Dest* dest_data) {
316 switch (sample_format) { 306 switch (sample_format) {
317 case kSampleFormatU8: 307 case kSampleFormatU8:
318 NOTREACHED(); 308 NOTREACHED();
319 break; 309 break;
320 case kSampleFormatS16: 310 case kSampleFormatS16:
321 InterleaveAndConvert<int16_t, Dest>( 311 InterleaveAndConvert<int16_t, Dest>(
322 channel_data, frames_to_copy * channel_count, trim_start, dest_data); 312 channel_data, frames_to_copy * channel_count, trim_start, dest_data);
323 break; 313 break;
324 case kSampleFormatS24: 314 case kSampleFormatS24:
325 case kSampleFormatS32: 315 case kSampleFormatS32:
326 InterleaveAndConvert<int32_t, Dest>( 316 InterleaveAndConvert<int32_t, Dest>(
327 channel_data, frames_to_copy * channel_count, trim_start, dest_data); 317 channel_data, frames_to_copy * channel_count, trim_start, dest_data);
328 break; 318 break;
329 case kSampleFormatF32: 319 case kSampleFormatF32:
330 InterleaveAndConvert<float, Dest>( 320 InterleaveAndConvertFloat<Dest>(
331 channel_data, frames_to_copy * channel_count, trim_start, dest_data); 321 channel_data, frames_to_copy * channel_count, trim_start, dest_data);
332 break; 322 break;
333 case kSampleFormatPlanarS16: 323 case kSampleFormatPlanarS16:
334 InterleaveAndConvert<int16_t, Dest>(channel_data, frames_to_copy, 324 InterleaveAndConvert<int16_t, Dest>(channel_data, frames_to_copy,
335 trim_start, dest_data); 325 trim_start, dest_data);
336 break; 326 break;
337 case kSampleFormatPlanarF32: 327 case kSampleFormatPlanarF32:
338 InterleaveAndConvert<float, Dest>(channel_data, frames_to_copy, 328 InterleaveAndConvertFloat<Dest>(channel_data, frames_to_copy, trim_start,
339 trim_start, dest_data); 329 dest_data);
340 break; 330 break;
341 case kSampleFormatPlanarS32: 331 case kSampleFormatPlanarS32:
342 InterleaveAndConvert<int32_t, Dest>(channel_data, frames_to_copy, 332 InterleaveAndConvert<int32_t, Dest>(channel_data, frames_to_copy,
343 trim_start, dest_data); 333 trim_start, dest_data);
344 break; 334 break;
345 case kUnknownSampleFormat: 335 case kUnknownSampleFormat:
346 NOTREACHED(); 336 NOTREACHED();
347 break; 337 break;
348 } 338 }
349 } 339 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 } 414 }
425 } else { 415 } else {
426 CHECK_EQ(frames_to_copy, 0); 416 CHECK_EQ(frames_to_copy, 0);
427 } 417 }
428 418
429 // Trim the leftover data off the end of the buffer and update duration. 419 // Trim the leftover data off the end of the buffer and update duration.
430 TrimEnd(frames_to_trim); 420 TrimEnd(frames_to_trim);
431 } 421 }
432 422
433 } // namespace media 423 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698