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 "base/logging.h"
8 #include "media/base/audio_bus.h"
9 #include "media/base/buffers.h"
10 #include "media/base/limits.h"
14 static base::TimeDelta
CalculateDuration(int frames
, double sample_rate
) {
15 DCHECK_GT(sample_rate
, 0);
16 return base::TimeDelta::FromMicroseconds(
17 frames
* base::Time::kMicrosecondsPerSecond
/ sample_rate
);
20 AudioBuffer::AudioBuffer(SampleFormat sample_format
,
21 ChannelLayout channel_layout
,
26 const uint8
* const* data
,
27 const base::TimeDelta timestamp
)
28 : sample_format_(sample_format
),
29 channel_layout_(channel_layout
),
30 channel_count_(channel_count
),
31 sample_rate_(sample_rate
),
32 adjusted_frame_count_(frame_count
),
34 end_of_stream_(!create_buffer
&& data
== NULL
&& frame_count
== 0),
35 timestamp_(timestamp
),
36 duration_(end_of_stream_
38 : CalculateDuration(adjusted_frame_count_
, sample_rate_
)) {
39 CHECK_GE(channel_count_
, 0);
40 CHECK_LE(channel_count_
, limits::kMaxChannels
);
41 CHECK_GE(frame_count
, 0);
42 DCHECK(channel_layout
== CHANNEL_LAYOUT_DISCRETE
||
43 ChannelLayoutToChannelCount(channel_layout
) == channel_count
);
45 int bytes_per_channel
= SampleFormatToBytesPerChannel(sample_format
);
46 DCHECK_LE(bytes_per_channel
, kChannelAlignment
);
47 int data_size
= frame_count
* bytes_per_channel
;
53 if (sample_format
== kSampleFormatPlanarF32
||
54 sample_format
== kSampleFormatPlanarS16
||
55 sample_format
== kSampleFormatPlanarS32
) {
56 // Planar data, so need to allocate buffer for each channel.
57 // Determine per channel data size, taking into account alignment.
58 int block_size_per_channel
=
59 (data_size
+ kChannelAlignment
- 1) & ~(kChannelAlignment
- 1);
60 DCHECK_GE(block_size_per_channel
, data_size
);
62 // Allocate a contiguous buffer for all the channel data.
63 data_
.reset(static_cast<uint8
*>(base::AlignedAlloc(
64 channel_count_
* block_size_per_channel
, kChannelAlignment
)));
65 channel_data_
.reserve(channel_count_
);
67 // Copy each channel's data into the appropriate spot.
68 for (int i
= 0; i
< channel_count_
; ++i
) {
69 channel_data_
.push_back(data_
.get() + i
* block_size_per_channel
);
71 memcpy(channel_data_
[i
], data
[i
], data_size
);
76 // Remaining formats are interleaved data.
77 DCHECK(sample_format_
== kSampleFormatU8
||
78 sample_format_
== kSampleFormatS16
||
79 sample_format_
== kSampleFormatS32
||
80 sample_format_
== kSampleFormatF32
) << sample_format_
;
81 // Allocate our own buffer and copy the supplied data into it. Buffer must
82 // contain the data for all channels.
83 data_size
*= channel_count_
;
85 static_cast<uint8
*>(base::AlignedAlloc(data_size
, kChannelAlignment
)));
86 channel_data_
.reserve(1);
87 channel_data_
.push_back(data_
.get());
89 memcpy(data_
.get(), data
[0], data_size
);
92 AudioBuffer::~AudioBuffer() {}
95 scoped_refptr
<AudioBuffer
> AudioBuffer::CopyFrom(
96 SampleFormat sample_format
,
97 ChannelLayout channel_layout
,
101 const uint8
* const* data
,
102 const base::TimeDelta timestamp
) {
103 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
104 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
106 return make_scoped_refptr(new AudioBuffer(sample_format
,
117 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateBuffer(
118 SampleFormat sample_format
,
119 ChannelLayout channel_layout
,
123 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
124 return make_scoped_refptr(new AudioBuffer(sample_format
,
135 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateEmptyBuffer(
136 ChannelLayout channel_layout
,
140 const base::TimeDelta timestamp
) {
141 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
142 // Since data == NULL, format doesn't matter.
143 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32
,
154 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateEOSBuffer() {
155 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat
,
165 // Convert int16 values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0].
166 static inline float ConvertS16ToFloat(int16 value
) {
167 return value
* (value
< 0 ? -1.0f
/ std::numeric_limits
<int16
>::min()
168 : 1.0f
/ std::numeric_limits
<int16
>::max());
171 void AudioBuffer::ReadFrames(int frames_to_copy
,
172 int source_frame_offset
,
173 int dest_frame_offset
,
175 // Deinterleave each channel (if necessary) and convert to 32bit
176 // floating-point with nominal range -1.0 -> +1.0 (if necessary).
178 // |dest| must have the same number of channels, and the number of frames
179 // specified must be in range.
180 DCHECK(!end_of_stream());
181 DCHECK_EQ(dest
->channels(), channel_count_
);
182 DCHECK_LE(source_frame_offset
+ frames_to_copy
, adjusted_frame_count_
);
183 DCHECK_LE(dest_frame_offset
+ frames_to_copy
, dest
->frames());
185 // Move the start past any frames that have been trimmed.
186 source_frame_offset
+= trim_start_
;
189 // Special case for an empty buffer.
190 dest
->ZeroFramesPartial(dest_frame_offset
, frames_to_copy
);
194 if (sample_format_
== kSampleFormatPlanarF32
) {
195 // Format is planar float32. Copy the data from each channel as a block.
196 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
197 const float* source_data
=
198 reinterpret_cast<const float*>(channel_data_
[ch
]) +
200 memcpy(dest
->channel(ch
) + dest_frame_offset
,
202 sizeof(float) * frames_to_copy
);
207 if (sample_format_
== kSampleFormatPlanarS16
) {
208 // Format is planar signed16. Convert each value into float and insert into
209 // output channel data.
210 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
211 const int16
* source_data
=
212 reinterpret_cast<const int16
*>(channel_data_
[ch
]) +
214 float* dest_data
= dest
->channel(ch
) + dest_frame_offset
;
215 for (int i
= 0; i
< frames_to_copy
; ++i
) {
216 dest_data
[i
] = ConvertS16ToFloat(source_data
[i
]);
222 if (sample_format_
== kSampleFormatF32
) {
223 // Format is interleaved float32. Copy the data into each channel.
224 const float* source_data
= reinterpret_cast<const float*>(data_
.get()) +
225 source_frame_offset
* channel_count_
;
226 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
227 float* dest_data
= dest
->channel(ch
) + dest_frame_offset
;
228 for (int i
= 0, offset
= ch
; i
< frames_to_copy
;
229 ++i
, offset
+= channel_count_
) {
230 dest_data
[i
] = source_data
[offset
];
236 // Remaining formats are integer interleaved data. Use the deinterleaving code
237 // in AudioBus to copy the data.
238 DCHECK(sample_format_
== kSampleFormatU8
||
239 sample_format_
== kSampleFormatS16
||
240 sample_format_
== kSampleFormatS32
);
241 int bytes_per_channel
= SampleFormatToBytesPerChannel(sample_format_
);
242 int frame_size
= channel_count_
* bytes_per_channel
;
243 const uint8
* source_data
= data_
.get() + source_frame_offset
* frame_size
;
244 dest
->FromInterleavedPartial(
245 source_data
, dest_frame_offset
, frames_to_copy
, bytes_per_channel
);
248 static inline int32
ConvertS16ToS32(int16 value
) {
249 return static_cast<int32
>(value
) << 16;
252 static inline int32
ConvertF32ToS32(float value
) {
253 return static_cast<int32
>(value
< 0
254 ? (-value
) * std::numeric_limits
<int32
>::min()
255 : value
* std::numeric_limits
<int32
>::max());
258 // No need for conversion. Return value as is. Keeping function to align with
260 static inline int32
ConvertS32ToS32(int32 value
) {
264 template <class Target
, typename Converter
>
265 void InterleaveToS32(const std::vector
<uint8
*>& channel_data
,
266 size_t frames_to_copy
,
269 Converter convert_func
) {
270 for (size_t ch
= 0; ch
< channel_data
.size(); ++ch
) {
271 const Target
* source_data
=
272 reinterpret_cast<const Target
*>(channel_data
[ch
]) + trim_start
;
273 for (size_t i
= 0, offset
= ch
; i
< frames_to_copy
;
274 ++i
, offset
+= channel_data
.size()) {
275 dest_data
[offset
] = convert_func(source_data
[i
]);
280 void AudioBuffer::ReadFramesInterleavedS32(int frames_to_copy
,
282 DCHECK_LE(frames_to_copy
, adjusted_frame_count_
);
284 switch (sample_format_
) {
285 case kSampleFormatU8
:
288 case kSampleFormatS16
:
289 // Format is interleaved signed16. Convert each value into int32 and
290 // insert into output channel data.
291 InterleaveToS32
<int16
>(channel_data_
,
292 frames_to_copy
* channel_count_
,
297 case kSampleFormatS32
: {
298 // Format is interleaved signed32; just copy the data.
299 const int32
* source_data
=
300 reinterpret_cast<const int32
*>(channel_data_
[0]) + trim_start_
;
303 frames_to_copy
* channel_count_
* sizeof(int32
));
305 case kSampleFormatF32
:
306 // Format is interleaved float. Convert each value into int32 and insert
307 // into output channel data.
308 InterleaveToS32
<float>(channel_data_
,
309 frames_to_copy
* channel_count_
,
314 case kSampleFormatPlanarS16
:
315 // Format is planar signed 16 bit. Convert each value into int32 and
316 // insert into output channel data.
317 InterleaveToS32
<int16
>(channel_data_
,
323 case kSampleFormatPlanarF32
:
324 // Format is planar float. Convert each value into int32 and insert into
325 // output channel data.
326 InterleaveToS32
<float>(channel_data_
,
332 case kSampleFormatPlanarS32
:
333 // Format is planar signed 32 bit. Convert each value into int32 and
334 // insert into output channel data.
335 InterleaveToS32
<int32
>(channel_data_
,
341 case kUnknownSampleFormat
:
347 void AudioBuffer::TrimStart(int frames_to_trim
) {
348 CHECK_GE(frames_to_trim
, 0);
349 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
351 // Adjust the number of frames in this buffer and where the start really is.
352 adjusted_frame_count_
-= frames_to_trim
;
353 trim_start_
+= frames_to_trim
;
355 // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
356 const base::TimeDelta old_duration
= duration_
;
357 duration_
= CalculateDuration(adjusted_frame_count_
, sample_rate_
);
358 timestamp_
+= old_duration
- duration_
;
361 void AudioBuffer::TrimEnd(int frames_to_trim
) {
362 CHECK_GE(frames_to_trim
, 0);
363 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
365 // Adjust the number of frames and duration for this buffer.
366 adjusted_frame_count_
-= frames_to_trim
;
367 duration_
= CalculateDuration(adjusted_frame_count_
, sample_rate_
);
370 void AudioBuffer::TrimRange(int start
, int end
) {
372 CHECK_LE(end
, adjusted_frame_count_
);
374 const int frames_to_trim
= end
- start
;
375 CHECK_GE(frames_to_trim
, 0);
376 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
378 const int bytes_per_channel
= SampleFormatToBytesPerChannel(sample_format_
);
379 const int frames_to_copy
= adjusted_frame_count_
- end
;
380 if (frames_to_copy
> 0) {
381 switch (sample_format_
) {
382 case kSampleFormatPlanarS16
:
383 case kSampleFormatPlanarF32
:
384 case kSampleFormatPlanarS32
:
385 // Planar data must be shifted per channel.
386 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
387 memmove(channel_data_
[ch
] + (trim_start_
+ start
) * bytes_per_channel
,
388 channel_data_
[ch
] + (trim_start_
+ end
) * bytes_per_channel
,
389 bytes_per_channel
* frames_to_copy
);
392 case kSampleFormatU8
:
393 case kSampleFormatS16
:
394 case kSampleFormatS32
:
395 case kSampleFormatF32
: {
396 // Interleaved data can be shifted all at once.
397 const int frame_size
= channel_count_
* bytes_per_channel
;
398 memmove(channel_data_
[0] + (trim_start_
+ start
) * frame_size
,
399 channel_data_
[0] + (trim_start_
+ end
) * frame_size
,
400 frame_size
* frames_to_copy
);
403 case kUnknownSampleFormat
:
404 NOTREACHED() << "Invalid sample format!";
407 CHECK_EQ(frames_to_copy
, 0);
410 // Trim the leftover data off the end of the buffer and update duration.
411 TrimEnd(frames_to_trim
);