1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/renderer/media/android/audio_decoder_android.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <errno.h> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <fcntl.h> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <limits.h> 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <sys/mman.h> 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <unistd.h> 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/file_descriptor_posix.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/memory/shared_memory.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/posix/eintr_wrapper.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/common/view_messages.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/android/webaudio_media_codec_info.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_bus.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/limits.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebAudioBus.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace content { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AudioDecoderIO { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioDecoderIO(const char* data, size_t data_size); 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~AudioDecoderIO(); 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool ShareEncodedToProcess(base::SharedMemoryHandle* handle); 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Returns true if AudioDecoderIO was successfully created. 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool IsValid() const; 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int read_fd() const { return read_fd_; } 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int write_fd() const { return write_fd_; } 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Shared memory that will hold the encoded audio data. This is 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // used by MediaCodec for decoding. 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SharedMemory encoded_shared_memory_; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // A pipe used to communicate with MediaCodec. MediaCodec owns 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // write_fd_ and writes to it. 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int read_fd_; 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int write_fd_; 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AudioDecoderIO); 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AudioDecoderIO::AudioDecoderIO(const char* data, size_t data_size) 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : read_fd_(-1), 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) write_fd_(-1) { 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!data || !data_size || data_size > 0x80000000) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create the shared memory and copy our data to it so that 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // MediaCodec can access it. 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) encoded_shared_memory_.CreateAndMapAnonymous(data_size); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!encoded_shared_memory_.memory()) 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) memcpy(encoded_shared_memory_.memory(), data, data_size); 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create a pipe for reading/writing the decoded PCM data 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int pipefd[2]; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pipe(pipefd)) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) read_fd_ = pipefd[0]; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) write_fd_ = pipefd[1]; 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AudioDecoderIO::~AudioDecoderIO() { 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Close the read end of the pipe. The write end should have been 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // closed by MediaCodec. 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (read_fd_ >= 0 && close(read_fd_)) { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "Cannot close read fd " << read_fd_ 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << ": " << strerror(errno); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool AudioDecoderIO::IsValid() const { 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return read_fd_ >= 0 && write_fd_ >= 0 && 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) encoded_shared_memory_.memory(); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool AudioDecoderIO::ShareEncodedToProcess(base::SharedMemoryHandle* handle) { 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return encoded_shared_memory_.ShareToProcess( 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Process::Current().handle(), 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) handle); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static float ConvertSampleToFloat(int16_t sample) { 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const float kMaxScale = 1.0f / std::numeric_limits<int16_t>::max(); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const float kMinScale = -1.0f / std::numeric_limits<int16_t>::min(); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return sample * (sample < 0 ? kMinScale : kMaxScale); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// A basic WAVE file decoder. See 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ for a 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// basic guide to the WAVE file format. 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class WAVEDecoder { 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) WAVEDecoder(const uint8* data, size_t data_size); 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ~WAVEDecoder(); 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Try to decode the data as a WAVE file. If the data is a supported 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // WAVE file, |destination_bus| is filled with the decoded data and 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // DecodeWAVEFile returns true. Otherwise, DecodeWAVEFile returns 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // false. 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool DecodeWAVEFile(blink::WebAudioBus* destination_bus); 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Minimum number of bytes in a WAVE file to hold all of the data we 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // need to interpret it as a WAVE file. 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const unsigned kMinimumWAVLength = 44; 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Number of bytes in the chunk ID field. 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const unsigned kChunkIDLength = 4; 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Number of bytes in the chunk size field. 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const unsigned kChunkSizeLength = 4; 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Number of bytes in the format field of the "RIFF" chunk. 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const unsigned kFormatFieldLength = 4; 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Number of bytes in a valid "fmt" chunk. 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const unsigned kFMTChunkLength = 16; 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Supported audio format in a WAVE file. 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(rtoy): Consider supporting other formats here, if necessary. 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const int16_t kAudioFormatPCM = 1; 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Maximum number (inclusive) of bytes per sample supported by this 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // decoder. 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const unsigned kMaximumBytesPerSample = 3; 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Read an unsigned integer of |length| bytes from |buffer|. The 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // integer is interpreted as being in little-endian order. 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uint32_t ReadUnsignedInteger(const uint8_t* buffer, size_t length); 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Read a PCM sample from the WAVE data at |pcm_data|. 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int16_t ReadPCMSample(const uint8_t* pcm_data); 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Read a WAVE chunk header including the chunk ID and chunk size. 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Returns false if the header could not be read. 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool ReadChunkHeader(); 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Read and parse the "fmt" chunk. Returns false if the fmt chunk 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // could not be read or contained unsupported formats. 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool ReadFMTChunk(); 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Read data chunk and save it to |destination_bus|. Returns false 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // if the data chunk could not be read correctly. 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool CopyDataChunkToBus(blink::WebAudioBus* destination_bus); 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The WAVE chunk ID that identifies the chunk. 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uint8_t chunk_id_[kChunkIDLength]; 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The number of bytes in the data portion of the chunk. 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t chunk_size_; 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The total number of bytes in the encoded data. 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t data_size_; 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The current position within the WAVE file. 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const uint8_t* buffer_; 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Points one byte past the end of the in-memory WAVE file. Used for 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // detecting if we've reached the end of the file. 1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const uint8_t* buffer_end_; 1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t bytes_per_sample_; 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uint16_t number_of_channels_; 1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Sample rate of the WAVE data, in Hz. 1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uint32_t sample_rate_; 1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WAVEDecoder); 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)WAVEDecoder::WAVEDecoder(const uint8_t* encoded_data, size_t data_size) 189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : data_size_(data_size), 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) buffer_(encoded_data), 1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer_end_(encoded_data + 1), 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bytes_per_sample_(0), 1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) number_of_channels_(0), 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sample_rate_(0) { 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (buffer_ + data_size > buffer_) 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer_end_ = buffer_ + data_size; 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)WAVEDecoder::~WAVEDecoder() {} 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)uint32_t WAVEDecoder::ReadUnsignedInteger(const uint8_t* buffer, 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t length) { 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) unsigned value = 0; 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (length == 0 || length > sizeof(value)) { 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(false) << "ReadUnsignedInteger: Invalid length: " << length; 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // All integer fields in a WAVE file are little-endian. 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t k = length; k > 0; --k) 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) value = (value << 8) + buffer[k - 1]; 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return value; 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int16_t WAVEDecoder::ReadPCMSample(const uint8_t* pcm_data) { 2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uint32_t unsigned_sample = ReadUnsignedInteger(pcm_data, bytes_per_sample_); 2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int16_t sample; 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Convert the unsigned data into a 16-bit PCM sample. 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (bytes_per_sample_) { 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case 1: 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sample = (unsigned_sample - 128) << 8; 2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case 2: 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sample = static_cast<int16_t>(unsigned_sample); 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case 3: 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Android currently converts 24-bit WAVE data into 16-bit 2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // samples by taking the high-order 16 bits without rounding. 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // We do the same here for consistency. 2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sample = static_cast<int16_t>(unsigned_sample >> 8); 2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sample = 0; 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return sample; 2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool WAVEDecoder::ReadChunkHeader() { 2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (buffer_ + kChunkIDLength + kChunkSizeLength >= buffer_end_) 2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) memcpy(chunk_id_, buffer_, kChunkIDLength); 2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) chunk_size_ = ReadUnsignedInteger(buffer_ + kChunkIDLength, kChunkSizeLength); 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Adjust for padding 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (chunk_size_ % 2) 2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++chunk_size_; 2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Check for completely bogus chunk size. 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (chunk_size_ > data_size_) 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool WAVEDecoder::ReadFMTChunk() { 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The fmt chunk has basic info about the format of the audio 2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // data. Only a basic PCM format is supported. 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (chunk_size_ < kFMTChunkLength) { 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "FMT chunk too short: " << chunk_size_; 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return 0; 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) uint16_t audio_format = ReadUnsignedInteger(buffer_, 2); 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (audio_format != kAudioFormatPCM) { 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "Audio format not supported: " << audio_format; 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) number_of_channels_ = ReadUnsignedInteger(buffer_ + 2, 2); 2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sample_rate_ = ReadUnsignedInteger(buffer_ + 4, 4); 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) unsigned bits_per_sample = ReadUnsignedInteger(buffer_ + 14, 2); 2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Sanity checks. 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!number_of_channels_ || 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) number_of_channels_ > media::limits::kMaxChannels) { 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "Unsupported number of channels: " << number_of_channels_; 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (sample_rate_ < media::limits::kMinSampleRate || 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sample_rate_ > media::limits::kMaxSampleRate) { 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "Unsupported sample rate: " << sample_rate_; 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // We only support 8, 16, and 24 bits per sample. 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (bits_per_sample == 8 || bits_per_sample == 16 || bits_per_sample == 24) { 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bytes_per_sample_ = bits_per_sample / 8; 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "Unsupported bits per sample: " << bits_per_sample; 3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool WAVEDecoder::CopyDataChunkToBus(blink::WebAudioBus* destination_bus) { 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The data chunk contains the audio data itself. 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!bytes_per_sample_ || bytes_per_sample_ > kMaximumBytesPerSample) { 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "WARNING: data chunk without preceeding fmt chunk," 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " or invalid bytes per sample."; 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) VLOG(0) << "Decoding WAVE file: " << number_of_channels_ << " channels, " 3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << sample_rate_ << " kHz, " 3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << chunk_size_ / bytes_per_sample_ / number_of_channels_ 3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " frames, " << 8 * bytes_per_sample_ << " bits/sample"; 3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Create the destination bus of the appropriate size and then decode 3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the data into the bus. 3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t number_of_frames = 3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) chunk_size_ / bytes_per_sample_ / number_of_channels_; 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) destination_bus->initialize( 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) number_of_channels_, number_of_frames, sample_rate_); 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t m = 0; m < number_of_frames; ++m) { 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (uint16_t k = 0; k < number_of_channels_; ++k) { 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int16_t sample = ReadPCMSample(buffer_); 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer_ += bytes_per_sample_; 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) destination_bus->channelData(k)[m] = ConvertSampleToFloat(sample); 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool WAVEDecoder::DecodeWAVEFile(blink::WebAudioBus* destination_bus) { 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Parse and decode WAVE file. If we can't parse it, return false. 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (buffer_ + kMinimumWAVLength > buffer_end_) { 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "Buffer too small to contain full WAVE header: "; 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Do we have a RIFF file? 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ReadChunkHeader(); 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (memcmp(chunk_id_, "RIFF", kChunkIDLength) != 0) { 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "RIFF missing"; 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer_ += kChunkIDLength + kChunkSizeLength; 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Check the format field of the RIFF chunk 3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) memcpy(chunk_id_, buffer_, kFormatFieldLength); 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (memcmp(chunk_id_, "WAVE", kFormatFieldLength) != 0) { 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "Invalid WAVE file: missing WAVE header"; 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Advance past the format field 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer_ += kFormatFieldLength; 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // We have a WAVE file. Start parsing the chunks. 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) while (buffer_ < buffer_end_) { 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ReadChunkHeader()) { 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "Couldn't read chunk header"; 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Consume the chunk ID and chunk size 3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer_ += kChunkIDLength + kChunkSizeLength; 3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Make sure we can read all chunk_size bytes. 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (buffer_ + chunk_size_ > buffer_end_) { 3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DVLOG(1) << "Insufficient bytes to read chunk of size " << chunk_size_; 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (memcmp(chunk_id_, "fmt ", kChunkIDLength) == 0) { 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ReadFMTChunk()) 3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (memcmp(chunk_id_, "data", kChunkIDLength) == 0) { 3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Return after reading the data chunk, whether we succeeded or 3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // not. 3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return CopyDataChunkToBus(destination_bus); 3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Ignore these chunks that we don't know about. 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(0) << "Ignoring WAVE chunk `" << chunk_id_ << "' size " 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << chunk_size_; 3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Advance to next chunk. 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffer_ += chunk_size_; 3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If we get here, that means we didn't find a data chunk, so we 3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // couldn't handle this WAVE file. 3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The number of frames is known so preallocate the destination 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// bus and copy the pcm data to the destination bus as it's being 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// received. 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void CopyPcmDataToBus(int input_fd, 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebAudioBus* destination_bus, 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t number_of_frames, 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned number_of_channels, 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) double file_sample_rate) { 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) destination_bus->initialize(number_of_channels, 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) number_of_frames, 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_sample_rate); 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int16_t pipe_data[PIPE_BUF / sizeof(int16_t)]; 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t decoded_frames = 0; 416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t current_sample_in_frame = 0; 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssize_t nread; 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while ((nread = HANDLE_EINTR(read(input_fd, pipe_data, sizeof(pipe_data)))) > 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0) { 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t samples_in_pipe = nread / sizeof(int16_t); 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The pipe may not contain a whole number of frames. This is 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // especially true if the number of channels is greater than 425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 2. Thus, keep track of which sample in a frame is being 426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // processed, so we handle the boundary at the end of the pipe 427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // correctly. 428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t m = 0; m < samples_in_pipe; ++m) { 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (decoded_frames >= number_of_frames) 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) destination_bus->channelData(current_sample_in_frame)[decoded_frames] = 433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ConvertSampleToFloat(pipe_data[m]); 434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++current_sample_in_frame; 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (current_sample_in_frame >= number_of_channels) { 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) current_sample_in_frame = 0; 438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++decoded_frames; 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // number_of_frames is only an estimate. Resize the buffer with the 444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // actual number of received frames. 445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (decoded_frames < number_of_frames) 446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) destination_bus->resizeSmaller(decoded_frames); 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The number of frames is unknown, so keep reading and buffering 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// until there's no more data and then copy the data to the 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// destination bus. 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void BufferAndCopyPcmDataToBus(int input_fd, 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebAudioBus* destination_bus, 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned number_of_channels, 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) double file_sample_rate) { 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int16_t pipe_data[PIPE_BUF / sizeof(int16_t)]; 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<int16_t> decoded_samples; 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssize_t nread; 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while ((nread = HANDLE_EINTR(read(input_fd, pipe_data, sizeof(pipe_data)))) > 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0) { 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t samples_in_pipe = nread / sizeof(int16_t); 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (decoded_samples.size() + samples_in_pipe > decoded_samples.capacity()) { 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) decoded_samples.reserve(std::max(samples_in_pipe, 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2 * decoded_samples.capacity())); 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::copy(pipe_data, 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pipe_data + samples_in_pipe, 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) back_inserter(decoded_samples)); 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "Total samples read = " << decoded_samples.size(); 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Convert the samples and save them in the audio bus. 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t number_of_samples = decoded_samples.size(); 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t number_of_frames = decoded_samples.size() / number_of_channels; 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t decoded_frames = 0; 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) destination_bus->initialize(number_of_channels, 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) number_of_frames, 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_sample_rate); 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t m = 0; m < number_of_samples; m += number_of_channels) { 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t k = 0; k < number_of_channels; ++k) { 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int16_t sample = decoded_samples[m + k]; 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) destination_bus->channelData(k)[decoded_frames] = 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConvertSampleToFloat(sample); 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++decoded_frames; 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 492424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // number_of_frames is only an estimate. Resize the buffer with the 493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // actual number of received frames. 494424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (decoded_frames < number_of_frames) 495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) destination_bus->resizeSmaller(decoded_frames); 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static bool TryWAVEFileDecoder(blink::WebAudioBus* destination_bus, 4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const uint8_t* encoded_data, 5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t data_size) { 5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) WAVEDecoder decoder(encoded_data, data_size); 5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return decoder.DecodeWAVEFile(destination_bus); 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// To decode audio data, we want to use the Android MediaCodec class. 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// But this can't run in a sandboxed process so we need initiate the 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// request to MediaCodec in the browser. To do this, we create a 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// shared memory buffer that holds the audio data. We send a message 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// to the browser to start the decoder using this buffer and one end 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// of a pipe. The MediaCodec class will decode the data from the 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// shared memory and write the PCM samples back to us over a pipe. 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DecodeAudioFileData(blink::WebAudioBus* destination_bus, const char* data, 514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t data_size, 515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<ThreadSafeSender> sender) { 5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Try to decode the data as a WAVE file first. If it can't be 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // decoded, use MediaCodec. See crbug.com/259048. 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (TryWAVEFileDecoder( 5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) destination_bus, reinterpret_cast<const uint8_t*>(data), data_size)) { 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AudioDecoderIO audio_decoder(data, data_size); 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!audio_decoder.IsValid()) 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SharedMemoryHandle encoded_data_handle; 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) audio_decoder.ShareEncodedToProcess(&encoded_data_handle); 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FileDescriptor fd(audio_decoder.write_fd(), true); 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "DecodeAudioFileData: Starting MediaCodec"; 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Start MediaCodec processing in the browser which will read from 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // encoded_data_handle for our shared memory and write the decoded 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // PCM samples (16-bit integer) to our pipe. 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sender->Send(new ViewHostMsg_RunWebAudioMediaCodec( 539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch encoded_data_handle, fd, data_size)); 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // First, read the number of channels, the sample rate, and the 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // number of frames and a flag indicating if the file is an 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ogg/vorbis file. This must be coordinated with 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // WebAudioMediaCodecBridge! 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 546eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If we know the number of samples, we can create the destination 547eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // bus directly and do the conversion directly to the bus instead of 548eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // buffering up everything before saving the data to the bus. 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int input_fd = audio_decoder.read_fd(); 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct media::WebAudioMediaCodecInfo info; 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "Reading audio file info from fd " << input_fd; 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssize_t nread = HANDLE_EINTR(read(input_fd, &info, sizeof(info))); 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "read: " << nread << " bytes:\n" 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " 0: number of channels = " << info.channel_count << "\n" 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " 1: sample rate = " << info.sample_rate << "\n" 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << " 2: number of frames = " << info.number_of_frames << "\n"; 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (nread != sizeof(info)) 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned number_of_channels = info.channel_count; 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) double file_sample_rate = static_cast<double>(info.sample_rate); 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t number_of_frames = info.number_of_frames; 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Sanity checks 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!number_of_channels || 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) number_of_channels > media::limits::kMaxChannels || 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_sample_rate < media::limits::kMinSampleRate || 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_sample_rate > media::limits::kMaxSampleRate) { 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (number_of_frames > 0) { 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CopyPcmDataToBus(input_fd, 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) destination_bus, 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) number_of_frames, 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) number_of_channels, 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_sample_rate); 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BufferAndCopyPcmDataToBus(input_fd, 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) destination_bus, 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) number_of_channels, 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_sample_rate); 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace content 592