Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "platform/audio/AudioRenderSink.h" | |
| 6 | |
| 7 #include "platform/audio/AudioPullFIFO.h" | |
| 8 #include "public/platform/Platform.h" | |
| 9 #include "public/platform/WebSecurityOrigin.h" | |
| 10 | |
| 11 namespace blink { | |
| 12 | |
| 13 // WebAudio engine's render quantum size. | |
| 14 const unsigned kRenderQuantumSize = 128; | |
| 15 | |
| 16 // Default pulling FIFO size. | |
| 17 const size_t kPullFifoSize = 8192; | |
| 18 | |
| 19 AudioRenderSink::AudioRenderSink(AudioIOCallback& callback, const String& inputD eviceId, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate, const PassRefPtr<SecurityOrigin>& securityOrigin) | |
| 20 : m_isRunning(false) | |
| 21 , m_sampleRate(sampleRate) | |
| 22 , m_numberOfOutputChannels(numberOfOutputChannels) | |
| 23 , m_callback(callback) | |
| 24 , m_inputBus(AudioBus::create(numberOfInputChannels, kRenderQuantumSize)) | |
| 25 , m_outputBus(AudioBus::create(numberOfOutputChannels, kRenderQuantumSize, f alse)) | |
| 26 { | |
| 27 // Use the optimal buffer size recommended by the audio stack. It differs | |
| 28 // from the render quantum size and it varies across the platform. | |
| 29 size_t recommendedBufferSize = Platform::current()->audioHardwareBufferSize( ); | |
| 30 m_callbackBufferSize = recommendedBufferSize; | |
| 31 | |
| 32 m_webAudioDevice = adoptPtr(Platform::current()->createAudioDevice(m_callbac kBufferSize, numberOfInputChannels, numberOfOutputChannels, sampleRate, this, in putDeviceId, securityOrigin)); | |
| 33 DCHECK(m_webAudioDevice); | |
| 34 | |
| 35 // TODO(hongchan): the ownership and the structure are weird. This | |
| 36 // AudioRenderSink is also AudioSourceProvider, this can provide input for | |
| 37 // its own FIFO. | |
| 38 m_pullFifo = adoptPtr(new AudioPullFIFO(numberOfOutputChannels, kPullFifoSiz e, *this, kRenderQuantumSize)); | |
| 39 | |
| 40 LOG(INFO) << "WEBAUDIO: hardware buffer size = " << recommendedBufferSize; | |
| 41 } | |
| 42 | |
| 43 AudioRenderSink::~AudioRenderSink() | |
| 44 { | |
| 45 stop(); | |
| 46 } | |
| 47 | |
| 48 PassOwnPtr<AudioRenderSink> AudioRenderSink::create(AudioIOCallback& callback, c onst String& inputDeviceId, unsigned numberOfInputChannels, unsigned numberOfOut putChannels, float sampleRate, const PassRefPtr<SecurityOrigin>& securityOrigin) | |
| 49 { | |
| 50 return adoptPtr(new AudioRenderSink(callback, inputDeviceId, numberOfInputCh annels, numberOfOutputChannels, sampleRate, securityOrigin)); | |
| 51 } | |
| 52 | |
| 53 size_t AudioRenderSink::renderQuantumSize() | |
| 54 { | |
| 55 return kRenderQuantumSize; | |
| 56 } | |
| 57 | |
| 58 unsigned AudioRenderSink::audioHardwareBufferSize() | |
| 59 { | |
| 60 return static_cast<unsigned>(Platform::current()->audioHardwareBufferSize()) ; | |
| 61 } | |
| 62 | |
| 63 float AudioRenderSink::audioHardwareSampleRate() | |
| 64 { | |
| 65 return static_cast<float>(Platform::current()->audioHardwareSampleRate()); | |
| 66 } | |
| 67 | |
| 68 unsigned AudioRenderSink::audioHardwareChannelCount() | |
| 69 { | |
| 70 return static_cast<unsigned>(Platform::current()->audioHardwareOutputChannel s()); | |
|
o1ka
2016/05/27 14:28:23
If WebAudioDevice provides all these information,
| |
| 71 } | |
| 72 | |
| 73 void AudioRenderSink::start() | |
| 74 { | |
| 75 if (!m_isRunning && m_webAudioDevice) { | |
| 76 m_webAudioDevice->start(); | |
| 77 m_isRunning = true; | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 void AudioRenderSink::stop() | |
| 82 { | |
| 83 if (m_isRunning && m_webAudioDevice) { | |
| 84 m_webAudioDevice->stop(); | |
| 85 m_isRunning = false; | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 void AudioRenderSink::render(const WebVector<float*>& source, const WebVector<fl oat*>& destination, size_t framesToProcess) | |
| 90 { | |
| 91 // If the number of channels or the number of frames to process do not match | |
| 92 // stop the render and return. | |
| 93 if (!(destination.size() == m_numberOfOutputChannels) | |
| 94 || !(framesToProcess == m_callbackBufferSize)) { | |
| 95 NOTREACHED(); | |
| 96 return; | |
| 97 } | |
| 98 | |
| 99 // Fetch the input stream and make the data available in the input FIFO. | |
| 100 if (source.size() >= 2) { | |
| 101 // TODO: implement this. | |
| 102 } | |
| 103 | |
| 104 for (unsigned i = 0; i < m_numberOfOutputChannels; ++i) | |
| 105 m_outputBus->setChannelMemory(i, destination[i], framesToProcess); | |
| 106 | |
| 107 // Fill the destination buffer by consuming data in the pull FIFO. | |
| 108 m_pullFifo->consume(m_outputBus.get(), framesToProcess); | |
| 109 | |
| 110 // LOG(INFO) << "AudioRenderSink::render" << framesToProcess; | |
| 111 } | |
| 112 | |
| 113 void AudioRenderSink::provideInput(AudioBus* outputBus, size_t numberOfFrames) | |
| 114 { | |
| 115 AudioBus* inputBus = m_inputBus.get(); | |
| 116 m_callback.render(inputBus, outputBus, numberOfFrames); | |
| 117 } | |
| 118 | |
| 119 } // namespace blink | |
| OLD | NEW |