This source file includes following definitions.
- create
- m_isPlaying
- start
- stop
- hardwareSampleRate
- maxChannelCount
- render
- provideInput
#include "config.h"
#if ENABLE(WEB_AUDIO)
#include "platform/audio/AudioDestination.h"
#include "platform/audio/AudioFIFO.h"
#include "platform/audio/AudioPullFIFO.h"
#include "public/platform/Platform.h"
namespace WebCore {
const unsigned renderBufferSize = 128;
const size_t fifoSize = 8192;
PassOwnPtr<AudioDestination> AudioDestination::create(AudioIOCallback& callback, const String& inputDeviceId, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate)
{
return adoptPtr(new AudioDestination(callback, inputDeviceId, numberOfInputChannels, numberOfOutputChannels, sampleRate));
}
AudioDestination::AudioDestination(AudioIOCallback& callback, const String& inputDeviceId, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate)
: m_callback(callback)
, m_numberOfOutputChannels(numberOfOutputChannels)
, m_inputBus(AudioBus::create(numberOfInputChannels, renderBufferSize))
, m_renderBus(AudioBus::create(numberOfOutputChannels, renderBufferSize, false))
, m_sampleRate(sampleRate)
, m_isPlaying(false)
{
m_callbackBufferSize = blink::Platform::current()->audioHardwareBufferSize();
#if OS(ANDROID)
const size_t kSmallBufferSize = 1024;
const size_t kDefaultCallbackBufferSize = 2048;
if (m_callbackBufferSize <= kSmallBufferSize)
m_callbackBufferSize = kDefaultCallbackBufferSize;
#endif
ASSERT(m_callbackBufferSize + renderBufferSize <= fifoSize);
if (m_callbackBufferSize + renderBufferSize > fifoSize)
return;
m_audioDevice = adoptPtr(blink::Platform::current()->createAudioDevice(m_callbackBufferSize, numberOfInputChannels, numberOfOutputChannels, sampleRate, this, inputDeviceId));
ASSERT(m_audioDevice);
m_fifo = adoptPtr(new AudioPullFIFO(*this, numberOfOutputChannels, fifoSize, renderBufferSize));
m_inputFifo = adoptPtr(new AudioFIFO(numberOfInputChannels, fifoSize));
if (m_callbackBufferSize != renderBufferSize) {
RefPtr<AudioBus> silence = AudioBus::create(2, renderBufferSize);
m_inputFifo->push(silence.get());
}
}
AudioDestination::~AudioDestination()
{
stop();
}
void AudioDestination::start()
{
if (!m_isPlaying && m_audioDevice) {
m_audioDevice->start();
m_isPlaying = true;
}
}
void AudioDestination::stop()
{
if (m_isPlaying && m_audioDevice) {
m_audioDevice->stop();
m_isPlaying = false;
}
}
float AudioDestination::hardwareSampleRate()
{
return static_cast<float>(blink::Platform::current()->audioHardwareSampleRate());
}
unsigned long AudioDestination::maxChannelCount()
{
return static_cast<float>(blink::Platform::current()->audioHardwareOutputChannels());
}
void AudioDestination::render(const blink::WebVector<float*>& sourceData, const blink::WebVector<float*>& audioData, size_t numberOfFrames)
{
bool isNumberOfChannelsGood = audioData.size() == m_numberOfOutputChannels;
if (!isNumberOfChannelsGood) {
ASSERT_NOT_REACHED();
return;
}
bool isBufferSizeGood = numberOfFrames == m_callbackBufferSize;
if (!isBufferSizeGood) {
ASSERT_NOT_REACHED();
return;
}
if (sourceData.size() >= 2) {
RefPtr<AudioBus> wrapperBus = AudioBus::create(2, numberOfFrames, false);
wrapperBus->setChannelMemory(0, sourceData[0], numberOfFrames);
wrapperBus->setChannelMemory(1, sourceData[1], numberOfFrames);
m_inputFifo->push(wrapperBus.get());
}
for (unsigned i = 0; i < m_numberOfOutputChannels; ++i)
m_renderBus->setChannelMemory(i, audioData[i], numberOfFrames);
m_fifo->consume(m_renderBus.get(), numberOfFrames);
}
void AudioDestination::provideInput(AudioBus* bus, size_t framesToProcess)
{
AudioBus* sourceBus = 0;
if (m_inputFifo->framesInFifo() >= framesToProcess) {
m_inputFifo->consume(m_inputBus.get(), framesToProcess);
sourceBus = m_inputBus.get();
}
m_callback.render(sourceBus, bus, framesToProcess);
}
}
#endif