OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 "media/base/audio_latency.h" | 5 #include "media/base/audio_latency.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/sys_info.h" |
12 #include "base/time/time.h" | 13 #include "base/time/time.h" |
13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
14 | 15 |
15 namespace media { | 16 namespace media { |
16 | 17 |
17 namespace { | 18 namespace { |
18 #if !defined(OS_WIN) | 19 #if !defined(OS_WIN) |
19 // Taken from "Bit Twiddling Hacks" | 20 // Taken from "Bit Twiddling Hacks" |
20 // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 | 21 // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 |
21 uint32_t RoundUpToPowerOfTwo(uint32_t v) { | 22 uint32_t RoundUpToPowerOfTwo(uint32_t v) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 DCHECK_NE(0, hardware_buffer_size); | 136 DCHECK_NE(0, hardware_buffer_size); |
136 | 137 |
137 // Round the requested size to the nearest multiple of the hardware size | 138 // Round the requested size to the nearest multiple of the hardware size |
138 const int buffer_size = | 139 const int buffer_size = |
139 std::round(std::max(requested_buffer_size, 1.0) / hardware_buffer_size) * | 140 std::round(std::max(requested_buffer_size, 1.0) / hardware_buffer_size) * |
140 hardware_buffer_size; | 141 hardware_buffer_size; |
141 | 142 |
142 return std::max(buffer_size, hardware_buffer_size); | 143 return std::max(buffer_size, hardware_buffer_size); |
143 } | 144 } |
144 | 145 |
| 146 #if defined(OS_MACOSX) |
| 147 namespace { |
| 148 // Define bounds for for low-latency input and output streams. |
| 149 static const int kMinimumInputOutputBufferSize = 128; |
| 150 static const int kMaximumInputOutputBufferSize = 4096; |
| 151 |
| 152 static int GetDefaultBufferSize(bool is_input, int sample_rate) { |
| 153 // kMinimumInputOutputBufferSize is too small for the output side because |
| 154 // CoreAudio can get into under-run if the renderer fails delivering data |
| 155 // to the browser within the allowed time by the OS. The workaround is to |
| 156 // use 256 samples as the default output buffer size for sample rates |
| 157 // smaller than 96KHz. |
| 158 // TODO(xians): Remove this workaround after WebAudio supports user defined |
| 159 // buffer size. See https://github.com/WebAudio/web-audio-api/issues/348 |
| 160 // for details. |
| 161 int buffer_size = is_input ? kMinimumInputOutputBufferSize |
| 162 : 2 * kMinimumInputOutputBufferSize; |
| 163 if (sample_rate > 48000) { |
| 164 // The default buffer size is too small for higher sample rates and may lead |
| 165 // to glitching. Adjust upwards by multiples of the default size. |
| 166 if (sample_rate <= 96000) |
| 167 buffer_size = 2 * kMinimumInputOutputBufferSize; |
| 168 else if (sample_rate <= 192000) |
| 169 buffer_size = 4 * kMinimumInputOutputBufferSize; |
| 170 } |
| 171 return buffer_size; |
| 172 } |
| 173 } // namespace |
| 174 |
| 175 int AudioLatency::GetMinimumAudioBufferSize(int sample_rate) { |
| 176 return GetDefaultBufferSize(false, sample_rate); |
| 177 } |
| 178 |
| 179 int AudioLatency::GetMaximumAudioBufferSize(int sample_rate) { |
| 180 return kMaximumInputOutputBufferSize; |
| 181 } |
| 182 |
| 183 int AudioLatency::GetDefaultAudioBufferSize(bool is_input, int sample_rate) { |
| 184 return GetDefaultBufferSize(is_input, sample_rate); |
| 185 } |
| 186 #elif defined(USE_CRAS) |
| 187 namespace { |
| 188 // Define bounds for the output buffer size. |
| 189 const int kMinimumOutputBufferSize = 512; |
| 190 const int kMaximumOutputBufferSize = 8192; |
| 191 |
| 192 static int GetMinimumOutputBufferSizePerBoard() { |
| 193 // On faster boards we can use smaller buffer size for lower latency. |
| 194 // On slower boards we should use larger buffer size to prevent underrun. |
| 195 std::string board = base::SysInfo::GetLsbReleaseBoard(); |
| 196 if (board == "kevin") |
| 197 return 768; |
| 198 else if (board == "samus") |
| 199 return 256; |
| 200 return kMinimumOutputBufferSize; |
| 201 } |
| 202 } // namespace |
| 203 |
| 204 int AudioLatency::GetMinimumAudioBufferSize(int sample_rate) { |
| 205 return GetMinimumOutputBufferSizePerBoard(); |
| 206 } |
| 207 |
| 208 int AudioLatency::GetMaximumAudioBufferSize(int sample_rate) { |
| 209 return kMaximumOutputBufferSize; |
| 210 } |
| 211 |
| 212 int AudioLatency::GetDefaultAudioBufferSize(bool is_input, int sample_rate) { |
| 213 return GetMinimumOutputBufferSizePerBoard(); |
| 214 } |
| 215 #endif |
| 216 |
145 } // namespace media | 217 } // namespace media |
OLD | NEW |