Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / media / base / audio_buffer.cc
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
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
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
91 AudioBuffer::~AudioBuffer() {}
92
93 // static
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
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
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
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].
165 static inline float ConvertS16ToFloat(int16 value) {
166   return value * (value < 0 ? -1.0f / kint16min : 1.0f / kint16max);
167 }
168
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
246 static inline int32 ConvertS16ToS32(int16 value) {
247   return static_cast<int32>(value) << 16;
248 }
249
250 static inline int32 ConvertF32ToS32(float value) {
251   return static_cast<int32>(value < 0
252                                 ? (-value) * std::numeric_limits<int32>::min()
253                                 : value * std::numeric_limits<int32>::max());
254 }
255
256 template <class Target, typename Converter>
257 void InterleaveToS32(const std::vector<uint8*>& channel_data,
258                      size_t frames_to_copy,
259                      int trim_start,
260                      int32* dest_data,
261                      Converter convert_func) {
262   for (size_t ch = 0; ch < channel_data.size(); ++ch) {
263     const Target* source_data =
264         reinterpret_cast<const Target*>(channel_data[ch]) + trim_start;
265     for (size_t i = 0, offset = ch; i < frames_to_copy;
266          ++i, offset += channel_data.size()) {
267       dest_data[offset] = convert_func(source_data[i]);
268     }
269   }
270 }
271
272 void AudioBuffer::ReadFramesInterleavedS32(int frames_to_copy,
273                                            int32* dest_data) {
274   DCHECK_LE(frames_to_copy, adjusted_frame_count_);
275
276   switch (sample_format_) {
277     case kSampleFormatU8:
278       NOTIMPLEMENTED();
279       break;
280     case kSampleFormatS16:
281       // Format is interleaved signed16. Convert each value into int32 and
282       // insert into output channel data.
283       InterleaveToS32<int16>(channel_data_,
284                              frames_to_copy * channel_count_,
285                              trim_start_,
286                              dest_data,
287                              ConvertS16ToS32);
288       break;
289     case kSampleFormatS32: {
290       // Format is interleaved signed32; just copy the data.
291       const int32* source_data =
292           reinterpret_cast<const int32*>(channel_data_[0]) + trim_start_;
293       memcpy(dest_data,
294              source_data,
295              frames_to_copy * channel_count_ * sizeof(int32));
296     } break;
297     case kSampleFormatF32:
298       // Format is interleaved float. Convert each value into int32 and insert
299       // into output channel data.
300       InterleaveToS32<float>(channel_data_,
301                              frames_to_copy * channel_count_,
302                              trim_start_,
303                              dest_data,
304                              ConvertF32ToS32);
305       break;
306     case kSampleFormatPlanarS16:
307       // Format is planar signed 16 bit. Convert each value into int32 and
308       // insert into output channel data.
309       InterleaveToS32<int16>(channel_data_,
310                              frames_to_copy,
311                              trim_start_,
312                              dest_data,
313                              ConvertS16ToS32);
314       break;
315     case kSampleFormatPlanarF32:
316       // Format is planar float. Convert each value into int32 and insert into
317       // output channel data.
318       InterleaveToS32<float>(channel_data_,
319                              frames_to_copy,
320                              trim_start_,
321                              dest_data,
322                              ConvertF32ToS32);
323       break;
324     case kUnknownSampleFormat:
325       NOTREACHED();
326       break;
327   }
328 }
329
330 void AudioBuffer::TrimStart(int frames_to_trim) {
331   CHECK_GE(frames_to_trim, 0);
332   CHECK_LE(frames_to_trim, adjusted_frame_count_);
333
334   // Adjust the number of frames in this buffer and where the start really is.
335   adjusted_frame_count_ -= frames_to_trim;
336   trim_start_ += frames_to_trim;
337
338   // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
339   const base::TimeDelta old_duration = duration_;
340   duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
341   timestamp_ += old_duration - duration_;
342 }
343
344 void AudioBuffer::TrimEnd(int frames_to_trim) {
345   CHECK_GE(frames_to_trim, 0);
346   CHECK_LE(frames_to_trim, adjusted_frame_count_);
347
348   // Adjust the number of frames and duration for this buffer.
349   adjusted_frame_count_ -= frames_to_trim;
350   duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
351 }
352
353 void AudioBuffer::TrimRange(int start, int end) {
354   CHECK_GE(start, 0);
355   CHECK_LE(end, adjusted_frame_count_);
356
357   const int frames_to_trim = end - start;
358   CHECK_GE(frames_to_trim, 0);
359   CHECK_LE(frames_to_trim, adjusted_frame_count_);
360
361   const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
362   const int frames_to_copy = adjusted_frame_count_ - end;
363   if (frames_to_copy > 0) {
364     switch (sample_format_) {
365       case kSampleFormatPlanarS16:
366       case kSampleFormatPlanarF32:
367         // Planar data must be shifted per channel.
368         for (int ch = 0; ch < channel_count_; ++ch) {
369           memmove(channel_data_[ch] + (trim_start_ + start) * bytes_per_channel,
370                   channel_data_[ch] + (trim_start_ + end) * bytes_per_channel,
371                   bytes_per_channel * frames_to_copy);
372         }
373         break;
374       case kSampleFormatU8:
375       case kSampleFormatS16:
376       case kSampleFormatS32:
377       case kSampleFormatF32: {
378         // Interleaved data can be shifted all at once.
379         const int frame_size = channel_count_ * bytes_per_channel;
380         memmove(channel_data_[0] + (trim_start_ + start) * frame_size,
381                 channel_data_[0] + (trim_start_ + end) * frame_size,
382                 frame_size * frames_to_copy);
383         break;
384       }
385       case kUnknownSampleFormat:
386         NOTREACHED() << "Invalid sample format!";
387     }
388   } else {
389     CHECK_EQ(frames_to_copy, 0);
390   }
391
392   // Trim the leftover data off the end of the buffer and update duration.
393   TrimEnd(frames_to_trim);
394 }
395
396 }  // namespace media