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 "ppapi/shared_impl/ppb_audio_config_shared.h" | 5 #include "ppapi/shared_impl/ppb_audio_config_shared.h" |
6 #include "ppapi/thunk/enter.h" | 6 #include "ppapi/thunk/enter.h" |
7 #include "ppapi/thunk/ppb_instance_api.h" | 7 #include "ppapi/thunk/ppb_instance_api.h" |
8 | 8 |
9 namespace ppapi { | 9 namespace ppapi { |
10 | 10 |
11 // Rounds up requested_size to the nearest multiple of minimum_size. | |
12 static uint32_t CalculateMultipleOfSampleFrameCount(uint32_t minimum_size, | |
13 uint32_t requested_size) { | |
14 const uint32_t multiple = (requested_size + minimum_size - 1) / minimum_size; | |
15 return std::min(minimum_size * multiple, | |
16 static_cast<uint32_t>(PP_AUDIOMAXSAMPLEFRAMECOUNT)); | |
17 } | |
18 | |
11 PPB_AudioConfig_Shared::PPB_AudioConfig_Shared(ResourceObjectType type, | 19 PPB_AudioConfig_Shared::PPB_AudioConfig_Shared(ResourceObjectType type, |
12 PP_Instance instance) | 20 PP_Instance instance) |
13 : Resource(type, instance), | 21 : Resource(type, instance), |
14 sample_rate_(PP_AUDIOSAMPLERATE_NONE), | 22 sample_rate_(PP_AUDIOSAMPLERATE_NONE), |
15 sample_frame_count_(0) { | 23 sample_frame_count_(0) { |
16 } | 24 } |
17 | 25 |
18 PPB_AudioConfig_Shared::~PPB_AudioConfig_Shared() { | 26 PPB_AudioConfig_Shared::~PPB_AudioConfig_Shared() { |
19 } | 27 } |
20 | 28 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 return 0; | 63 return 0; |
56 | 64 |
57 // Get the hardware config. | 65 // Get the hardware config. |
58 PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>( | 66 PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>( |
59 enter.functions()->GetAudioHardwareOutputSampleRate(instance)); | 67 enter.functions()->GetAudioHardwareOutputSampleRate(instance)); |
60 uint32_t hardware_sample_frame_count = | 68 uint32_t hardware_sample_frame_count = |
61 enter.functions()->GetAudioHardwareOutputBufferSize(instance); | 69 enter.functions()->GetAudioHardwareOutputBufferSize(instance); |
62 if (sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT) | 70 if (sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT) |
63 sample_frame_count = PP_AUDIOMINSAMPLEFRAMECOUNT; | 71 sample_frame_count = PP_AUDIOMINSAMPLEFRAMECOUNT; |
64 | 72 |
73 // If hardware information isn't available we're connected to a fake audio | |
74 // output stream on the browser side, so we can use whatever sample count the | |
75 // client wants. | |
76 if (!hardware_sample_frame_count || !hardware_sample_rate) | |
77 return sample_frame_count; | |
78 | |
79 // Note: All the values below were determined through experimentation to | |
80 // minimize jitter and back-to-back callbacks from the browser. Please take | |
81 // care when modifying these values as they impact a large number of users. | |
82 // TODO(dalecurtis): Land jitter test and add documentation for updating this. | |
83 | |
84 // These values have only been tested with 44.1kHz and 48kHz, so ensure a | |
85 // runtime error occurs when new sample rates are added. | |
86 if (sample_rate != PP_AUDIOSAMPLERATE_44100 && | |
87 sample_rate != PP_AUDIOSAMPLERATE_48000) { | |
88 NOTREACHED() << "Unsupported sample rate, please update " | |
Chris Rogers
2013/05/03 19:55:06
I could be wrong, but isn't NOTREACHED() supposed
DaleCurtis
2013/05/03 20:02:08
There's PP_DCHECK() which wraps assert(). If that
DaleCurtis
2013/05/21 23:16:43
Actually cpp/ which defines PP_DCHECK is excluded
| |
89 << "RecommendSampleFrameCount_1_1()!"; | |
90 return 0; | |
91 } | |
92 | |
65 // If client is using same sample rate as audio hardware, then recommend a | 93 // If client is using same sample rate as audio hardware, then recommend a |
66 // multiple of the audio hardware's sample frame count. | 94 // multiple of the audio hardware's sample frame count. |
67 if (hardware_sample_rate == sample_rate && hardware_sample_frame_count > 0) { | 95 if (hardware_sample_rate == sample_rate) { |
68 // Round up input sample_frame_count to nearest multiple. | 96 return CalculateMultipleOfSampleFrameCount( |
69 uint32_t multiple = (sample_frame_count + hardware_sample_frame_count - 1) / | 97 hardware_sample_frame_count, sample_frame_count); |
70 hardware_sample_frame_count; | |
71 uint32_t recommendation = hardware_sample_frame_count * multiple; | |
72 if (recommendation > PP_AUDIOMAXSAMPLEFRAMECOUNT) | |
73 recommendation = PP_AUDIOMAXSAMPLEFRAMECOUNT; | |
74 return recommendation; | |
75 } | 98 } |
76 | 99 |
77 // Otherwise, recommend a conservative 50ms buffer based on sample rate. | 100 // Should track the value reported by XP and ALSA backends. |
78 const uint32_t kDefault50msAt44100kHz = 2205; | 101 const uint32_t kHighLatencySampleFrameCount = 2048; |
79 const uint32_t kDefault50msAt48000kHz = 2400; | 102 |
80 switch (sample_rate) { | 103 // If the hardware requires a high latency buffer or we're at a low sample |
81 case PP_AUDIOSAMPLERATE_44100: | 104 // rate w/ a buffer that's too large, choose the nearest multiple of the high |
82 return kDefault50msAt44100kHz; | 105 // latency sample frame count. An example of too low and too large is 16kHz |
83 case PP_AUDIOSAMPLERATE_48000: | 106 // and a sample frame count greater than 160 frames. |
84 return kDefault50msAt48000kHz; | 107 if (hardware_sample_frame_count >= kHighLatencySampleFrameCount || |
85 case PP_AUDIOSAMPLERATE_NONE: | 108 (hardware_sample_rate < 44100 && |
86 return 0; | 109 hardware_sample_frame_count > hardware_sample_rate / 100)) { |
110 return CalculateMultipleOfSampleFrameCount( | |
111 sample_frame_count, | |
112 std::max(kHighLatencySampleFrameCount, hardware_sample_frame_count)); | |
87 } | 113 } |
88 // Unable to make a recommendation. | 114 |
89 return 0; | 115 // All low latency clients should be able to handle a 512 frame buffer with |
116 // resampling from 44.1kHz and 48kHz to higher sample rates. | |
117 const uint32_t kLowLatencySampleFrameCount = 512; | |
henrika (OOO until Aug 14)
2013/05/13 08:11:56
Would it be beneficial to do as for WebRTC and alw
DaleCurtis
2013/05/13 21:57:37
We could provide AudioConverter to PPAPI, but that
| |
118 | |
119 // Special case for 48kHz -> 44.1kHz and buffer sizes too large. Which | |
henrika (OOO until Aug 14)
2013/05/14 07:29:35
This sentence is a bit vague IMO. Could it be clar
DaleCurtis
2013/05/21 23:16:43
Cleaned up a bit. Linux part is unnecessary.
| |
120 // includes all Linux clients at the time of this writing (sizes >= 512). | |
121 int min_sample_frame_count = kLowLatencySampleFrameCount; | |
122 if (hardware_sample_rate == 44100 && sample_rate == 48000 && | |
123 hardware_sample_frame_count > hardware_sample_rate / 100) { | |
124 min_sample_frame_count = std::max( | |
125 2 * kLowLatencySampleFrameCount, hardware_sample_frame_count); | |
126 } | |
127 | |
128 return CalculateMultipleOfSampleFrameCount( | |
129 min_sample_frame_count, sample_frame_count); | |
90 } | 130 } |
91 | 131 |
92 // static | 132 // static |
93 PP_AudioSampleRate PPB_AudioConfig_Shared::RecommendSampleRate( | 133 PP_AudioSampleRate PPB_AudioConfig_Shared::RecommendSampleRate( |
94 PP_Instance instance) { | 134 PP_Instance instance) { |
95 thunk::EnterInstanceNoLock enter(instance); | 135 thunk::EnterInstanceNoLock enter(instance); |
96 if (enter.failed()) | 136 if (enter.failed()) |
97 return PP_AUDIOSAMPLERATE_NONE; | 137 return PP_AUDIOSAMPLERATE_NONE; |
98 PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>( | 138 PP_AudioSampleRate hardware_sample_rate = static_cast<PP_AudioSampleRate>( |
99 enter.functions()->GetAudioHardwareOutputSampleRate(instance)); | 139 enter.functions()->GetAudioHardwareOutputSampleRate(instance)); |
(...skipping 25 matching lines...) Expand all Loading... | |
125 if (sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT || | 165 if (sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT || |
126 sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT) | 166 sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT) |
127 return false; | 167 return false; |
128 | 168 |
129 sample_rate_ = sample_rate; | 169 sample_rate_ = sample_rate; |
130 sample_frame_count_ = sample_frame_count; | 170 sample_frame_count_ = sample_frame_count; |
131 return true; | 171 return true; |
132 } | 172 } |
133 | 173 |
134 } // namespace ppapi | 174 } // namespace ppapi |
OLD | NEW |