OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/audio/PushPullFIFO.h" | 5 #include "platform/audio/PushPullFIFO.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include "platform/audio/AudioUtilities.h" | 8 #include "platform/audio/AudioUtilities.h" |
9 #include "platform/wtf/PtrUtil.h" | 9 #include "platform/wtf/PtrUtil.h" |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... | |
27 underflow_count_(0) { | 27 underflow_count_(0) { |
28 CHECK_LE(fifo_length_, kMaxFIFOLength); | 28 CHECK_LE(fifo_length_, kMaxFIFOLength); |
29 fifo_bus_ = AudioBus::Create(number_of_channels, fifo_length_); | 29 fifo_bus_ = AudioBus::Create(number_of_channels, fifo_length_); |
30 } | 30 } |
31 | 31 |
32 PushPullFIFO::~PushPullFIFO() {} | 32 PushPullFIFO::~PushPullFIFO() {} |
33 | 33 |
34 // Push the data from |inputBus| to FIFO. The size of push is determined by | 34 // Push the data from |inputBus| to FIFO. The size of push is determined by |
35 // the length of |inputBus|. | 35 // the length of |inputBus|. |
36 void PushPullFIFO::Push(const AudioBus* input_bus) { | 36 void PushPullFIFO::Push(const AudioBus* input_bus) { |
37 MutexLocker locker(lock_); | |
38 | |
37 CHECK(input_bus); | 39 CHECK(input_bus); |
38 CHECK_EQ(input_bus->length(), AudioUtilities::kRenderQuantumFrames); | 40 CHECK_EQ(input_bus->length(), AudioUtilities::kRenderQuantumFrames); |
39 SECURITY_CHECK(input_bus->length() <= fifo_length_); | 41 SECURITY_CHECK(input_bus->length() <= fifo_length_); |
40 SECURITY_CHECK(index_write_ < fifo_length_); | 42 SECURITY_CHECK(index_write_ < fifo_length_); |
41 | 43 |
42 const size_t input_bus_length = input_bus->length(); | 44 const size_t input_bus_length = input_bus->length(); |
43 const size_t remainder = fifo_length_ - index_write_; | 45 const size_t remainder = fifo_length_ - index_write_; |
44 | 46 |
45 for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) { | 47 for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) { |
46 float* fifo_bus_channel = fifo_bus_->Channel(i)->MutableData(); | 48 float* fifo_bus_channel = fifo_bus_->Channel(i)->MutableData(); |
(...skipping 28 matching lines...) Expand all Loading... | |
75 } | 77 } |
76 | 78 |
77 // Update the number of frames available in FIFO. | 79 // Update the number of frames available in FIFO. |
78 frames_available_ = | 80 frames_available_ = |
79 std::min(frames_available_ + input_bus_length, fifo_length_); | 81 std::min(frames_available_ + input_bus_length, fifo_length_); |
80 DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_); | 82 DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_); |
81 } | 83 } |
82 | 84 |
83 // Pull the data out of FIFO to |outputBus|. If remaining frame in the FIFO | 85 // Pull the data out of FIFO to |outputBus|. If remaining frame in the FIFO |
84 // is less than the frames to pull, provides remaining frame plus the silence. | 86 // is less than the frames to pull, provides remaining frame plus the silence. |
85 void PushPullFIFO::Pull(AudioBus* output_bus, size_t frames_requested) { | 87 void PushPullFIFO::Pull( |
88 AudioBus* output_bus, | |
89 size_t frames_requested, | |
90 std::unique_ptr<WTF::Function<void(size_t, size_t)>> | |
91 push_request_render_callback) { | |
86 #if OS(ANDROID) | 92 #if OS(ANDROID) |
87 if (!output_bus) { | 93 if (!output_bus) { |
88 // Log when outputBus or FIFO object is invalid. (crbug.com/692423) | 94 // Log when outputBus or FIFO object is invalid. (crbug.com/692423) |
89 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) | 95 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) |
90 << ">] |outputBus| is invalid."; | 96 << ">] |outputBus| is invalid."; |
91 // Silently return to avoid crash. | 97 // Silently return to avoid crash. |
nhiroki
2017/04/17 03:27:30
Generally, I'd recommend to run the callback on al
hongchan
2017/04/17 16:03:29
A good point. I missed that.
| |
92 return; | 98 return; |
93 } | 99 } |
94 | 100 |
95 // The following checks are in place to catch the inexplicable crash. | 101 // The following checks are in place to catch the inexplicable crash. |
96 // (crbug.com/692423) | 102 // (crbug.com/692423) |
97 if (frames_requested > output_bus->length()) { | 103 if (frames_requested > output_bus->length()) { |
98 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) | 104 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) |
99 << ">] framesRequested > outputBus->length() (" | 105 << ">] framesRequested > outputBus->length() (" |
100 << frames_requested << " > " << output_bus->length() << ")"; | 106 << frames_requested << " > " << output_bus->length() << ")"; |
101 } | 107 } |
102 if (frames_requested > fifo_length_) { | 108 if (frames_requested > fifo_length_) { |
103 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) | 109 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) |
104 << ">] framesRequested > m_fifoLength (" << frames_requested | 110 << ">] framesRequested > m_fifoLength (" << frames_requested |
105 << " > " << fifo_length_ << ")"; | 111 << " > " << fifo_length_ << ")"; |
106 } | 112 } |
107 if (index_read_ >= fifo_length_) { | 113 if (index_read_ >= fifo_length_) { |
108 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) | 114 LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << static_cast<void*>(this) |
109 << ">] m_indexRead >= m_fifoLength (" << index_read_ | 115 << ">] m_indexRead >= m_fifoLength (" << index_read_ |
110 << " >= " << fifo_length_ << ")"; | 116 << " >= " << fifo_length_ << ")"; |
111 } | 117 } |
112 #endif | 118 #endif |
119 | |
120 MutexLocker locker(lock_); | |
121 | |
113 CHECK(output_bus); | 122 CHECK(output_bus); |
114 SECURITY_CHECK(frames_requested <= output_bus->length()); | 123 SECURITY_CHECK(frames_requested <= output_bus->length()); |
115 SECURITY_CHECK(frames_requested <= fifo_length_); | 124 SECURITY_CHECK(frames_requested <= fifo_length_); |
116 SECURITY_CHECK(index_read_ < fifo_length_); | 125 SECURITY_CHECK(index_read_ < fifo_length_); |
117 | 126 |
118 const size_t remainder = fifo_length_ - index_read_; | 127 const size_t remainder = fifo_length_ - index_read_; |
119 const size_t frames_to_fill = std::min(frames_available_, frames_requested); | 128 const size_t frames_to_fill = std::min(frames_available_, frames_requested); |
120 | 129 |
121 for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) { | 130 for (unsigned i = 0; i < fifo_bus_->NumberOfChannels(); ++i) { |
122 const float* fifo_bus_channel = fifo_bus_->Channel(i)->Data(); | 131 const float* fifo_bus_channel = fifo_bus_->Channel(i)->Data(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 << "underflowCount=" << underflow_count_ | 164 << "underflowCount=" << underflow_count_ |
156 << ", availableFrames=" << frames_available_ | 165 << ", availableFrames=" << frames_available_ |
157 << ", requestedFrames=" << frames_requested | 166 << ", requestedFrames=" << frames_requested |
158 << ", fifoLength=" << fifo_length_ << ")"; | 167 << ", fifoLength=" << fifo_length_ << ")"; |
159 } | 168 } |
160 } | 169 } |
161 | 170 |
162 // Update the number of frames in FIFO. | 171 // Update the number of frames in FIFO. |
163 frames_available_ -= frames_to_fill; | 172 frames_available_ -= frames_to_fill; |
164 DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_); | 173 DCHECK_EQ((index_read_ + frames_available_) % fifo_length_, index_write_); |
174 | |
175 // Number of frames to render via WebAudio graph. |framesToRender > 0| means | |
176 // the frames in FIFO is not enough to fulfill the requested frames from the | |
177 // audio device. | |
178 size_t frames_to_render = frames_requested > frames_available_ | |
179 ? frames_requested - frames_available_ | |
180 : 0; | |
181 | |
182 if (frames_to_render > 0) | |
183 (*push_request_render_callback)(frames_requested, frames_to_render); | |
nhiroki
2017/04/17 03:27:30
This callback is called within the mutex section (
hongchan
2017/04/17 16:03:29
Actually that'd be cleaner than what I have here.
| |
165 } | 184 } |
166 | 185 |
167 const PushPullFIFOStateForTest PushPullFIFO::GetStateForTest() const { | 186 const PushPullFIFOStateForTest PushPullFIFO::GetStateForTest() const { |
168 return {length(), NumberOfChannels(), FramesAvailable(), index_read_, | 187 return {length(), NumberOfChannels(), frames_available_, index_read_, |
169 index_write_, overflow_count_, underflow_count_}; | 188 index_write_, overflow_count_, underflow_count_}; |
170 } | 189 } |
171 | 190 |
172 } // namespace blink | 191 } // namespace blink |
OLD | NEW |