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 AudioBuffer::AudioBuffer(SampleFormat sample_format
,
15 ChannelLayout channel_layout
,
19 const uint8
* const* data
,
20 const base::TimeDelta timestamp
,
21 const base::TimeDelta duration
)
22 : sample_format_(sample_format
),
23 channel_layout_(channel_layout
),
24 channel_count_(ChannelLayoutToChannelCount(channel_layout
)),
25 sample_rate_(sample_rate
),
26 adjusted_frame_count_(frame_count
),
28 end_of_stream_(!create_buffer
&& data
== NULL
&& frame_count
== 0),
29 timestamp_(timestamp
),
31 CHECK_GE(channel_count_
, 0);
32 CHECK_LE(channel_count_
, limits::kMaxChannels
);
33 CHECK_GE(frame_count
, 0);
34 int bytes_per_channel
= SampleFormatToBytesPerChannel(sample_format
);
35 DCHECK_LE(bytes_per_channel
, kChannelAlignment
);
36 int data_size
= frame_count
* bytes_per_channel
;
42 if (sample_format
== kSampleFormatPlanarF32
||
43 sample_format
== kSampleFormatPlanarS16
) {
44 // Planar data, so need to allocate buffer for each channel.
45 // Determine per channel data size, taking into account alignment.
46 int block_size_per_channel
=
47 (data_size
+ kChannelAlignment
- 1) & ~(kChannelAlignment
- 1);
48 DCHECK_GE(block_size_per_channel
, data_size
);
50 // Allocate a contiguous buffer for all the channel data.
51 data_
.reset(static_cast<uint8
*>(base::AlignedAlloc(
52 channel_count_
* block_size_per_channel
, kChannelAlignment
)));
53 channel_data_
.reserve(channel_count_
);
55 // Copy each channel's data into the appropriate spot.
56 for (int i
= 0; i
< channel_count_
; ++i
) {
57 channel_data_
.push_back(data_
.get() + i
* block_size_per_channel
);
59 memcpy(channel_data_
[i
], data
[i
], data_size
);
64 // Remaining formats are interleaved data.
65 DCHECK(sample_format_
== kSampleFormatU8
||
66 sample_format_
== kSampleFormatS16
||
67 sample_format_
== kSampleFormatS32
||
68 sample_format_
== kSampleFormatF32
) << sample_format_
;
69 // Allocate our own buffer and copy the supplied data into it. Buffer must
70 // contain the data for all channels.
71 data_size
*= channel_count_
;
73 static_cast<uint8
*>(base::AlignedAlloc(data_size
, kChannelAlignment
)));
74 channel_data_
.reserve(1);
75 channel_data_
.push_back(data_
.get());
77 memcpy(data_
.get(), data
[0], data_size
);
80 AudioBuffer::~AudioBuffer() {}
83 scoped_refptr
<AudioBuffer
> AudioBuffer::CopyFrom(
84 SampleFormat sample_format
,
85 ChannelLayout channel_layout
,
88 const uint8
* const* data
,
89 const base::TimeDelta timestamp
,
90 const base::TimeDelta duration
) {
91 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
92 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
94 return make_scoped_refptr(new AudioBuffer(sample_format
,
105 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateBuffer(
106 SampleFormat sample_format
,
107 ChannelLayout channel_layout
,
110 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
111 return make_scoped_refptr(new AudioBuffer(sample_format
,
122 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateEmptyBuffer(
123 ChannelLayout channel_layout
,
126 const base::TimeDelta timestamp
,
127 const base::TimeDelta duration
) {
128 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
129 // Since data == NULL, format doesn't matter.
130 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32
,
141 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateEOSBuffer() {
142 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat
,
152 // Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0].
153 static inline float ConvertS16ToFloat(int16 value
) {
154 return value
* (value
< 0 ? -1.0f
/ kint16min
: 1.0f
/ kint16max
);
157 void AudioBuffer::ReadFrames(int frames_to_copy
,
158 int source_frame_offset
,
159 int dest_frame_offset
,
161 // Deinterleave each channel (if necessary) and convert to 32bit
162 // floating-point with nominal range -1.0 -> +1.0 (if necessary).
164 // |dest| must have the same number of channels, and the number of frames
165 // specified must be in range.
166 DCHECK(!end_of_stream());
167 DCHECK_EQ(dest
->channels(), channel_count_
);
168 DCHECK_LE(source_frame_offset
+ frames_to_copy
, adjusted_frame_count_
);
169 DCHECK_LE(dest_frame_offset
+ frames_to_copy
, dest
->frames());
171 // Move the start past any frames that have been trimmed.
172 source_frame_offset
+= trim_start_
;
175 // Special case for an empty buffer.
176 dest
->ZeroFramesPartial(dest_frame_offset
, frames_to_copy
);
180 if (sample_format_
== kSampleFormatPlanarF32
) {
181 // Format is planar float32. Copy the data from each channel as a block.
182 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
183 const float* source_data
=
184 reinterpret_cast<const float*>(channel_data_
[ch
]) +
186 memcpy(dest
->channel(ch
) + dest_frame_offset
,
188 sizeof(float) * frames_to_copy
);
193 if (sample_format_
== kSampleFormatPlanarS16
) {
194 // Format is planar signed16. Convert each value into float and insert into
195 // output channel data.
196 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
197 const int16
* source_data
=
198 reinterpret_cast<const int16
*>(channel_data_
[ch
]) +
200 float* dest_data
= dest
->channel(ch
) + dest_frame_offset
;
201 for (int i
= 0; i
< frames_to_copy
; ++i
) {
202 dest_data
[i
] = ConvertS16ToFloat(source_data
[i
]);
208 if (sample_format_
== kSampleFormatF32
) {
209 // Format is interleaved float32. Copy the data into each channel.
210 const float* source_data
= reinterpret_cast<const float*>(data_
.get()) +
211 source_frame_offset
* channel_count_
;
212 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
213 float* dest_data
= dest
->channel(ch
) + dest_frame_offset
;
214 for (int i
= 0, offset
= ch
; i
< frames_to_copy
;
215 ++i
, offset
+= channel_count_
) {
216 dest_data
[i
] = source_data
[offset
];
222 // Remaining formats are integer interleaved data. Use the deinterleaving code
223 // in AudioBus to copy the data.
224 DCHECK(sample_format_
== kSampleFormatU8
||
225 sample_format_
== kSampleFormatS16
||
226 sample_format_
== kSampleFormatS32
);
227 int bytes_per_channel
= SampleFormatToBytesPerChannel(sample_format_
);
228 int frame_size
= channel_count_
* bytes_per_channel
;
229 const uint8
* source_data
= data_
.get() + source_frame_offset
* frame_size
;
230 dest
->FromInterleavedPartial(
231 source_data
, dest_frame_offset
, frames_to_copy
, bytes_per_channel
);
234 void AudioBuffer::TrimStart(int frames_to_trim
) {
235 CHECK_GE(frames_to_trim
, 0);
236 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
238 // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
239 double offset
= static_cast<double>(duration_
.InMicroseconds()) *
240 frames_to_trim
/ adjusted_frame_count_
;
241 base::TimeDelta offset_as_time
=
242 base::TimeDelta::FromMicroseconds(static_cast<int64
>(offset
));
243 timestamp_
+= offset_as_time
;
244 duration_
-= offset_as_time
;
246 // Finally adjust the number of frames in this buffer and where the start
248 adjusted_frame_count_
-= frames_to_trim
;
249 trim_start_
+= frames_to_trim
;
252 void AudioBuffer::TrimEnd(int frames_to_trim
) {
253 CHECK_GE(frames_to_trim
, 0);
254 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
256 // Adjust duration_ only to reflect the smaller number of frames.
257 double offset
= static_cast<double>(duration_
.InMicroseconds()) *
258 frames_to_trim
/ adjusted_frame_count_
;
259 base::TimeDelta offset_as_time
=
260 base::TimeDelta::FromMicroseconds(static_cast<int64
>(offset
));
261 duration_
-= offset_as_time
;
263 // Finally adjust the number of frames in this buffer.
264 adjusted_frame_count_
-= frames_to_trim
;