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

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: Fix handling of 32-bit, fix asymmetric scale 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 <algorithm>
7 #include <cmath> 8 #include <cmath>
8 9
9 #include "base/logging.h" 10 #include "base/logging.h"
10 #include "media/base/audio_bus.h" 11 #include "media/base/audio_bus.h"
12 #include "media/base/audio_sample_conversion.h"
11 #include "media/base/limits.h" 13 #include "media/base/limits.h"
12 #include "media/base/timestamp_constants.h" 14 #include "media/base/timestamp_constants.h"
13 15
14 namespace media { 16 namespace media {
15 17
16 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { 18 static base::TimeDelta CalculateDuration(int frames, double sample_rate) {
17 DCHECK_GT(sample_rate, 0); 19 DCHECK_GT(sample_rate, 0);
18 return base::TimeDelta::FromMicroseconds( 20 return base::TimeDelta::FromMicroseconds(
19 frames * base::Time::kMicrosecondsPerSecond / sample_rate); 21 frames * base::Time::kMicrosecondsPerSecond / sample_rate);
20 } 22 }
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, 157 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat,
156 CHANNEL_LAYOUT_NONE, 158 CHANNEL_LAYOUT_NONE,
157 0, 159 0,
158 0, 160 0,
159 0, 161 0,
160 false, 162 false,
161 NULL, 163 NULL,
162 kNoTimestamp())); 164 kNoTimestamp()));
163 } 165 }
164 166
165 template <typename Target, typename Dest>
166 static inline Dest ConvertSample(Target value);
167
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
176 template <>
177 inline int32_t ConvertSample<int16_t, int32_t>(int16_t value) {
178 return static_cast<int32_t>(value) << 16;
179 }
180
181 template <>
182 inline int32_t ConvertSample<int32_t, int32_t>(int32_t value) {
183 return value;
184 }
185
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
194 template <>
195 inline int16_t ConvertSample<int16_t, int16_t>(int16_t sample) {
196 return sample;
197 }
198
199 template <>
200 inline int16_t ConvertSample<int32_t, int16_t>(int32_t sample) {
201 return sample >> 16;
202 }
203
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) { 167 void AudioBuffer::AdjustSampleRate(int sample_rate) {
212 DCHECK(!end_of_stream_); 168 DCHECK(!end_of_stream_);
213 sample_rate_ = sample_rate; 169 sample_rate_ = sample_rate;
214 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); 170 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
215 } 171 }
216 172
217 void AudioBuffer::ReadFrames(int frames_to_copy, 173 void AudioBuffer::ReadFrames(int frames_to_copy,
218 int source_frame_offset, 174 int source_frame_offset,
219 int dest_frame_offset, 175 int dest_frame_offset,
220 AudioBus* dest) { 176 AudioBus* dest) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 DCHECK( 240 DCHECK(
285 sample_format_ == kSampleFormatU8 || sample_format_ == kSampleFormatS16 || 241 sample_format_ == kSampleFormatU8 || sample_format_ == kSampleFormatS16 ||
286 sample_format_ == kSampleFormatS24 || sample_format_ == kSampleFormatS32); 242 sample_format_ == kSampleFormatS24 || sample_format_ == kSampleFormatS32);
287 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); 243 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
288 int frame_size = channel_count_ * bytes_per_channel; 244 int frame_size = channel_count_ * bytes_per_channel;
289 const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; 245 const uint8_t* source_data = data_.get() + source_frame_offset * frame_size;
290 dest->FromInterleavedPartial( 246 dest->FromInterleavedPartial(
291 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); 247 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel);
292 } 248 }
293 249
294 template <class Target, typename Dest>
295 void InterleaveAndConvert(const std::vector<uint8_t*>& channel_data,
296 size_t frames_to_copy,
297 int trim_start,
298 Dest* dest_data) {
299 for (size_t ch = 0; ch < channel_data.size(); ++ch) {
300 const Target* source_data =
301 reinterpret_cast<const Target*>(channel_data[ch]) + trim_start;
302 for (size_t i = 0, offset = ch; i < frames_to_copy;
303 ++i, offset += channel_data.size()) {
304 dest_data[offset] = ConvertSample<Target, Dest>(source_data[i]);
305 }
306 }
307 }
308
309 template <typename Dest> 250 template <typename Dest>
310 void ReadFramesInterleaved(const std::vector<uint8_t*>& channel_data, 251 void ReadFramesInterleaved(const std::vector<uint8_t*>& channel_data,
311 int channel_count, 252 int channel_count,
312 SampleFormat sample_format, 253 SampleFormat sample_format,
313 int frames_to_copy, 254 int frames_to_copy,
314 int trim_start, 255 int trim_start,
315 Dest* dest_data) { 256 Dest* dest_data) {
316 switch (sample_format) { 257 switch (sample_format) {
317 case kSampleFormatU8: 258 case kSampleFormatU8:
318 NOTREACHED(); 259 NOTREACHED();
319 break; 260 break;
320 case kSampleFormatS16: 261 case kSampleFormatS16:
321 InterleaveAndConvert<int16_t, Dest>( 262 PlanarToInterleaved<int16_t, Dest>(
322 channel_data, frames_to_copy * channel_count, trim_start, dest_data); 263 channel_data, frames_to_copy * channel_count, trim_start, dest_data);
323 break; 264 break;
324 case kSampleFormatS24: 265 case kSampleFormatS24:
325 case kSampleFormatS32: 266 case kSampleFormatS32:
326 InterleaveAndConvert<int32_t, Dest>( 267 PlanarToInterleaved<int32_t, Dest>(
327 channel_data, frames_to_copy * channel_count, trim_start, dest_data); 268 channel_data, frames_to_copy * channel_count, trim_start, dest_data);
328 break; 269 break;
329 case kSampleFormatF32: 270 case kSampleFormatF32:
330 InterleaveAndConvert<float, Dest>( 271 PlanarToInterleaved<float, Dest>(
331 channel_data, frames_to_copy * channel_count, trim_start, dest_data); 272 channel_data, frames_to_copy * channel_count, trim_start, dest_data);
332 break; 273 break;
333 case kSampleFormatPlanarS16: 274 case kSampleFormatPlanarS16:
334 InterleaveAndConvert<int16_t, Dest>(channel_data, frames_to_copy, 275 PlanarToInterleaved<int16_t, Dest>(channel_data, frames_to_copy,
335 trim_start, dest_data); 276 trim_start, dest_data);
336 break; 277 break;
337 case kSampleFormatPlanarF32: 278 case kSampleFormatPlanarF32:
338 InterleaveAndConvert<float, Dest>(channel_data, frames_to_copy, 279 PlanarToInterleaved<float, Dest>(channel_data, frames_to_copy, trim_start,
339 trim_start, dest_data); 280 dest_data);
340 break; 281 break;
341 case kSampleFormatPlanarS32: 282 case kSampleFormatPlanarS32:
342 InterleaveAndConvert<int32_t, Dest>(channel_data, frames_to_copy, 283 PlanarToInterleaved<int32_t, Dest>(channel_data, frames_to_copy,
343 trim_start, dest_data); 284 trim_start, dest_data);
344 break; 285 break;
345 case kUnknownSampleFormat: 286 case kUnknownSampleFormat:
346 NOTREACHED(); 287 NOTREACHED();
347 break; 288 break;
348 } 289 }
349 } 290 }
350 291
351 void AudioBuffer::ReadFramesInterleavedS32(int frames_to_copy, 292 void AudioBuffer::ReadFramesInterleavedS32(int frames_to_copy,
352 int32_t* dest_data) { 293 int32_t* dest_data) {
353 DCHECK_LE(frames_to_copy, adjusted_frame_count_); 294 DCHECK_LE(frames_to_copy, adjusted_frame_count_);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 } 365 }
425 } else { 366 } else {
426 CHECK_EQ(frames_to_copy, 0); 367 CHECK_EQ(frames_to_copy, 0);
427 } 368 }
428 369
429 // Trim the leftover data off the end of the buffer and update duration. 370 // Trim the leftover data off the end of the buffer and update duration.
430 TrimEnd(frames_to_trim); 371 TrimEnd(frames_to_trim);
431 } 372 }
432 373
433 } // namespace media 374 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698