Chromium Code Reviews| 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 |