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 |