OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "build/build_config.h" | 5 #include "build/build_config.h" |
6 #include "ppapi/shared_impl/ppb_audio_config_shared.h" | 6 #include "ppapi/shared_impl/ppb_audio_config_shared.h" |
7 #include "ppapi/thunk/enter.h" | 7 #include "ppapi/thunk/enter.h" |
8 #include "ppapi/thunk/ppb_instance_api.h" | 8 #include "ppapi/thunk/ppb_instance_api.h" |
9 | 9 |
10 namespace ppapi { | 10 namespace ppapi { |
11 | 11 |
12 // Rounds up requested_size to the nearest multiple of minimum_size. | 12 // Rounds up requested_size to the nearest multiple of minimum_size. |
13 static uint32_t CalculateMultipleOfSampleFrameCount(uint32_t minimum_size, | 13 static uint32_t CalculateMultipleOfSampleFrameCount(uint32_t minimum_size, |
14 uint32_t requested_size) { | 14 uint32_t requested_size) { |
15 const uint32_t multiple = (requested_size + minimum_size - 1) / minimum_size; | 15 const uint32_t multiple = (requested_size + minimum_size - 1) / minimum_size; |
16 return std::min(minimum_size * multiple, | 16 return std::min(minimum_size * multiple, |
17 static_cast<uint32_t>(PP_AUDIOMAXSAMPLEFRAMECOUNT)); | 17 static_cast<uint32_t>(PP_AUDIOMAXSAMPLEFRAMECOUNT)); |
18 } | 18 } |
19 | 19 |
20 PPB_AudioConfig_Shared::PPB_AudioConfig_Shared(ResourceObjectType type, | 20 PPB_AudioConfig_Shared::PPB_AudioConfig_Shared(ResourceObjectType type, |
21 PP_Instance instance) | 21 PP_Instance instance) |
22 : Resource(type, instance), | 22 : Resource(type, instance), |
23 sample_rate_(PP_AUDIOSAMPLERATE_NONE), | 23 sample_rate_(PP_AUDIOSAMPLERATE_NONE), |
24 sample_frame_count_(0) { | 24 sample_frame_count_(0) {} |
25 } | |
26 | 25 |
27 PPB_AudioConfig_Shared::~PPB_AudioConfig_Shared() { | 26 PPB_AudioConfig_Shared::~PPB_AudioConfig_Shared() {} |
28 } | |
29 | 27 |
30 PP_Resource PPB_AudioConfig_Shared::Create( | 28 PP_Resource PPB_AudioConfig_Shared::Create(ResourceObjectType type, |
31 ResourceObjectType type, | 29 PP_Instance instance, |
32 PP_Instance instance, | 30 PP_AudioSampleRate sample_rate, |
33 PP_AudioSampleRate sample_rate, | 31 uint32_t sample_frame_count) { |
34 uint32_t sample_frame_count) { | |
35 scoped_refptr<PPB_AudioConfig_Shared> object( | 32 scoped_refptr<PPB_AudioConfig_Shared> object( |
36 new PPB_AudioConfig_Shared(type, instance)); | 33 new PPB_AudioConfig_Shared(type, instance)); |
37 if (!object->Init(sample_rate, sample_frame_count)) | 34 if (!object->Init(sample_rate, sample_frame_count)) |
38 return 0; | 35 return 0; |
39 return object->GetReference(); | 36 return object->GetReference(); |
40 } | 37 } |
41 | 38 |
42 // static | 39 // static |
43 uint32_t PPB_AudioConfig_Shared::RecommendSampleFrameCount_1_0( | 40 uint32_t PPB_AudioConfig_Shared::RecommendSampleFrameCount_1_0( |
44 PP_AudioSampleRate sample_rate, | 41 PP_AudioSampleRate sample_rate, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 // Adobe Flash is affected but not HTML5, WebRTC and WebAudio (they are using | 87 // Adobe Flash is affected but not HTML5, WebRTC and WebAudio (they are using |
91 // real time threads). | 88 // real time threads). |
92 const bool kHighLatencyDevice = true; | 89 const bool kHighLatencyDevice = true; |
93 #else | 90 #else |
94 const bool kHighLatencyDevice = false; | 91 const bool kHighLatencyDevice = false; |
95 #endif | 92 #endif |
96 | 93 |
97 // If client is using same sample rate as audio hardware, then recommend a | 94 // If client is using same sample rate as audio hardware, then recommend a |
98 // multiple of the audio hardware's sample frame count. | 95 // multiple of the audio hardware's sample frame count. |
99 if (!kHighLatencyDevice && hardware_sample_rate == sample_rate) { | 96 if (!kHighLatencyDevice && hardware_sample_rate == sample_rate) { |
100 return CalculateMultipleOfSampleFrameCount( | 97 return CalculateMultipleOfSampleFrameCount(hardware_sample_frame_count, |
101 hardware_sample_frame_count, sample_frame_count); | 98 sample_frame_count); |
102 } | 99 } |
103 | 100 |
104 // If the hardware requires a high latency buffer or we're at a low sample | 101 // If the hardware requires a high latency buffer or we're at a low sample |
105 // rate w/ a buffer that's larger than 10ms, choose the nearest multiple of | 102 // rate w/ a buffer that's larger than 10ms, choose the nearest multiple of |
106 // the high latency sample frame count. An example of too low and too large | 103 // the high latency sample frame count. An example of too low and too large |
107 // is 16kHz and a sample frame count greater than 160 frames. | 104 // is 16kHz and a sample frame count greater than 160 frames. |
108 if (kHighLatencyDevice || | 105 if (kHighLatencyDevice || |
109 hardware_sample_frame_count >= kHighLatencySampleFrameCount || | 106 hardware_sample_frame_count >= kHighLatencySampleFrameCount || |
110 (hardware_sample_rate < 44100 && | 107 (hardware_sample_rate < 44100 && |
111 hardware_sample_frame_count > hardware_sample_rate / 100u)) { | 108 hardware_sample_frame_count > hardware_sample_rate / 100u)) { |
112 return CalculateMultipleOfSampleFrameCount( | 109 return CalculateMultipleOfSampleFrameCount( |
113 sample_frame_count, | 110 sample_frame_count, |
114 std::max(kHighLatencySampleFrameCount, hardware_sample_frame_count)); | 111 std::max(kHighLatencySampleFrameCount, hardware_sample_frame_count)); |
115 } | 112 } |
116 | 113 |
117 // All low latency clients should be able to handle a 512 frame buffer with | 114 // All low latency clients should be able to handle a 512 frame buffer with |
118 // resampling from 44.1kHz and 48kHz to higher sample rates. | 115 // resampling from 44.1kHz and 48kHz to higher sample rates. |
119 // TODO(dalecurtis): We may need to investigate making the callback thread | 116 // TODO(dalecurtis): We may need to investigate making the callback thread |
120 // high priority to handle buffers at the absolute minimum w/o glitching. | 117 // high priority to handle buffers at the absolute minimum w/o glitching. |
121 const uint32_t kLowLatencySampleFrameCount = 512; | 118 const uint32_t kLowLatencySampleFrameCount = 512; |
122 | 119 |
123 // Special case for 48kHz -> 44.1kHz and buffer sizes greater than 10ms. In | 120 // Special case for 48kHz -> 44.1kHz and buffer sizes greater than 10ms. In |
124 // testing most buffer sizes > 10ms led to glitching, so we choose a size we | 121 // testing most buffer sizes > 10ms led to glitching, so we choose a size we |
125 // know won't cause jitter. | 122 // know won't cause jitter. |
126 int min_sample_frame_count = kLowLatencySampleFrameCount; | 123 int min_sample_frame_count = kLowLatencySampleFrameCount; |
127 if (hardware_sample_rate == 44100 && sample_rate == 48000 && | 124 if (hardware_sample_rate == 44100 && sample_rate == 48000 && |
128 hardware_sample_frame_count > hardware_sample_rate / 100u) { | 125 hardware_sample_frame_count > hardware_sample_rate / 100u) { |
129 min_sample_frame_count = std::max( | 126 min_sample_frame_count = |
130 2 * kLowLatencySampleFrameCount, hardware_sample_frame_count); | 127 std::max(2 * kLowLatencySampleFrameCount, hardware_sample_frame_count); |
131 } | 128 } |
132 | 129 |
133 return CalculateMultipleOfSampleFrameCount( | 130 return CalculateMultipleOfSampleFrameCount(min_sample_frame_count, |
134 min_sample_frame_count, sample_frame_count); | 131 sample_frame_count); |
135 } | 132 } |
136 | 133 |
137 // static | 134 // static |
138 PP_AudioSampleRate PPB_AudioConfig_Shared::RecommendSampleRate( | 135 PP_AudioSampleRate PPB_AudioConfig_Shared::RecommendSampleRate( |
139 PP_Instance instance) { | 136 PP_Instance instance) { |
140 thunk::EnterInstanceNoLock enter(instance); | 137 thunk::EnterInstanceNoLock enter(instance); |
141 if (enter.failed()) | 138 if (enter.failed()) |
142 return PP_AUDIOSAMPLERATE_NONE; | 139 return PP_AUDIOSAMPLERATE_NONE; |
143 PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>( | 140 PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>( |
144 enter.functions()->GetAudioHardwareOutputSampleRate(instance)); | 141 enter.functions()->GetAudioHardwareOutputSampleRate(instance)); |
145 return hardware_sample_rate; | 142 return hardware_sample_rate; |
146 } | 143 } |
147 | 144 |
148 thunk::PPB_AudioConfig_API* PPB_AudioConfig_Shared::AsPPB_AudioConfig_API() { | 145 thunk::PPB_AudioConfig_API* PPB_AudioConfig_Shared::AsPPB_AudioConfig_API() { |
149 return this; | 146 return this; |
150 } | 147 } |
151 | 148 |
152 PP_AudioSampleRate PPB_AudioConfig_Shared::GetSampleRate() { | 149 PP_AudioSampleRate PPB_AudioConfig_Shared::GetSampleRate() { |
153 return sample_rate_; | 150 return sample_rate_; |
154 } | 151 } |
(...skipping 17 matching lines...) Expand all Loading... |
172 if (sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT || | 169 if (sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT || |
173 sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT) | 170 sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT) |
174 return false; | 171 return false; |
175 | 172 |
176 sample_rate_ = sample_rate; | 173 sample_rate_ = sample_rate; |
177 sample_frame_count_ = sample_frame_count; | 174 sample_frame_count_ = sample_frame_count; |
178 return true; | 175 return true; |
179 } | 176 } |
180 | 177 |
181 } // namespace ppapi | 178 } // namespace ppapi |
OLD | NEW |