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 // Planar data, so need to allocate buffer for each channel.
56 // Determine per channel data size, taking into account alignment.
57 int block_size_per_channel
=
58 (data_size
+ kChannelAlignment
- 1) & ~(kChannelAlignment
- 1);
59 DCHECK_GE(block_size_per_channel
, data_size
);
61 // Allocate a contiguous buffer for all the channel data.
62 data_
.reset(static_cast<uint8
*>(base::AlignedAlloc(
63 channel_count_
* block_size_per_channel
, kChannelAlignment
)));
64 channel_data_
.reserve(channel_count_
);
66 // Copy each channel's data into the appropriate spot.
67 for (int i
= 0; i
< channel_count_
; ++i
) {
68 channel_data_
.push_back(data_
.get() + i
* block_size_per_channel
);
70 memcpy(channel_data_
[i
], data
[i
], data_size
);
75 // Remaining formats are interleaved data.
76 DCHECK(sample_format_
== kSampleFormatU8
||
77 sample_format_
== kSampleFormatS16
||
78 sample_format_
== kSampleFormatS32
||
79 sample_format_
== kSampleFormatF32
) << sample_format_
;
80 // Allocate our own buffer and copy the supplied data into it. Buffer must
81 // contain the data for all channels.
82 data_size
*= channel_count_
;
84 static_cast<uint8
*>(base::AlignedAlloc(data_size
, kChannelAlignment
)));
85 channel_data_
.reserve(1);
86 channel_data_
.push_back(data_
.get());
88 memcpy(data_
.get(), data
[0], data_size
);
91 AudioBuffer::~AudioBuffer() {}
94 scoped_refptr
<AudioBuffer
> AudioBuffer::CopyFrom(
95 SampleFormat sample_format
,
96 ChannelLayout channel_layout
,
100 const uint8
* const* data
,
101 const base::TimeDelta timestamp
) {
102 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
103 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
105 return make_scoped_refptr(new AudioBuffer(sample_format
,
116 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateBuffer(
117 SampleFormat sample_format
,
118 ChannelLayout channel_layout
,
122 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
123 return make_scoped_refptr(new AudioBuffer(sample_format
,
134 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateEmptyBuffer(
135 ChannelLayout channel_layout
,
139 const base::TimeDelta timestamp
) {
140 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
141 // Since data == NULL, format doesn't matter.
142 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32
,
153 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateEOSBuffer() {
154 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat
,
164 // Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0].
165 static inline float ConvertS16ToFloat(int16 value
) {
166 return value
* (value
< 0 ? -1.0f
/ kint16min
: 1.0f
/ kint16max
);
169 void AudioBuffer::ReadFrames(int frames_to_copy
,
170 int source_frame_offset
,
171 int dest_frame_offset
,
173 // Deinterleave each channel (if necessary) and convert to 32bit
174 // floating-point with nominal range -1.0 -> +1.0 (if necessary).
176 // |dest| must have the same number of channels, and the number of frames
177 // specified must be in range.
178 DCHECK(!end_of_stream());
179 DCHECK_EQ(dest
->channels(), channel_count_
);
180 DCHECK_LE(source_frame_offset
+ frames_to_copy
, adjusted_frame_count_
);
181 DCHECK_LE(dest_frame_offset
+ frames_to_copy
, dest
->frames());
183 // Move the start past any frames that have been trimmed.
184 source_frame_offset
+= trim_start_
;
187 // Special case for an empty buffer.
188 dest
->ZeroFramesPartial(dest_frame_offset
, frames_to_copy
);
192 if (sample_format_
== kSampleFormatPlanarF32
) {
193 // Format is planar float32. Copy the data from each channel as a block.
194 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
195 const float* source_data
=
196 reinterpret_cast<const float*>(channel_data_
[ch
]) +
198 memcpy(dest
->channel(ch
) + dest_frame_offset
,
200 sizeof(float) * frames_to_copy
);
205 if (sample_format_
== kSampleFormatPlanarS16
) {
206 // Format is planar signed16. Convert each value into float and insert into
207 // output channel data.
208 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
209 const int16
* source_data
=
210 reinterpret_cast<const int16
*>(channel_data_
[ch
]) +
212 float* dest_data
= dest
->channel(ch
) + dest_frame_offset
;
213 for (int i
= 0; i
< frames_to_copy
; ++i
) {
214 dest_data
[i
] = ConvertS16ToFloat(source_data
[i
]);
220 if (sample_format_
== kSampleFormatF32
) {
221 // Format is interleaved float32. Copy the data into each channel.
222 const float* source_data
= reinterpret_cast<const float*>(data_
.get()) +
223 source_frame_offset
* channel_count_
;
224 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
225 float* dest_data
= dest
->channel(ch
) + dest_frame_offset
;
226 for (int i
= 0, offset
= ch
; i
< frames_to_copy
;
227 ++i
, offset
+= channel_count_
) {
228 dest_data
[i
] = source_data
[offset
];
234 // Remaining formats are integer interleaved data. Use the deinterleaving code
235 // in AudioBus to copy the data.
236 DCHECK(sample_format_
== kSampleFormatU8
||
237 sample_format_
== kSampleFormatS16
||
238 sample_format_
== kSampleFormatS32
);
239 int bytes_per_channel
= SampleFormatToBytesPerChannel(sample_format_
);
240 int frame_size
= channel_count_
* bytes_per_channel
;
241 const uint8
* source_data
= data_
.get() + source_frame_offset
* frame_size
;
242 dest
->FromInterleavedPartial(
243 source_data
, dest_frame_offset
, frames_to_copy
, bytes_per_channel
);
246 void AudioBuffer::TrimStart(int frames_to_trim
) {
247 CHECK_GE(frames_to_trim
, 0);
248 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
250 // Adjust the number of frames in this buffer and where the start really is.
251 adjusted_frame_count_
-= frames_to_trim
;
252 trim_start_
+= frames_to_trim
;
254 // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
255 const base::TimeDelta old_duration
= duration_
;
256 duration_
= CalculateDuration(adjusted_frame_count_
, sample_rate_
);
257 timestamp_
+= old_duration
- duration_
;
260 void AudioBuffer::TrimEnd(int frames_to_trim
) {
261 CHECK_GE(frames_to_trim
, 0);
262 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
264 // Adjust the number of frames and duration for this buffer.
265 adjusted_frame_count_
-= frames_to_trim
;
266 duration_
= CalculateDuration(adjusted_frame_count_
, sample_rate_
);
269 void AudioBuffer::TrimRange(int start
, int end
) {
271 CHECK_LE(end
, adjusted_frame_count_
);
273 const int frames_to_trim
= end
- start
;
274 CHECK_GE(frames_to_trim
, 0);
275 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
277 const int bytes_per_channel
= SampleFormatToBytesPerChannel(sample_format_
);
278 const int frames_to_copy
= adjusted_frame_count_
- end
;
279 if (frames_to_copy
> 0) {
280 switch (sample_format_
) {
281 case kSampleFormatPlanarS16
:
282 case kSampleFormatPlanarF32
:
283 // Planar data must be shifted per channel.
284 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
285 memmove(channel_data_
[ch
] + (trim_start_
+ start
) * bytes_per_channel
,
286 channel_data_
[ch
] + (trim_start_
+ end
) * bytes_per_channel
,
287 bytes_per_channel
* frames_to_copy
);
290 case kSampleFormatU8
:
291 case kSampleFormatS16
:
292 case kSampleFormatS32
:
293 case kSampleFormatF32
: {
294 // Interleaved data can be shifted all at once.
295 const int frame_size
= channel_count_
* bytes_per_channel
;
296 memmove(channel_data_
[0] + (trim_start_
+ start
) * frame_size
,
297 channel_data_
[0] + (trim_start_
+ end
) * frame_size
,
298 frame_size
* frames_to_copy
);
301 case kUnknownSampleFormat
:
302 NOTREACHED() << "Invalid sample format!";
305 CHECK_EQ(frames_to_copy
, 0);
308 // Trim the leftover data off the end of the buffer and update duration.
309 TrimEnd(frames_to_trim
);