• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 namespace media {
13 
CalculateDuration(int frames,double sample_rate)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);
18 }
19 
AudioBuffer(SampleFormat sample_format,ChannelLayout channel_layout,int channel_count,int sample_rate,int frame_count,bool create_buffer,const uint8 * const * data,const base::TimeDelta timestamp)20 AudioBuffer::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 
~AudioBuffer()91 AudioBuffer::~AudioBuffer() {}
92 
93 // static
CopyFrom(SampleFormat sample_format,ChannelLayout channel_layout,int channel_count,int sample_rate,int frame_count,const uint8 * const * data,const base::TimeDelta timestamp)94 scoped_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
CreateBuffer(SampleFormat sample_format,ChannelLayout channel_layout,int channel_count,int sample_rate,int frame_count)116 scoped_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
CreateEmptyBuffer(ChannelLayout channel_layout,int channel_count,int sample_rate,int frame_count,const base::TimeDelta timestamp)134 scoped_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
CreateEOSBuffer()153 scoped_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].
ConvertS16ToFloat(int16 value)165 static inline float ConvertS16ToFloat(int16 value) {
166   return value * (value < 0 ? -1.0f / kint16min : 1.0f / kint16max);
167 }
168 
ReadFrames(int frames_to_copy,int source_frame_offset,int dest_frame_offset,AudioBus * dest)169 void 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 
TrimStart(int frames_to_trim)246 void 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 
TrimEnd(int frames_to_trim)260 void 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 
TrimRange(int start,int end)269 void 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