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.
4
5#include "media/base/audio_buffer.h"
6
7#include "base/logging.h"
8#include "media/base/audio_bus.h"
9#include "media/base/buffers.h"
10#include "media/base/limits.h"
11
12namespace media {
13
14static 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);
18}
19
20AudioBuffer::AudioBuffer(SampleFormat sample_format,
21                         ChannelLayout channel_layout,
22                         int channel_count,
23                         int sample_rate,
24                         int frame_count,
25                         bool create_buffer,
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),
33      trim_start_(0),
34      end_of_stream_(!create_buffer && data == NULL && frame_count == 0),
35      timestamp_(timestamp),
36      duration_(end_of_stream_
37                    ? base::TimeDelta()
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);
44
45  int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
46  DCHECK_LE(bytes_per_channel, kChannelAlignment);
47  int data_size = frame_count * bytes_per_channel;
48
49  // Empty buffer?
50  if (!create_buffer)
51    return;
52
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);
60
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_);
65
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);
69      if (data)
70        memcpy(channel_data_[i], data[i], data_size);
71    }
72    return;
73  }
74
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_;
83  data_.reset(
84      static_cast<uint8*>(base::AlignedAlloc(data_size, kChannelAlignment)));
85  channel_data_.reserve(1);
86  channel_data_.push_back(data_.get());
87  if (data)
88    memcpy(data_.get(), data[0], data_size);
89}
90
91AudioBuffer::~AudioBuffer() {}
92
93// static
94scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom(
95    SampleFormat sample_format,
96    ChannelLayout channel_layout,
97    int channel_count,
98    int sample_rate,
99    int frame_count,
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.
104  CHECK(data[0]);
105  return make_scoped_refptr(new AudioBuffer(sample_format,
106                                            channel_layout,
107                                            channel_count,
108                                            sample_rate,
109                                            frame_count,
110                                            true,
111                                            data,
112                                            timestamp));
113}
114
115// static
116scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer(
117    SampleFormat sample_format,
118    ChannelLayout channel_layout,
119    int channel_count,
120    int sample_rate,
121    int frame_count) {
122  CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
123  return make_scoped_refptr(new AudioBuffer(sample_format,
124                                            channel_layout,
125                                            channel_count,
126                                            sample_rate,
127                                            frame_count,
128                                            true,
129                                            NULL,
130                                            kNoTimestamp()));
131}
132
133// static
134scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer(
135    ChannelLayout channel_layout,
136    int channel_count,
137    int sample_rate,
138    int frame_count,
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,
143                                            channel_layout,
144                                            channel_count,
145                                            sample_rate,
146                                            frame_count,
147                                            false,
148                                            NULL,
149                                            timestamp));
150}
151
152// static
153scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() {
154  return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat,
155                                            CHANNEL_LAYOUT_NONE,
156                                            0,
157                                            0,
158                                            0,
159                                            false,
160                                            NULL,
161                                            kNoTimestamp()));
162}
163
164// Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0].
165static inline float ConvertS16ToFloat(int16 value) {
166  return value * (value < 0 ? -1.0f / kint16min : 1.0f / kint16max);
167}
168
169void AudioBuffer::ReadFrames(int frames_to_copy,
170                             int source_frame_offset,
171                             int dest_frame_offset,
172                             AudioBus* dest) {
173  // Deinterleave each channel (if necessary) and convert to 32bit
174  // floating-point with nominal range -1.0 -> +1.0 (if necessary).
175
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());
182
183  // Move the start past any frames that have been trimmed.
184  source_frame_offset += trim_start_;
185
186  if (!data_) {
187    // Special case for an empty buffer.
188    dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy);
189    return;
190  }
191
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]) +
197          source_frame_offset;
198      memcpy(dest->channel(ch) + dest_frame_offset,
199             source_data,
200             sizeof(float) * frames_to_copy);
201    }
202    return;
203  }
204
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]) +
211          source_frame_offset;
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]);
215      }
216    }
217    return;
218  }
219
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];
229      }
230    }
231    return;
232  }
233
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);
244}
245
246void AudioBuffer::TrimStart(int frames_to_trim) {
247  CHECK_GE(frames_to_trim, 0);
248  CHECK_LE(frames_to_trim, adjusted_frame_count_);
249
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;
253
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_;
258}
259
260void AudioBuffer::TrimEnd(int frames_to_trim) {
261  CHECK_GE(frames_to_trim, 0);
262  CHECK_LE(frames_to_trim, adjusted_frame_count_);
263
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_);
267}
268
269void AudioBuffer::TrimRange(int start, int end) {
270  CHECK_GE(start, 0);
271  CHECK_LE(end, adjusted_frame_count_);
272
273  const int frames_to_trim = end - start;
274  CHECK_GE(frames_to_trim, 0);
275  CHECK_LE(frames_to_trim, adjusted_frame_count_);
276
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);
288        }
289        break;
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);
299        break;
300      }
301      case kUnknownSampleFormat:
302        NOTREACHED() << "Invalid sample format!";
303    }
304  } else {
305    CHECK_EQ(frames_to_copy, 0);
306  }
307
308  // Trim the leftover data off the end of the buffer and update duration.
309  TrimEnd(frames_to_trim);
310}
311
312}  // namespace media
313