17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file. 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "media/base/audio_buffer.h" 67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/logging.h" 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "media/base/audio_bus.h" 97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "media/base/buffers.h" 107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "media/base/limits.h" 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace media { 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static base::TimeDelta CalculateDuration(int frames, double sample_rate) { 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_GT(sample_rate, 0); 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return base::TimeDelta::FromMicroseconds( 17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) frames * base::Time::kMicrosecondsPerSecond / sample_rate); 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)AudioBuffer::AudioBuffer(SampleFormat sample_format, 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ChannelLayout channel_layout, 22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int channel_count, 2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int sample_rate, 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int frame_count, 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool create_buffer, 267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const uint8* const* data, 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::TimeDelta timestamp) 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : sample_format_(sample_format), 2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_layout_(channel_layout), 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch channel_count_(channel_count), 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) sample_rate_(sample_rate), 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch adjusted_frame_count_(frame_count), 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch trim_start_(0), 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) end_of_stream_(!create_buffer && data == NULL && frame_count == 0), 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) timestamp_(timestamp), 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) duration_(end_of_stream_ 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ? base::TimeDelta() 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : CalculateDuration(adjusted_frame_count_, sample_rate_)) { 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) CHECK_GE(channel_count_, 0); 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) CHECK_LE(channel_count_, limits::kMaxChannels); 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK_GE(frame_count, 0); 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE || 43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ChannelLayoutToChannelCount(channel_layout) == channel_count); 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format); 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK_LE(bytes_per_channel, kChannelAlignment); 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int data_size = frame_count * bytes_per_channel; 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Empty buffer? 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!create_buffer) 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (sample_format == kSampleFormatPlanarF32 || 547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sample_format == kSampleFormatPlanarS16) { 557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Planar data, so need to allocate buffer for each channel. 567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Determine per channel data size, taking into account alignment. 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int block_size_per_channel = 587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (data_size + kChannelAlignment - 1) & ~(kChannelAlignment - 1); 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK_GE(block_size_per_channel, data_size); 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Allocate a contiguous buffer for all the channel data. 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) data_.reset(static_cast<uint8*>(base::AlignedAlloc( 6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_count_ * block_size_per_channel, kChannelAlignment))); 6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_data_.reserve(channel_count_); 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Copy each channel's data into the appropriate spot. 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) for (int i = 0; i < channel_count_; ++i) { 687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) channel_data_.push_back(data_.get() + i * block_size_per_channel); 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (data) 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) memcpy(channel_data_[i], data[i], data_size); 717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Remaining formats are interleaved data. 767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(sample_format_ == kSampleFormatU8 || 777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sample_format_ == kSampleFormatS16 || 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sample_format_ == kSampleFormatS32 || 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sample_format_ == kSampleFormatF32) << sample_format_; 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Allocate our own buffer and copy the supplied data into it. Buffer must 817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // contain the data for all channels. 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) data_size *= channel_count_; 837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) data_.reset( 847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static_cast<uint8*>(base::AlignedAlloc(data_size, kChannelAlignment))); 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) channel_data_.reserve(1); 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) channel_data_.push_back(data_.get()); 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (data) 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) memcpy(data_.get(), data[0], data_size); 897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)AudioBuffer::~AudioBuffer() {} 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom( 957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SampleFormat sample_format, 9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ChannelLayout channel_layout, 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int channel_count, 9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int sample_rate, 997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int frame_count, 1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const uint8* const* data, 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::TimeDelta timestamp) { 1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. 1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK(data[0]); 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return make_scoped_refptr(new AudioBuffer(sample_format, 10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_layout, 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch channel_count, 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) sample_rate, 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) frame_count, 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) true, 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) data, 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) timestamp)); 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static 11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer( 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SampleFormat sample_format, 11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ChannelLayout channel_layout, 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int channel_count, 12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int sample_rate, 12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int frame_count) { 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. 123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return make_scoped_refptr(new AudioBuffer(sample_format, 12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_layout, 125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch channel_count, 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) sample_rate, 127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) frame_count, 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) true, 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NULL, 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) kNoTimestamp())); 1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochscoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer( 13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ChannelLayout channel_layout, 136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int channel_count, 13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int sample_rate, 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int frame_count, 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::TimeDelta timestamp) { 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CHECK_GT(frame_count, 0); // Otherwise looks like an EOF buffer. 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Since data == NULL, format doesn't matter. 142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return make_scoped_refptr(new AudioBuffer(kSampleFormatF32, 14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_layout, 144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch channel_count, 14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) sample_rate, 146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) frame_count, 147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) false, 148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NULL, 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) timestamp)); 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() { 15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, 15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) CHANNEL_LAYOUT_NONE, 15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 0, 15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 0, 158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 0, 15923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) false, 16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL, 16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kNoTimestamp())); 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0]. 1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static inline float ConvertS16ToFloat(int16 value) { 1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return value * (value < 0 ? -1.0f / kint16min : 1.0f / kint16max); 1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void AudioBuffer::ReadFrames(int frames_to_copy, 1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int source_frame_offset, 1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int dest_frame_offset, 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AudioBus* dest) { 1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Deinterleave each channel (if necessary) and convert to 32bit 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // floating-point with nominal range -1.0 -> +1.0 (if necessary). 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |dest| must have the same number of channels, and the number of frames 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // specified must be in range. 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(!end_of_stream()); 1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK_EQ(dest->channels(), channel_count_); 180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_); 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames()); 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Move the start past any frames that have been trimmed. 184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) source_frame_offset += trim_start_; 185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!data_) { 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Special case for an empty buffer. 1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy); 1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (sample_format_ == kSampleFormatPlanarF32) { 1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Format is planar float32. Copy the data from each channel as a block. 1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int ch = 0; ch < channel_count_; ++ch) { 1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const float* source_data = 1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) reinterpret_cast<const float*>(channel_data_[ch]) + 1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source_frame_offset; 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) memcpy(dest->channel(ch) + dest_frame_offset, 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source_data, 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sizeof(float) * frames_to_copy); 2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (sample_format_ == kSampleFormatPlanarS16) { 2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Format is planar signed16. Convert each value into float and insert into 2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // output channel data. 2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int ch = 0; ch < channel_count_; ++ch) { 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const int16* source_data = 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) reinterpret_cast<const int16*>(channel_data_[ch]) + 2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source_frame_offset; 2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) float* dest_data = dest->channel(ch) + dest_frame_offset; 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int i = 0; i < frames_to_copy; ++i) { 2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dest_data[i] = ConvertS16ToFloat(source_data[i]); 2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (sample_format_ == kSampleFormatF32) { 2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Format is interleaved float32. Copy the data into each channel. 2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const float* source_data = reinterpret_cast<const float*>(data_.get()) + 2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source_frame_offset * channel_count_; 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int ch = 0; ch < channel_count_; ++ch) { 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) float* dest_data = dest->channel(ch) + dest_frame_offset; 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int i = 0, offset = ch; i < frames_to_copy; 2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ++i, offset += channel_count_) { 2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dest_data[i] = source_data[offset]; 2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Remaining formats are integer interleaved data. Use the deinterleaving code 2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // in AudioBus to copy the data. 2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(sample_format_ == kSampleFormatU8 || 2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sample_format_ == kSampleFormatS16 || 2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sample_format_ == kSampleFormatS32); 2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int frame_size = channel_count_ * bytes_per_channel; 2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const uint8* source_data = data_.get() + source_frame_offset * frame_size; 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dest->FromInterleavedPartial( 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AudioBuffer::TrimStart(int frames_to_trim) { 247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CHECK_GE(frames_to_trim, 0); 248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CHECK_LE(frames_to_trim, adjusted_frame_count_); 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Adjust the number of frames in this buffer and where the start really is. 251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) adjusted_frame_count_ -= frames_to_trim; 252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) trim_start_ += frames_to_trim; 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Adjust timestamp_ and duration_ to reflect the smaller number of frames. 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::TimeDelta old_duration = duration_; 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) timestamp_ += old_duration - duration_; 258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void AudioBuffer::TrimEnd(int frames_to_trim) { 261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CHECK_GE(frames_to_trim, 0); 262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CHECK_LE(frames_to_trim, adjusted_frame_count_); 263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Adjust the number of frames and duration for this buffer. 265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) adjusted_frame_count_ -= frames_to_trim; 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AudioBuffer::TrimRange(int start, int end) { 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK_GE(start, 0); 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK_LE(end, adjusted_frame_count_); 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const int frames_to_trim = end - start; 274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK_GE(frames_to_trim, 0); 275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK_LE(frames_to_trim, adjusted_frame_count_); 276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); 278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const int frames_to_copy = adjusted_frame_count_ - end; 279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (frames_to_copy > 0) { 280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch (sample_format_) { 281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case kSampleFormatPlanarS16: 282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case kSampleFormatPlanarF32: 283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Planar data must be shifted per channel. 284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (int ch = 0; ch < channel_count_; ++ch) { 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) memmove(channel_data_[ch] + (trim_start_ + start) * bytes_per_channel, 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) channel_data_[ch] + (trim_start_ + end) * bytes_per_channel, 287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bytes_per_channel * frames_to_copy); 288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) break; 290010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case kSampleFormatU8: 291010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case kSampleFormatS16: 292010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case kSampleFormatS32: 293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case kSampleFormatF32: { 294010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Interleaved data can be shifted all at once. 295010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const int frame_size = channel_count_ * bytes_per_channel; 296010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) memmove(channel_data_[0] + (trim_start_ + start) * frame_size, 297010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) channel_data_[0] + (trim_start_ + end) * frame_size, 298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) frame_size * frames_to_copy); 299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) break; 300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case kUnknownSampleFormat: 302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NOTREACHED() << "Invalid sample format!"; 303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 304010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK_EQ(frames_to_copy, 0); 306010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Trim the leftover data off the end of the buffer and update duration. 309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TrimEnd(frames_to_trim); 3107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace media 313