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
,
18 const uint8
* const* data
,
19 const base::TimeDelta timestamp
,
20 const base::TimeDelta duration
)
21 : sample_format_(sample_format
),
22 channel_count_(channel_count
),
23 adjusted_frame_count_(frame_count
),
25 end_of_stream_(!create_buffer
&& data
== NULL
&& frame_count
== 0),
26 timestamp_(timestamp
),
28 CHECK_GE(channel_count
, 0);
29 CHECK_LE(channel_count
, limits::kMaxChannels
);
30 CHECK_GE(frame_count
, 0);
31 int bytes_per_channel
= SampleFormatToBytesPerChannel(sample_format
);
32 DCHECK_LE(bytes_per_channel
, kChannelAlignment
);
33 int data_size
= frame_count
* bytes_per_channel
;
39 if (sample_format
== kSampleFormatPlanarF32
||
40 sample_format
== kSampleFormatPlanarS16
) {
41 // Planar data, so need to allocate buffer for each channel.
42 // Determine per channel data size, taking into account alignment.
43 int block_size_per_channel
=
44 (data_size
+ kChannelAlignment
- 1) & ~(kChannelAlignment
- 1);
45 DCHECK_GE(block_size_per_channel
, data_size
);
47 // Allocate a contiguous buffer for all the channel data.
48 data_
.reset(static_cast<uint8
*>(base::AlignedAlloc(
49 channel_count
* block_size_per_channel
, kChannelAlignment
)));
50 channel_data_
.reserve(channel_count
);
52 // Copy each channel's data into the appropriate spot.
53 for (int i
= 0; i
< channel_count
; ++i
) {
54 channel_data_
.push_back(data_
.get() + i
* block_size_per_channel
);
56 memcpy(channel_data_
[i
], data
[i
], data_size
);
61 // Remaining formats are interleaved data.
62 DCHECK(sample_format_
== kSampleFormatU8
||
63 sample_format_
== kSampleFormatS16
||
64 sample_format_
== kSampleFormatS32
||
65 sample_format_
== kSampleFormatF32
) << sample_format_
;
66 // Allocate our own buffer and copy the supplied data into it. Buffer must
67 // contain the data for all channels.
68 data_size
*= channel_count
;
70 static_cast<uint8
*>(base::AlignedAlloc(data_size
, kChannelAlignment
)));
71 channel_data_
.reserve(1);
72 channel_data_
.push_back(data_
.get());
74 memcpy(data_
.get(), data
[0], data_size
);
77 AudioBuffer::~AudioBuffer() {}
80 scoped_refptr
<AudioBuffer
> AudioBuffer::CopyFrom(
81 SampleFormat sample_format
,
84 const uint8
* const* data
,
85 const base::TimeDelta timestamp
,
86 const base::TimeDelta duration
) {
87 // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
88 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
90 return make_scoped_refptr(new AudioBuffer(sample_format
,
100 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateBuffer(SampleFormat sample_format
,
103 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
104 return make_scoped_refptr(new AudioBuffer(sample_format
,
114 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateEmptyBuffer(
117 const base::TimeDelta timestamp
,
118 const base::TimeDelta duration
) {
119 CHECK_GT(frame_count
, 0); // Otherwise looks like an EOF buffer.
120 // Since data == NULL, format doesn't matter.
121 return make_scoped_refptr(new AudioBuffer(kSampleFormatF32
,
131 scoped_refptr
<AudioBuffer
> AudioBuffer::CreateEOSBuffer() {
132 return make_scoped_refptr(new AudioBuffer(
133 kUnknownSampleFormat
, 1, 0, false, NULL
, kNoTimestamp(), kNoTimestamp()));
136 // Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0].
137 static inline float ConvertS16ToFloat(int16 value
) {
138 return value
* (value
< 0 ? -1.0f
/ kint16min
: 1.0f
/ kint16max
);
141 void AudioBuffer::ReadFrames(int frames_to_copy
,
142 int source_frame_offset
,
143 int dest_frame_offset
,
145 // Deinterleave each channel (if necessary) and convert to 32bit
146 // floating-point with nominal range -1.0 -> +1.0 (if necessary).
148 // |dest| must have the same number of channels, and the number of frames
149 // specified must be in range.
150 DCHECK(!end_of_stream());
151 DCHECK_EQ(dest
->channels(), channel_count_
);
152 DCHECK_LE(source_frame_offset
+ frames_to_copy
, adjusted_frame_count_
);
153 DCHECK_LE(dest_frame_offset
+ frames_to_copy
, dest
->frames());
155 // Move the start past any frames that have been trimmed.
156 source_frame_offset
+= trim_start_
;
159 // Special case for an empty buffer.
160 dest
->ZeroFramesPartial(dest_frame_offset
, frames_to_copy
);
164 if (sample_format_
== kSampleFormatPlanarF32
) {
165 // Format is planar float32. Copy the data from each channel as a block.
166 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
167 const float* source_data
=
168 reinterpret_cast<const float*>(channel_data_
[ch
]) +
170 memcpy(dest
->channel(ch
) + dest_frame_offset
,
172 sizeof(float) * frames_to_copy
);
177 if (sample_format_
== kSampleFormatPlanarS16
) {
178 // Format is planar signed16. Convert each value into float and insert into
179 // output channel data.
180 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
181 const int16
* source_data
=
182 reinterpret_cast<const int16
*>(channel_data_
[ch
]) +
184 float* dest_data
= dest
->channel(ch
) + dest_frame_offset
;
185 for (int i
= 0; i
< frames_to_copy
; ++i
) {
186 dest_data
[i
] = ConvertS16ToFloat(source_data
[i
]);
192 if (sample_format_
== kSampleFormatF32
) {
193 // Format is interleaved float32. Copy the data into each channel.
194 const float* source_data
= reinterpret_cast<const float*>(data_
.get()) +
195 source_frame_offset
* channel_count_
;
196 for (int ch
= 0; ch
< channel_count_
; ++ch
) {
197 float* dest_data
= dest
->channel(ch
) + dest_frame_offset
;
198 for (int i
= 0, offset
= ch
; i
< frames_to_copy
;
199 ++i
, offset
+= channel_count_
) {
200 dest_data
[i
] = source_data
[offset
];
206 // Remaining formats are integer interleaved data. Use the deinterleaving code
207 // in AudioBus to copy the data.
208 DCHECK(sample_format_
== kSampleFormatU8
||
209 sample_format_
== kSampleFormatS16
||
210 sample_format_
== kSampleFormatS32
);
211 int bytes_per_channel
= SampleFormatToBytesPerChannel(sample_format_
);
212 int frame_size
= channel_count_
* bytes_per_channel
;
213 const uint8
* source_data
= data_
.get() + source_frame_offset
* frame_size
;
214 dest
->FromInterleavedPartial(
215 source_data
, dest_frame_offset
, frames_to_copy
, bytes_per_channel
);
218 void AudioBuffer::TrimStart(int frames_to_trim
) {
219 CHECK_GE(frames_to_trim
, 0);
220 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
222 // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
223 double offset
= static_cast<double>(duration_
.InMicroseconds()) *
224 frames_to_trim
/ adjusted_frame_count_
;
225 base::TimeDelta offset_as_time
=
226 base::TimeDelta::FromMicroseconds(static_cast<int64
>(offset
));
227 timestamp_
+= offset_as_time
;
228 duration_
-= offset_as_time
;
230 // Finally adjust the number of frames in this buffer and where the start
232 adjusted_frame_count_
-= frames_to_trim
;
233 trim_start_
+= frames_to_trim
;
236 void AudioBuffer::TrimEnd(int frames_to_trim
) {
237 CHECK_GE(frames_to_trim
, 0);
238 CHECK_LE(frames_to_trim
, adjusted_frame_count_
);
240 // Adjust duration_ only to reflect the smaller number of frames.
241 double offset
= static_cast<double>(duration_
.InMicroseconds()) *
242 frames_to_trim
/ adjusted_frame_count_
;
243 base::TimeDelta offset_as_time
=
244 base::TimeDelta::FromMicroseconds(static_cast<int64
>(offset
));
245 duration_
-= offset_as_time
;
247 // Finally adjust the number of frames in this buffer.
248 adjusted_frame_count_
-= frames_to_trim
;