168513a70bcd92384395513322f1b801e7bf9c729Steve Block/* 268513a70bcd92384395513322f1b801e7bf9c729Steve Block * Copyright (C) 2010 Google Inc. All rights reserved. 368513a70bcd92384395513322f1b801e7bf9c729Steve Block * 468513a70bcd92384395513322f1b801e7bf9c729Steve Block * Redistribution and use in source and binary forms, with or without 568513a70bcd92384395513322f1b801e7bf9c729Steve Block * modification, are permitted provided that the following conditions 668513a70bcd92384395513322f1b801e7bf9c729Steve Block * are met: 768513a70bcd92384395513322f1b801e7bf9c729Steve Block * 868513a70bcd92384395513322f1b801e7bf9c729Steve Block * 1. Redistributions of source code must retain the above copyright 968513a70bcd92384395513322f1b801e7bf9c729Steve Block * notice, this list of conditions and the following disclaimer. 1068513a70bcd92384395513322f1b801e7bf9c729Steve Block * 2. Redistributions in binary form must reproduce the above copyright 1168513a70bcd92384395513322f1b801e7bf9c729Steve Block * notice, this list of conditions and the following disclaimer in the 1268513a70bcd92384395513322f1b801e7bf9c729Steve Block * documentation and/or other materials provided with the distribution. 1368513a70bcd92384395513322f1b801e7bf9c729Steve Block * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 1468513a70bcd92384395513322f1b801e7bf9c729Steve Block * its contributors may be used to endorse or promote products derived 1568513a70bcd92384395513322f1b801e7bf9c729Steve Block * from this software without specific prior written permission. 1668513a70bcd92384395513322f1b801e7bf9c729Steve Block * 1768513a70bcd92384395513322f1b801e7bf9c729Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 1868513a70bcd92384395513322f1b801e7bf9c729Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 1968513a70bcd92384395513322f1b801e7bf9c729Steve Block * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2068513a70bcd92384395513322f1b801e7bf9c729Steve Block * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 2168513a70bcd92384395513322f1b801e7bf9c729Steve Block * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2268513a70bcd92384395513322f1b801e7bf9c729Steve Block * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2368513a70bcd92384395513322f1b801e7bf9c729Steve Block * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 2468513a70bcd92384395513322f1b801e7bf9c729Steve Block * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2568513a70bcd92384395513322f1b801e7bf9c729Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2668513a70bcd92384395513322f1b801e7bf9c729Steve Block * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2768513a70bcd92384395513322f1b801e7bf9c729Steve Block */ 2868513a70bcd92384395513322f1b801e7bf9c729Steve Block 2968513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "config.h" 3068513a70bcd92384395513322f1b801e7bf9c729Steve Block 3168513a70bcd92384395513322f1b801e7bf9c729Steve Block#if ENABLE(WEB_AUDIO) 3268513a70bcd92384395513322f1b801e7bf9c729Steve Block 3368513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "AudioFileReaderMac.h" 3468513a70bcd92384395513322f1b801e7bf9c729Steve Block 3568513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "AudioBus.h" 3668513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "AudioFileReader.h" 3768513a70bcd92384395513322f1b801e7bf9c729Steve Block#include <CoreFoundation/CoreFoundation.h> 386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include <CoreServices/CoreServices.h> 3968513a70bcd92384395513322f1b801e7bf9c729Steve Block 4068513a70bcd92384395513322f1b801e7bf9c729Steve Blocknamespace WebCore { 4168513a70bcd92384395513322f1b801e7bf9c729Steve Block 4268513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic AudioBufferList* createAudioBufferList(size_t numberOfBuffers) 4368513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 4468513a70bcd92384395513322f1b801e7bf9c729Steve Block size_t bufferListSize = sizeof(AudioBufferList) - sizeof(AudioBuffer); 4568513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferListSize += numberOfBuffers * sizeof(AudioBuffer); 4668513a70bcd92384395513322f1b801e7bf9c729Steve Block 4768513a70bcd92384395513322f1b801e7bf9c729Steve Block AudioBufferList* bufferList = static_cast<AudioBufferList*>(calloc(1, bufferListSize)); 4868513a70bcd92384395513322f1b801e7bf9c729Steve Block if (bufferList) 4968513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mNumberBuffers = numberOfBuffers; 5068513a70bcd92384395513322f1b801e7bf9c729Steve Block 5168513a70bcd92384395513322f1b801e7bf9c729Steve Block return bufferList; 5268513a70bcd92384395513322f1b801e7bf9c729Steve Block} 5368513a70bcd92384395513322f1b801e7bf9c729Steve Block 5468513a70bcd92384395513322f1b801e7bf9c729Steve Blockstatic void destroyAudioBufferList(AudioBufferList* bufferList) 5568513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 5668513a70bcd92384395513322f1b801e7bf9c729Steve Block free(bufferList); 5768513a70bcd92384395513322f1b801e7bf9c729Steve Block} 5868513a70bcd92384395513322f1b801e7bf9c729Steve Block 5968513a70bcd92384395513322f1b801e7bf9c729Steve BlockAudioFileReader::AudioFileReader(const char* filePath) 6068513a70bcd92384395513322f1b801e7bf9c729Steve Block : m_data(0) 6168513a70bcd92384395513322f1b801e7bf9c729Steve Block , m_dataSize(0) 6268513a70bcd92384395513322f1b801e7bf9c729Steve Block , m_filePath(filePath) 6368513a70bcd92384395513322f1b801e7bf9c729Steve Block , m_audioFileID(0) 6468513a70bcd92384395513322f1b801e7bf9c729Steve Block , m_extAudioFileRef(0) 6568513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 6668513a70bcd92384395513322f1b801e7bf9c729Steve Block FSRef fsref; 6768513a70bcd92384395513322f1b801e7bf9c729Steve Block OSStatus result = FSPathMakeRef((UInt8*)filePath, &fsref, 0); 6868513a70bcd92384395513322f1b801e7bf9c729Steve Block if (result != noErr) 6968513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 7068513a70bcd92384395513322f1b801e7bf9c729Steve Block 7168513a70bcd92384395513322f1b801e7bf9c729Steve Block CFURLRef urlRef = CFURLCreateFromFSRef(0, &fsref); 7268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!urlRef) 7368513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 7468513a70bcd92384395513322f1b801e7bf9c729Steve Block 7568513a70bcd92384395513322f1b801e7bf9c729Steve Block ExtAudioFileOpenURL(urlRef, &m_extAudioFileRef); 7668513a70bcd92384395513322f1b801e7bf9c729Steve Block 7768513a70bcd92384395513322f1b801e7bf9c729Steve Block if (urlRef) 7868513a70bcd92384395513322f1b801e7bf9c729Steve Block CFRelease(urlRef); 7968513a70bcd92384395513322f1b801e7bf9c729Steve Block} 8068513a70bcd92384395513322f1b801e7bf9c729Steve Block 8168513a70bcd92384395513322f1b801e7bf9c729Steve BlockAudioFileReader::AudioFileReader(const void* data, size_t dataSize) 8268513a70bcd92384395513322f1b801e7bf9c729Steve Block : m_data(data) 8368513a70bcd92384395513322f1b801e7bf9c729Steve Block , m_dataSize(dataSize) 8468513a70bcd92384395513322f1b801e7bf9c729Steve Block , m_filePath(0) 8568513a70bcd92384395513322f1b801e7bf9c729Steve Block , m_audioFileID(0) 8668513a70bcd92384395513322f1b801e7bf9c729Steve Block , m_extAudioFileRef(0) 8768513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 8868513a70bcd92384395513322f1b801e7bf9c729Steve Block OSStatus result = AudioFileOpenWithCallbacks(this, readProc, 0, getSizeProc, 0, 0, &m_audioFileID); 8968513a70bcd92384395513322f1b801e7bf9c729Steve Block 9068513a70bcd92384395513322f1b801e7bf9c729Steve Block if (result != noErr) 9168513a70bcd92384395513322f1b801e7bf9c729Steve Block return; 9268513a70bcd92384395513322f1b801e7bf9c729Steve Block 9368513a70bcd92384395513322f1b801e7bf9c729Steve Block result = ExtAudioFileWrapAudioFileID(m_audioFileID, false, &m_extAudioFileRef); 9468513a70bcd92384395513322f1b801e7bf9c729Steve Block if (result != noErr) 9568513a70bcd92384395513322f1b801e7bf9c729Steve Block m_extAudioFileRef = 0; 9668513a70bcd92384395513322f1b801e7bf9c729Steve Block} 9768513a70bcd92384395513322f1b801e7bf9c729Steve Block 9868513a70bcd92384395513322f1b801e7bf9c729Steve BlockAudioFileReader::~AudioFileReader() 9968513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 10068513a70bcd92384395513322f1b801e7bf9c729Steve Block if (m_extAudioFileRef) 10168513a70bcd92384395513322f1b801e7bf9c729Steve Block ExtAudioFileDispose(m_extAudioFileRef); 10268513a70bcd92384395513322f1b801e7bf9c729Steve Block 10368513a70bcd92384395513322f1b801e7bf9c729Steve Block m_extAudioFileRef = 0; 10468513a70bcd92384395513322f1b801e7bf9c729Steve Block 10568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (m_audioFileID) 10668513a70bcd92384395513322f1b801e7bf9c729Steve Block AudioFileClose(m_audioFileID); 10768513a70bcd92384395513322f1b801e7bf9c729Steve Block 10868513a70bcd92384395513322f1b801e7bf9c729Steve Block m_audioFileID = 0; 10968513a70bcd92384395513322f1b801e7bf9c729Steve Block} 11068513a70bcd92384395513322f1b801e7bf9c729Steve Block 11168513a70bcd92384395513322f1b801e7bf9c729Steve BlockOSStatus AudioFileReader::readProc(void* clientData, SInt64 position, UInt32 requestCount, void* buffer, UInt32* actualCount) 11268513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 11368513a70bcd92384395513322f1b801e7bf9c729Steve Block AudioFileReader* audioFileReader = static_cast<AudioFileReader*>(clientData); 11468513a70bcd92384395513322f1b801e7bf9c729Steve Block 11568513a70bcd92384395513322f1b801e7bf9c729Steve Block size_t dataSize = audioFileReader->dataSize(); 11668513a70bcd92384395513322f1b801e7bf9c729Steve Block const void* data = audioFileReader->data(); 11768513a70bcd92384395513322f1b801e7bf9c729Steve Block size_t bytesToRead = 0; 11868513a70bcd92384395513322f1b801e7bf9c729Steve Block 11968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (static_cast<UInt64>(position) < dataSize) { 12068513a70bcd92384395513322f1b801e7bf9c729Steve Block size_t bytesAvailable = dataSize - static_cast<size_t>(position); 12168513a70bcd92384395513322f1b801e7bf9c729Steve Block bytesToRead = requestCount <= bytesAvailable ? requestCount : bytesAvailable; 12268513a70bcd92384395513322f1b801e7bf9c729Steve Block memcpy(buffer, static_cast<const char*>(data) + position, bytesToRead); 12368513a70bcd92384395513322f1b801e7bf9c729Steve Block } else 12468513a70bcd92384395513322f1b801e7bf9c729Steve Block bytesToRead = 0; 12568513a70bcd92384395513322f1b801e7bf9c729Steve Block 12668513a70bcd92384395513322f1b801e7bf9c729Steve Block if (actualCount) 12768513a70bcd92384395513322f1b801e7bf9c729Steve Block *actualCount = bytesToRead; 12868513a70bcd92384395513322f1b801e7bf9c729Steve Block 12968513a70bcd92384395513322f1b801e7bf9c729Steve Block return noErr; 13068513a70bcd92384395513322f1b801e7bf9c729Steve Block} 13168513a70bcd92384395513322f1b801e7bf9c729Steve Block 13268513a70bcd92384395513322f1b801e7bf9c729Steve BlockSInt64 AudioFileReader::getSizeProc(void* clientData) 13368513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 13468513a70bcd92384395513322f1b801e7bf9c729Steve Block AudioFileReader* audioFileReader = static_cast<AudioFileReader*>(clientData); 13568513a70bcd92384395513322f1b801e7bf9c729Steve Block return audioFileReader->dataSize(); 13668513a70bcd92384395513322f1b801e7bf9c729Steve Block} 13768513a70bcd92384395513322f1b801e7bf9c729Steve Block 13868513a70bcd92384395513322f1b801e7bf9c729Steve BlockPassOwnPtr<AudioBus> AudioFileReader::createBus(double sampleRate, bool mixToMono) 13968513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 14068513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!m_extAudioFileRef) 14168513a70bcd92384395513322f1b801e7bf9c729Steve Block return 0; 14268513a70bcd92384395513322f1b801e7bf9c729Steve Block 14368513a70bcd92384395513322f1b801e7bf9c729Steve Block // Get file's data format 14468513a70bcd92384395513322f1b801e7bf9c729Steve Block UInt32 size = sizeof(m_fileDataFormat); 14568513a70bcd92384395513322f1b801e7bf9c729Steve Block OSStatus result = ExtAudioFileGetProperty(m_extAudioFileRef, kExtAudioFileProperty_FileDataFormat, &size, &m_fileDataFormat); 14668513a70bcd92384395513322f1b801e7bf9c729Steve Block if (result != noErr) 14768513a70bcd92384395513322f1b801e7bf9c729Steve Block return 0; 14868513a70bcd92384395513322f1b801e7bf9c729Steve Block 14968513a70bcd92384395513322f1b801e7bf9c729Steve Block // Number of channels 15068513a70bcd92384395513322f1b801e7bf9c729Steve Block size_t numberOfChannels = m_fileDataFormat.mChannelsPerFrame; 15168513a70bcd92384395513322f1b801e7bf9c729Steve Block 15268513a70bcd92384395513322f1b801e7bf9c729Steve Block // Number of frames 15368513a70bcd92384395513322f1b801e7bf9c729Steve Block SInt64 numberOfFrames64 = 0; 15468513a70bcd92384395513322f1b801e7bf9c729Steve Block size = sizeof(numberOfFrames64); 15568513a70bcd92384395513322f1b801e7bf9c729Steve Block result = ExtAudioFileGetProperty(m_extAudioFileRef, kExtAudioFileProperty_FileLengthFrames, &size, &numberOfFrames64); 15668513a70bcd92384395513322f1b801e7bf9c729Steve Block if (result != noErr) 15768513a70bcd92384395513322f1b801e7bf9c729Steve Block return 0; 15868513a70bcd92384395513322f1b801e7bf9c729Steve Block 15968513a70bcd92384395513322f1b801e7bf9c729Steve Block // Sample-rate 16068513a70bcd92384395513322f1b801e7bf9c729Steve Block double fileSampleRate = m_fileDataFormat.mSampleRate; 16168513a70bcd92384395513322f1b801e7bf9c729Steve Block 16268513a70bcd92384395513322f1b801e7bf9c729Steve Block // Make client format same number of channels as file format, but tweak a few things. 16368513a70bcd92384395513322f1b801e7bf9c729Steve Block // Client format will be linear PCM (canonical), and potentially change sample-rate. 16468513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat = m_fileDataFormat; 16568513a70bcd92384395513322f1b801e7bf9c729Steve Block 16668513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat.mFormatID = kAudioFormatLinearPCM; 16768513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat.mFormatFlags = kAudioFormatFlagsCanonical; 16868513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat.mBitsPerChannel = 8 * sizeof(AudioSampleType); 16968513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat.mChannelsPerFrame = numberOfChannels; 17068513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat.mFramesPerPacket = 1; 17168513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat.mBytesPerPacket = sizeof(AudioSampleType); 17268513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat.mBytesPerFrame = sizeof(AudioSampleType); 17368513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat.mFormatFlags |= kAudioFormatFlagIsNonInterleaved; 17468513a70bcd92384395513322f1b801e7bf9c729Steve Block 17568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (sampleRate) 17668513a70bcd92384395513322f1b801e7bf9c729Steve Block m_clientDataFormat.mSampleRate = sampleRate; 17768513a70bcd92384395513322f1b801e7bf9c729Steve Block 17868513a70bcd92384395513322f1b801e7bf9c729Steve Block result = ExtAudioFileSetProperty(m_extAudioFileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &m_clientDataFormat); 17968513a70bcd92384395513322f1b801e7bf9c729Steve Block if (result != noErr) 18068513a70bcd92384395513322f1b801e7bf9c729Steve Block return 0; 18168513a70bcd92384395513322f1b801e7bf9c729Steve Block 18268513a70bcd92384395513322f1b801e7bf9c729Steve Block // Change numberOfFrames64 to destination sample-rate 18368513a70bcd92384395513322f1b801e7bf9c729Steve Block numberOfFrames64 = numberOfFrames64 * (m_clientDataFormat.mSampleRate / fileSampleRate); 18468513a70bcd92384395513322f1b801e7bf9c729Steve Block size_t numberOfFrames = static_cast<size_t>(numberOfFrames64); 18568513a70bcd92384395513322f1b801e7bf9c729Steve Block 18668513a70bcd92384395513322f1b801e7bf9c729Steve Block size_t busChannelCount = mixToMono ? 1 : numberOfChannels; 18768513a70bcd92384395513322f1b801e7bf9c729Steve Block 18868513a70bcd92384395513322f1b801e7bf9c729Steve Block // Create AudioBus where we'll put the PCM audio data 18968513a70bcd92384395513322f1b801e7bf9c729Steve Block OwnPtr<AudioBus> audioBus = adoptPtr(new AudioBus(busChannelCount, numberOfFrames)); 19068513a70bcd92384395513322f1b801e7bf9c729Steve Block audioBus->setSampleRate(m_clientDataFormat.mSampleRate); // save for later 19168513a70bcd92384395513322f1b801e7bf9c729Steve Block 19268513a70bcd92384395513322f1b801e7bf9c729Steve Block // Only allocated in the mixToMono case 19368513a70bcd92384395513322f1b801e7bf9c729Steve Block AudioFloatArray bufL; 19468513a70bcd92384395513322f1b801e7bf9c729Steve Block AudioFloatArray bufR; 19568513a70bcd92384395513322f1b801e7bf9c729Steve Block float* bufferL = 0; 19668513a70bcd92384395513322f1b801e7bf9c729Steve Block float* bufferR = 0; 19768513a70bcd92384395513322f1b801e7bf9c729Steve Block 19868513a70bcd92384395513322f1b801e7bf9c729Steve Block // Setup AudioBufferList in preparation for reading 19968513a70bcd92384395513322f1b801e7bf9c729Steve Block AudioBufferList* bufferList = createAudioBufferList(numberOfChannels); 20068513a70bcd92384395513322f1b801e7bf9c729Steve Block 20168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (mixToMono && numberOfChannels == 2) { 20268513a70bcd92384395513322f1b801e7bf9c729Steve Block bufL.resize(numberOfFrames); 20368513a70bcd92384395513322f1b801e7bf9c729Steve Block bufR.resize(numberOfFrames); 20468513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferL = bufL.data(); 20568513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferR = bufR.data(); 20668513a70bcd92384395513322f1b801e7bf9c729Steve Block 20768513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mBuffers[0].mNumberChannels = 1; 20868513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mBuffers[0].mDataByteSize = numberOfFrames * sizeof(float); 20968513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mBuffers[0].mData = bufferL; 21068513a70bcd92384395513322f1b801e7bf9c729Steve Block 21168513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mBuffers[1].mNumberChannels = 1; 21268513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mBuffers[1].mDataByteSize = numberOfFrames * sizeof(float); 21368513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mBuffers[1].mData = bufferR; 21468513a70bcd92384395513322f1b801e7bf9c729Steve Block } else { 21568513a70bcd92384395513322f1b801e7bf9c729Steve Block ASSERT(!mixToMono || numberOfChannels == 1); 21668513a70bcd92384395513322f1b801e7bf9c729Steve Block 21768513a70bcd92384395513322f1b801e7bf9c729Steve Block // for True-stereo (numberOfChannels == 4) 21868513a70bcd92384395513322f1b801e7bf9c729Steve Block for (size_t i = 0; i < numberOfChannels; ++i) { 21968513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mBuffers[i].mNumberChannels = 1; 22068513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mBuffers[i].mDataByteSize = numberOfFrames * sizeof(float); 22168513a70bcd92384395513322f1b801e7bf9c729Steve Block bufferList->mBuffers[i].mData = audioBus->channel(i)->data(); 22268513a70bcd92384395513322f1b801e7bf9c729Steve Block } 22368513a70bcd92384395513322f1b801e7bf9c729Steve Block } 22468513a70bcd92384395513322f1b801e7bf9c729Steve Block 22568513a70bcd92384395513322f1b801e7bf9c729Steve Block // Read from the file (or in-memory version) 22668513a70bcd92384395513322f1b801e7bf9c729Steve Block UInt32 framesToRead = numberOfFrames; 22768513a70bcd92384395513322f1b801e7bf9c729Steve Block result = ExtAudioFileRead(m_extAudioFileRef, &framesToRead, bufferList); 22868513a70bcd92384395513322f1b801e7bf9c729Steve Block if (result != noErr) 22968513a70bcd92384395513322f1b801e7bf9c729Steve Block return 0; 23068513a70bcd92384395513322f1b801e7bf9c729Steve Block 23168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (mixToMono && numberOfChannels == 2) { 23268513a70bcd92384395513322f1b801e7bf9c729Steve Block // Mix stereo down to mono 23368513a70bcd92384395513322f1b801e7bf9c729Steve Block float* destL = audioBus->channel(0)->data(); 23468513a70bcd92384395513322f1b801e7bf9c729Steve Block for (size_t i = 0; i < numberOfFrames; i++) 23568513a70bcd92384395513322f1b801e7bf9c729Steve Block destL[i] = 0.5f * (bufferL[i] + bufferR[i]); 23668513a70bcd92384395513322f1b801e7bf9c729Steve Block } 23768513a70bcd92384395513322f1b801e7bf9c729Steve Block 23868513a70bcd92384395513322f1b801e7bf9c729Steve Block // Cleanup 23968513a70bcd92384395513322f1b801e7bf9c729Steve Block destroyAudioBufferList(bufferList); 24068513a70bcd92384395513322f1b801e7bf9c729Steve Block 24168513a70bcd92384395513322f1b801e7bf9c729Steve Block return audioBus.release(); 24268513a70bcd92384395513322f1b801e7bf9c729Steve Block} 24368513a70bcd92384395513322f1b801e7bf9c729Steve Block 24468513a70bcd92384395513322f1b801e7bf9c729Steve BlockPassOwnPtr<AudioBus> createBusFromAudioFile(const char* filePath, bool mixToMono, double sampleRate) 24568513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 24668513a70bcd92384395513322f1b801e7bf9c729Steve Block AudioFileReader reader(filePath); 24768513a70bcd92384395513322f1b801e7bf9c729Steve Block return reader.createBus(sampleRate, mixToMono); 24868513a70bcd92384395513322f1b801e7bf9c729Steve Block} 24968513a70bcd92384395513322f1b801e7bf9c729Steve Block 25068513a70bcd92384395513322f1b801e7bf9c729Steve BlockPassOwnPtr<AudioBus> createBusFromInMemoryAudioFile(const void* data, size_t dataSize, bool mixToMono, double sampleRate) 25168513a70bcd92384395513322f1b801e7bf9c729Steve Block{ 25268513a70bcd92384395513322f1b801e7bf9c729Steve Block AudioFileReader reader(data, dataSize); 25368513a70bcd92384395513322f1b801e7bf9c729Steve Block return reader.createBus(sampleRate, mixToMono); 25468513a70bcd92384395513322f1b801e7bf9c729Steve Block} 25568513a70bcd92384395513322f1b801e7bf9c729Steve Block 25668513a70bcd92384395513322f1b801e7bf9c729Steve Block} // WebCore 25768513a70bcd92384395513322f1b801e7bf9c729Steve Block 25868513a70bcd92384395513322f1b801e7bf9c729Steve Block#endif // ENABLE(WEB_AUDIO) 259