BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / media / base / audio_buffer.cc
blob564cff156bbb7f5defa7067439731a1efa44c500
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
3 // found in the LICENSE file.
5 #include "media/base/audio_buffer.h"
7 #include <cmath>
9 #include "base/logging.h"
10 #include "media/base/audio_bus.h"
11 #include "media/base/limits.h"
12 #include "media/base/timestamp_constants.h"
14 namespace media {
16 static base::TimeDelta CalculateDuration(int frames, double sample_rate) {
17 DCHECK_GT(sample_rate, 0);
18 return base::TimeDelta::FromMicroseconds(
19 frames * base::Time::kMicrosecondsPerSecond / sample_rate);
22 AudioBuffer::AudioBuffer(SampleFormat sample_format,
23 ChannelLayout channel_layout,
24 int channel_count,
25 int sample_rate,
26 int frame_count,
27 bool create_buffer,
28 const uint8* const* data,
29 const base::TimeDelta timestamp)
30 : sample_format_(sample_format),
31 channel_layout_(channel_layout),
32 channel_count_(channel_count),
33 sample_rate_(sample_rate),
34 adjusted_frame_count_(frame_count),
35 trim_start_(0),
36 end_of_stream_(!create_buffer && data == NULL && frame_count == 0),
37 timestamp_(timestamp),
38 duration_(end_of_stream_
39 ? base::TimeDelta()
40 : CalculateDuration(adjusted_frame_count_, sample_rate_)) {
41 CHECK_GE(channel_count_, 0);
42 CHECK_LE(channel_count_, limits::kMaxChannels);
43 CHECK_GE(frame_count, 0);
44 DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE ||
45 ChannelLayoutToChannelCount(channel_layout) == channel_count);
47 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
48 DCHECK_LE(bytes_per_channel, kChannelAlignment);
49 int data_size = frame_count * bytes_per_channel;
51 // Empty buffer?
52 if (!create_buffer)
53 return;
55 if (sample_format == kSampleFormatPlanarF32 ||
56 sample_format == kSampleFormatPlanarS16 ||
57 sample_format == kSampleFormatPlanarS32) {
58 // Planar data, so need to allocate buffer for each channel.
59 // Determine per channel data size, taking into account alignment.
60 int block_size_per_channel =
61 (data_size + kChannelAlignment - 1) & ~(kChannelAlignment - 1);
62 DCHECK_GE(block_size_per_channel, data_size);
64 // Allocate a contiguous buffer for all the channel data.
65 data_.reset(static_cast<uint8*>(base::AlignedAlloc(
66 channel_count_ * block_size_per_channel, kChannelAlignment)));
67 channel_data_.reserve(channel_count_);
69 // Copy each channel's data into the appropriate spot.
70 for (int i = 0; i < channel_count_; ++i) {
71 channel_data_.push_back(data_.get() + i * block_size_per_channel);
72 if (data)
73 memcpy(channel_data_[i], data[i], data_size);
75 return;
78 // Remaining formats are interleaved data.
79 DCHECK(sample_format_ == kSampleFormatU8 ||
80 sample_format_ == kSampleFormatS16 ||
81 sample_format_ == kSampleFormatS32 ||
82 sample_format_ == kSampleFormatF32) << sample_format_;
83 // Allocate our own buffer and copy the supplied data into it. Buffer must
84 // contain the data for all channels.
85 data_size *= channel_count_;
86 data_.reset(
87 static_cast<uint8*>(base::AlignedAlloc(data_size, kChannelAlignment)));
88 channel_data_.reserve(1);
89 channel_data_.push_back(data_.get());
90 if (data)
91 memcpy(data_.get(), data[0], data_size);
94 AudioBuffer::~AudioBuffer() {}
96 // static
97 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom(
98 SampleFormat sample_format,
99 ChannelLayout channel_layout,
100 int channel_count,
101 int sample_rate,
102 int frame_count,
103 const uint8* const* data,
104 const base::TimeDelta timestamp) {
105 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
106 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer.
107 CHECK(data[0]);
108 return make_scoped_refptr(new AudioBuffer(sample_format,
109 channel_layout,
110 channel_count,
111 sample_rate,
112 frame_count,
113 true,
114 data,
115 timestamp));
118 // static
119 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer(
120 SampleFormat sample_format,
121 ChannelLayout channel_layout,
122 int channel_count,
123 int sample_rate,
124 int frame_count) {
125 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer.
126 return make_scoped_refptr(new AudioBuffer(sample_format,
127 channel_layout,
128 channel_count,
129 sample_rate,
130 frame_count,
131 true,
132 NULL,
133 kNoTimestamp()));
136 // static
137 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer(
138 ChannelLayout channel_layout,
139 int channel_count,
140 int sample_rate,
141 int frame_count,
142 const base::TimeDelta timestamp) {
143 CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer.
144 // Since data == NULL, format doesn't matter.
145 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32,
146 channel_layout,
147 channel_count,
148 sample_rate,
149 frame_count,
150 false,
151 NULL,
152 timestamp));
155 // static
156 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() {
157 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat,
158 CHANNEL_LAYOUT_NONE,
162 false,
163 NULL,
164 kNoTimestamp()));
167 template <typename Target, typename Dest>
168 static inline Dest ConvertSample(Target value);
170 // Convert int16 values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0].
171 template <>
172 inline float ConvertSample<int16, float>(int16 value) {
173 return value * (value < 0 ? -1.0f / std::numeric_limits<int16>::min()
174 : 1.0f / std::numeric_limits<int16>::max());
177 // Specializations for int32
178 template <>
179 inline int32 ConvertSample<int16, int32>(int16 value) {
180 return static_cast<int32>(value) << 16;
183 template <>
184 inline int32 ConvertSample<int32, int32>(int32 value) {
185 return value;
188 template <>
189 inline int32 ConvertSample<float, int32>(float value) {
190 return static_cast<int32>(value < 0
191 ? (-value) * std::numeric_limits<int32>::min()
192 : value * std::numeric_limits<int32>::max());
195 // Specializations for int16
196 template <>
197 inline int16 ConvertSample<int16, int16>(int16 sample) {
198 return sample;
201 template <>
202 inline int16 ConvertSample<int32, int16>(int32 sample) {
203 return sample >> 16;
206 template <>
207 inline int16 ConvertSample<float, int16>(float sample) {
208 return static_cast<int16>(
209 nearbyint(sample < 0 ? (-sample) * std::numeric_limits<int16>::min()
210 : sample * std::numeric_limits<int16>::max()));
213 void AudioBuffer::ReadFrames(int frames_to_copy,
214 int source_frame_offset,
215 int dest_frame_offset,
216 AudioBus* dest) {
217 // Deinterleave each channel (if necessary) and convert to 32bit
218 // floating-point with nominal range -1.0 -> +1.0 (if necessary).
220 // |dest| must have the same number of channels, and the number of frames
221 // specified must be in range.
222 DCHECK(!end_of_stream());
223 DCHECK_EQ(dest->channels(), channel_count_);
224 DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_);
225 DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames());
227 // Move the start past any frames that have been trimmed.
228 source_frame_offset += trim_start_;
230 if (!data_) {
231 // Special case for an empty buffer.
232 dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy);
233 return;
236 if (sample_format_ == kSampleFormatPlanarF32) {
237 // Format is planar float32. Copy the data from each channel as a block.
238 for (int ch = 0; ch < channel_count_; ++ch) {
239 const float* source_data =
240 reinterpret_cast<const float*>(channel_data_[ch]) +
241 source_frame_offset;
242 memcpy(dest->channel(ch) + dest_frame_offset,
243 source_data,
244 sizeof(float) * frames_to_copy);
246 return;
249 if (sample_format_ == kSampleFormatPlanarS16) {
250 // Format is planar signed16. Convert each value into float and insert into
251 // output channel data.
252 for (int ch = 0; ch < channel_count_; ++ch) {
253 const int16* source_data =
254 reinterpret_cast<const int16*>(channel_data_[ch]) +
255 source_frame_offset;
256 float* dest_data = dest->channel(ch) + dest_frame_offset;
257 for (int i = 0; i < frames_to_copy; ++i) {
258 dest_data[i] = ConvertSample<int16, float>(source_data[i]);
261 return;
264 if (sample_format_ == kSampleFormatF32) {
265 // Format is interleaved float32. Copy the data into each channel.
266 const float* source_data = reinterpret_cast<const float*>(data_.get()) +
267 source_frame_offset * channel_count_;
268 for (int ch = 0; ch < channel_count_; ++ch) {
269 float* dest_data = dest->channel(ch) + dest_frame_offset;
270 for (int i = 0, offset = ch; i < frames_to_copy;
271 ++i, offset += channel_count_) {
272 dest_data[i] = source_data[offset];
275 return;
278 // Remaining formats are integer interleaved data. Use the deinterleaving code
279 // in AudioBus to copy the data.
280 DCHECK(sample_format_ == kSampleFormatU8 ||
281 sample_format_ == kSampleFormatS16 ||
282 sample_format_ == kSampleFormatS32);
283 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
284 int frame_size = channel_count_ * bytes_per_channel;
285 const uint8* source_data = data_.get() + source_frame_offset * frame_size;
286 dest->FromInterleavedPartial(
287 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel);
290 template <class Target, typename Dest>
291 void InterleaveAndConvert(const std::vector<uint8*>& channel_data,
292 size_t frames_to_copy,
293 int trim_start,
294 Dest* dest_data) {
295 for (size_t ch = 0; ch < channel_data.size(); ++ch) {
296 const Target* source_data =
297 reinterpret_cast<const Target*>(channel_data[ch]) + trim_start;
298 for (size_t i = 0, offset = ch; i < frames_to_copy;
299 ++i, offset += channel_data.size()) {
300 dest_data[offset] = ConvertSample<Target, Dest>(source_data[i]);
305 template <typename Dest>
306 void ReadFramesInterleaved(const std::vector<uint8*>& channel_data,
307 int channel_count,
308 SampleFormat sample_format,
309 int frames_to_copy,
310 int trim_start,
311 Dest* dest_data) {
312 switch (sample_format) {
313 case kSampleFormatU8:
314 NOTREACHED();
315 break;
316 case kSampleFormatS16:
317 InterleaveAndConvert<int16, Dest>(
318 channel_data, frames_to_copy * channel_count, trim_start, dest_data);
319 break;
320 case kSampleFormatS32:
321 InterleaveAndConvert<int32, Dest>(
322 channel_data, frames_to_copy * channel_count, trim_start, dest_data);
323 break;
324 case kSampleFormatF32:
325 InterleaveAndConvert<float, Dest>(
326 channel_data, frames_to_copy * channel_count, trim_start, dest_data);
327 break;
328 case kSampleFormatPlanarS16:
329 InterleaveAndConvert<int16, Dest>(channel_data, frames_to_copy,
330 trim_start, dest_data);
331 break;
332 case kSampleFormatPlanarF32:
333 InterleaveAndConvert<float, Dest>(channel_data, frames_to_copy,
334 trim_start, dest_data);
335 break;
336 case kSampleFormatPlanarS32:
337 InterleaveAndConvert<int32, Dest>(channel_data, frames_to_copy,
338 trim_start, dest_data);
339 break;
340 case kUnknownSampleFormat:
341 NOTREACHED();
342 break;
346 void AudioBuffer::ReadFramesInterleavedS32(int frames_to_copy,
347 int32* dest_data) {
348 DCHECK_LE(frames_to_copy, adjusted_frame_count_);
349 ReadFramesInterleaved<int32>(channel_data_, channel_count_, sample_format_,
350 frames_to_copy, trim_start_, dest_data);
353 void AudioBuffer::ReadFramesInterleavedS16(int frames_to_copy,
354 int16* dest_data) {
355 DCHECK_LE(frames_to_copy, adjusted_frame_count_);
356 ReadFramesInterleaved<int16>(channel_data_, channel_count_, sample_format_,
357 frames_to_copy, trim_start_, dest_data);
360 void AudioBuffer::TrimStart(int frames_to_trim) {
361 CHECK_GE(frames_to_trim, 0);
362 CHECK_LE(frames_to_trim, adjusted_frame_count_);
364 // Adjust the number of frames in this buffer and where the start really is.
365 adjusted_frame_count_ -= frames_to_trim;
366 trim_start_ += frames_to_trim;
368 // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
369 const base::TimeDelta old_duration = duration_;
370 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
371 timestamp_ += old_duration - duration_;
374 void AudioBuffer::TrimEnd(int frames_to_trim) {
375 CHECK_GE(frames_to_trim, 0);
376 CHECK_LE(frames_to_trim, adjusted_frame_count_);
378 // Adjust the number of frames and duration for this buffer.
379 adjusted_frame_count_ -= frames_to_trim;
380 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
383 void AudioBuffer::TrimRange(int start, int end) {
384 CHECK_GE(start, 0);
385 CHECK_LE(end, adjusted_frame_count_);
387 const int frames_to_trim = end - start;
388 CHECK_GE(frames_to_trim, 0);
389 CHECK_LE(frames_to_trim, adjusted_frame_count_);
391 const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
392 const int frames_to_copy = adjusted_frame_count_ - end;
393 if (frames_to_copy > 0) {
394 switch (sample_format_) {
395 case kSampleFormatPlanarS16:
396 case kSampleFormatPlanarF32:
397 case kSampleFormatPlanarS32:
398 // Planar data must be shifted per channel.
399 for (int ch = 0; ch < channel_count_; ++ch) {
400 memmove(channel_data_[ch] + (trim_start_ + start) * bytes_per_channel,
401 channel_data_[ch] + (trim_start_ + end) * bytes_per_channel,
402 bytes_per_channel * frames_to_copy);
404 break;
405 case kSampleFormatU8:
406 case kSampleFormatS16:
407 case kSampleFormatS32:
408 case kSampleFormatF32: {
409 // Interleaved data can be shifted all at once.
410 const int frame_size = channel_count_ * bytes_per_channel;
411 memmove(channel_data_[0] + (trim_start_ + start) * frame_size,
412 channel_data_[0] + (trim_start_ + end) * frame_size,
413 frame_size * frames_to_copy);
414 break;
416 case kUnknownSampleFormat:
417 NOTREACHED() << "Invalid sample format!";
419 } else {
420 CHECK_EQ(frames_to_copy, 0);
423 // Trim the leftover data off the end of the buffer and update duration.
424 TrimEnd(frames_to_trim);
427 } // namespace media