audio_parameters.cc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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
  3. // found in the LICENSE file.
  4. #include "media/base/audio_parameters.h"
  5. #include <sstream>
  6. #include "media/base/audio_bus.h"
  7. #include "media/base/limits.h"
  8. namespace media {
  9. static_assert(AudioBus::kChannelAlignment == kParametersAlignment,
  10. "Audio buffer parameters struct alignment not same as AudioBus");
  11. static_assert(sizeof(AudioInputBufferParameters) %
  12. AudioBus::kChannelAlignment ==
  13. 0,
  14. "AudioInputBufferParameters not aligned");
  15. static_assert(sizeof(AudioOutputBufferParameters) %
  16. AudioBus::kChannelAlignment ==
  17. 0,
  18. "AudioOutputBufferParameters not aligned");
  19. const char* FormatToString(AudioParameters::Format format) {
  20. switch (format) {
  21. case AudioParameters::AUDIO_PCM_LINEAR:
  22. return "PCM_LINEAR";
  23. case AudioParameters::AUDIO_PCM_LOW_LATENCY:
  24. return "PCM_LOW_LATENCY";
  25. case AudioParameters::AUDIO_BITSTREAM_AC3:
  26. return "BITSTREAM_AC3";
  27. case AudioParameters::AUDIO_BITSTREAM_EAC3:
  28. return "BITSTREAM_EAC3";
  29. case AudioParameters::AUDIO_BITSTREAM_DTS:
  30. return "BITSTREAM_DTS";
  31. case AudioParameters::AUDIO_BITSTREAM_DTS_HD:
  32. return "BITSTREAM_DTS_HD";
  33. case AudioParameters::AUDIO_BITSTREAM_DTSX_P2:
  34. return "BITSTREAM_DTSX_P2";
  35. case AudioParameters::AUDIO_BITSTREAM_IEC61937:
  36. return "BITSTREAM_IEC61937";
  37. case AudioParameters::AUDIO_FAKE:
  38. return "FAKE";
  39. }
  40. }
  41. base::CheckedNumeric<uint32_t> ComputeAudioInputBufferSizeChecked(
  42. const AudioParameters& parameters,
  43. uint32_t shared_memory_count) {
  44. base::CheckedNumeric<uint32_t> result = AudioBus::CalculateMemorySize(
  45. parameters.channels(), parameters.frames_per_buffer());
  46. result += sizeof(media::AudioInputBufferParameters);
  47. result *= shared_memory_count;
  48. return result;
  49. }
  50. uint32_t ComputeAudioInputBufferSize(const AudioParameters& parameters,
  51. uint32_t shared_memory_count) {
  52. return ComputeAudioInputBufferSizeChecked(parameters, shared_memory_count)
  53. .ValueOrDie();
  54. }
  55. uint32_t ComputeAudioInputBufferSize(int channels,
  56. int frames,
  57. uint32_t shared_memory_count) {
  58. base::CheckedNumeric<uint32_t> result =
  59. AudioBus::CalculateMemorySize(channels, frames);
  60. result += sizeof(media::AudioInputBufferParameters);
  61. result *= shared_memory_count;
  62. return result.ValueOrDie();
  63. }
  64. base::CheckedNumeric<uint32_t> ComputeAudioOutputBufferSizeChecked(
  65. const AudioParameters& parameters) {
  66. base::CheckedNumeric<uint32_t> result = AudioBus::CalculateMemorySize(
  67. parameters.channels(), parameters.frames_per_buffer());
  68. result += sizeof(media::AudioOutputBufferParameters);
  69. return result;
  70. }
  71. uint32_t ComputeAudioOutputBufferSize(const AudioParameters& parameters) {
  72. return ComputeAudioOutputBufferSize(parameters.channels(),
  73. parameters.frames_per_buffer());
  74. }
  75. uint32_t ComputeAudioOutputBufferSize(int channels, int frames) {
  76. base::CheckedNumeric<uint32_t> result =
  77. AudioBus::CalculateMemorySize(channels, frames);
  78. result += sizeof(media::AudioOutputBufferParameters);
  79. return result.ValueOrDie();
  80. }
  81. AudioParameters::AudioParameters()
  82. : AudioParameters(AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_NONE, 0, 0) {}
  83. AudioParameters::AudioParameters(Format format,
  84. ChannelLayout channel_layout,
  85. int sample_rate,
  86. int frames_per_buffer)
  87. : latency_tag_(AudioLatency::LATENCY_COUNT) {
  88. Reset(format, channel_layout, sample_rate, frames_per_buffer);
  89. }
  90. AudioParameters::AudioParameters(
  91. Format format,
  92. ChannelLayout channel_layout,
  93. int sample_rate,
  94. int frames_per_buffer,
  95. const HardwareCapabilities& hardware_capabilities)
  96. : latency_tag_(AudioLatency::LATENCY_COUNT),
  97. hardware_capabilities_(hardware_capabilities) {
  98. Reset(format, channel_layout, sample_rate, frames_per_buffer);
  99. }
  100. AudioParameters::~AudioParameters() = default;
  101. AudioParameters::AudioParameters(const AudioParameters&) = default;
  102. AudioParameters& AudioParameters::operator=(const AudioParameters&) = default;
  103. void AudioParameters::Reset(Format format,
  104. ChannelLayout channel_layout,
  105. int sample_rate,
  106. int frames_per_buffer) {
  107. format_ = format;
  108. channel_layout_ = channel_layout;
  109. channels_ = ChannelLayoutToChannelCount(channel_layout);
  110. sample_rate_ = sample_rate;
  111. frames_per_buffer_ = frames_per_buffer;
  112. effects_ = NO_EFFECTS;
  113. mic_positions_.clear();
  114. }
  115. bool AudioParameters::IsValid() const {
  116. return (channels_ > 0) && (channels_ <= media::limits::kMaxChannels) &&
  117. (channel_layout_ > CHANNEL_LAYOUT_UNSUPPORTED) &&
  118. (sample_rate_ >= media::limits::kMinSampleRate) &&
  119. (sample_rate_ <= media::limits::kMaxSampleRate) &&
  120. (frames_per_buffer_ > 0) &&
  121. (frames_per_buffer_ <= media::limits::kMaxSamplesPerPacket) &&
  122. (!hardware_capabilities_ ||
  123. ((hardware_capabilities_->min_frames_per_buffer >= 0) &&
  124. (hardware_capabilities_->min_frames_per_buffer <=
  125. media::limits::kMaxSamplesPerPacket) &&
  126. (hardware_capabilities_->max_frames_per_buffer >= 0) &&
  127. (hardware_capabilities_->max_frames_per_buffer <=
  128. media::limits::kMaxSamplesPerPacket) &&
  129. (hardware_capabilities_->max_frames_per_buffer >=
  130. hardware_capabilities_->min_frames_per_buffer))) &&
  131. (channel_layout_ == CHANNEL_LAYOUT_DISCRETE ||
  132. channel_layout_ == CHANNEL_LAYOUT_5_1_4_DOWNMIX ||
  133. channels_ == ChannelLayoutToChannelCount(channel_layout_));
  134. }
  135. std::string AudioParameters::AsHumanReadableString() const {
  136. std::ostringstream s;
  137. s << "format: " << FormatToString(format())
  138. << ", channel_layout: " << channel_layout() << ", channels: " << channels()
  139. << ", sample_rate: " << sample_rate()
  140. << ", frames_per_buffer: " << frames_per_buffer()
  141. << ", effects: " << effects()
  142. << ", mic_positions: " << PointsToString(mic_positions_);
  143. if (hardware_capabilities_.has_value()) {
  144. s << ", hw_capabilities: min_frames_per_buffer: "
  145. << hardware_capabilities_->min_frames_per_buffer
  146. << ", max_frames_per_buffer: "
  147. << hardware_capabilities_->max_frames_per_buffer
  148. << ", bitstream_formats:" << hardware_capabilities_->bitstream_formats;
  149. }
  150. return s.str();
  151. }
  152. int AudioParameters::GetBytesPerBuffer(SampleFormat fmt) const {
  153. return GetBytesPerFrame(fmt) * frames_per_buffer_;
  154. }
  155. int AudioParameters::GetBytesPerFrame(SampleFormat fmt) const {
  156. return channels_ * SampleFormatToBytesPerChannel(fmt);
  157. }
  158. double AudioParameters::GetMicrosecondsPerFrame() const {
  159. return static_cast<double>(base::Time::kMicrosecondsPerSecond) / sample_rate_;
  160. }
  161. base::TimeDelta AudioParameters::GetBufferDuration() const {
  162. return base::Microseconds(static_cast<int64_t>(
  163. frames_per_buffer_ * base::Time::kMicrosecondsPerSecond /
  164. static_cast<float>(sample_rate_)));
  165. }
  166. bool AudioParameters::Equals(const AudioParameters& other) const {
  167. return format_ == other.format() && sample_rate_ == other.sample_rate() &&
  168. channel_layout_ == other.channel_layout() &&
  169. channels_ == other.channels() &&
  170. frames_per_buffer_ == other.frames_per_buffer() &&
  171. effects_ == other.effects() && mic_positions_ == other.mic_positions_;
  172. }
  173. bool AudioParameters::IsBitstreamFormat() const {
  174. switch (format_) {
  175. case AUDIO_BITSTREAM_AC3:
  176. case AUDIO_BITSTREAM_EAC3:
  177. case AUDIO_BITSTREAM_DTS:
  178. case AUDIO_BITSTREAM_DTS_HD:
  179. case AUDIO_BITSTREAM_DTSX_P2:
  180. case AUDIO_BITSTREAM_IEC61937:
  181. return true;
  182. default:
  183. return false;
  184. }
  185. }
  186. bool AudioParameters::IsFormatSupportedByHardware(Format format) const {
  187. return hardware_capabilities_.has_value() &&
  188. (hardware_capabilities_->bitstream_formats & format);
  189. }
  190. // static
  191. AudioParameters AudioParameters::UnavailableDeviceParams() {
  192. // Using 10 ms buffer since WebAudioMediaStreamSource::DeliverRebufferedAudio
  193. // deals incorrectly with reference time calculation if output buffer size
  194. // significantly differs from 10 ms used there, see http://crbug/701000.
  195. return media::AudioParameters(
  196. media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
  197. media::AudioParameters::kAudioCDSampleRate,
  198. media::AudioParameters::kAudioCDSampleRate / 100);
  199. }
  200. } // namespace media