Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: chromecast/media/cma/backend/alsa/stream_mixer_alsa.cc

Issue 1632393002: [Chromecast] Resample all audio below 32000 Hz. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "chromecast/media/cma/backend/alsa/stream_mixer_alsa.h" 5 #include "chromecast/media/cma/backend/alsa/stream_mixer_alsa.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <utility> 10 #include <utility>
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 // A list of supported sample rates. 76 // A list of supported sample rates.
77 // TODO(jyw): move this up into chromecast/public for 1) documentation and 77 // TODO(jyw): move this up into chromecast/public for 1) documentation and
78 // 2) to help when implementing IsSampleRateSupported() 78 // 2) to help when implementing IsSampleRateSupported()
79 // clang-format off 79 // clang-format off
80 const int kSupportedSampleRates[] = 80 const int kSupportedSampleRates[] =
81 { 8000, 11025, 12000, 81 { 8000, 11025, 12000,
82 16000, 22050, 24000, 82 16000, 22050, 24000,
83 32000, 44100, 48000, 83 32000, 44100, 48000,
84 64000, 88200, 96000}; 84 64000, 88200, 96000};
85 // clang-format on 85 // clang-format on
86 const int kInvalidSampleRate = 0;
86 87
87 // Arbitrary sample rate in Hz to mix all audio to when a new primary input has 88 // Arbitrary sample rate in Hz to mix all audio to when a new primary input has
88 // a sample rate that is not directly supported, and a better fallback sample 89 // a sample rate that is not directly supported, and a better fallback sample
89 // rate cannot be determined. 48000 is the highest supported non-hi-res sample 90 // rate cannot be determined. 48000 is the highest supported non-hi-res sample
90 // rate. 96000 is the highest supported hi-res sample rate. 91 // rate. 96000 is the highest supported hi-res sample rate.
91 const unsigned int kFallbackSampleRate = 48000; 92 const unsigned int kFallbackSampleRate = 48000;
92 const unsigned int kFallbackSampleRateHiRes = 96000; 93 const unsigned int kFallbackSampleRateHiRes = 96000;
93 94
95 // Resample all audio below this frequency.
96 const unsigned int kLowSampleRateCutoff = 32000;
97
94 // The snd_pcm_(hw|sw)_params_set_*_near families of functions will report what 98 // The snd_pcm_(hw|sw)_params_set_*_near families of functions will report what
95 // direction they adjusted the requested parameter in, but since we read the 99 // direction they adjusted the requested parameter in, but since we read the
96 // output param and then log the information, this module doesn't need to get 100 // output param and then log the information, this module doesn't need to get
97 // the direction explicitly. 101 // the direction explicitly.
98 static int* kAlsaDirDontCare = nullptr; 102 static int* kAlsaDirDontCare = nullptr;
99 103
100 // These sample formats will be tried in order. 32 bit samples is ideal, but 104 // These sample formats will be tried in order. 32 bit samples is ideal, but
101 // some devices do not support 32 bit samples. 105 // some devices do not support 32 bit samples.
102 const snd_pcm_format_t kPreferredSampleFormats[] = {SND_PCM_FORMAT_S32, 106 const snd_pcm_format_t kPreferredSampleFormats[] = {SND_PCM_FORMAT_S32,
103 SND_PCM_FORMAT_S16}; 107 SND_PCM_FORMAT_S16};
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 166
163 // static 167 // static
164 void StreamMixerAlsa::MakeSingleThreadedForTest() { 168 void StreamMixerAlsa::MakeSingleThreadedForTest() {
165 single_threaded_for_test_ = true; 169 single_threaded_for_test_ = true;
166 StreamMixerAlsa::Get()->ResetTaskRunnerForTest(); 170 StreamMixerAlsa::Get()->ResetTaskRunnerForTest();
167 } 171 }
168 172
169 StreamMixerAlsa::StreamMixerAlsa() 173 StreamMixerAlsa::StreamMixerAlsa()
170 : mixer_thread_(new base::Thread("ALSA CMA mixer thread")), 174 : mixer_thread_(new base::Thread("ALSA CMA mixer thread")),
171 mixer_task_runner_(nullptr), 175 mixer_task_runner_(nullptr),
172 requested_output_samples_per_second_(0), 176 requested_output_samples_per_second_(kInvalidSampleRate),
173 output_samples_per_second_(0), 177 output_samples_per_second_(kInvalidSampleRate),
174 pcm_(nullptr), 178 pcm_(nullptr),
175 pcm_hw_params_(nullptr), 179 pcm_hw_params_(nullptr),
176 pcm_status_(nullptr), 180 pcm_status_(nullptr),
177 pcm_format_(SND_PCM_FORMAT_UNKNOWN), 181 pcm_format_(SND_PCM_FORMAT_UNKNOWN),
178 alsa_buffer_size_(0), 182 alsa_buffer_size_(0),
179 alsa_period_explicitly_set(false), 183 alsa_period_explicitly_set(false),
180 alsa_period_size_(0), 184 alsa_period_size_(0),
181 alsa_start_threshold_(0), 185 alsa_start_threshold_(0),
182 alsa_avail_min_(0), 186 alsa_avail_min_(0),
183 state_(kStateUninitialized), 187 state_(kStateUninitialized),
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 // doesn't always choose a rate that's actually near the given input sample 303 // doesn't always choose a rate that's actually near the given input sample
300 // rate when the input sample rate is not supported. 304 // rate when the input sample rate is not supported.
301 const int* kSupportedSampleRatesEnd = 305 const int* kSupportedSampleRatesEnd =
302 kSupportedSampleRates + arraysize(kSupportedSampleRates); 306 kSupportedSampleRates + arraysize(kSupportedSampleRates);
303 auto nearest_sample_rate = 307 auto nearest_sample_rate =
304 std::min_element(kSupportedSampleRates, kSupportedSampleRatesEnd, 308 std::min_element(kSupportedSampleRates, kSupportedSampleRatesEnd,
305 [this](int r1, int r2) -> bool { 309 [this](int r1, int r2) -> bool {
306 return abs(requested_output_samples_per_second_ - r1) < 310 return abs(requested_output_samples_per_second_ - r1) <
307 abs(requested_output_samples_per_second_ - r2); 311 abs(requested_output_samples_per_second_ - r2);
308 }); 312 });
313 // Resample audio with sample rates deemed to be too low (i.e. below 32kHz)
314 // because some common AV receivers don't support optical out at these
315 // frequencies. See b/26385501
316 unsigned int first_choice_sample_rate = requested_rate;
317 if (requested_rate < kLowSampleRateCutoff) {
318 first_choice_sample_rate = output_samples_per_second_ != kInvalidSampleRate
319 ? output_samples_per_second_
320 : kFallbackSampleRate;
321 }
309 const unsigned int preferred_sample_rates[] = { 322 const unsigned int preferred_sample_rates[] = {
310 requested_rate, 323 first_choice_sample_rate,
311 static_cast<unsigned int>(*nearest_sample_rate), 324 static_cast<unsigned int>(*nearest_sample_rate),
312 kFallbackSampleRateHiRes, 325 kFallbackSampleRateHiRes,
313 kFallbackSampleRate}; 326 kFallbackSampleRate};
314 for (const auto& sample_rate : preferred_sample_rates) { 327 for (const auto& sample_rate : preferred_sample_rates) {
315 err = alsa_->PcmHwParamsTestRate(pcm_, pcm_hw_params_, sample_rate, 328 err = alsa_->PcmHwParamsTestRate(pcm_, pcm_hw_params_, sample_rate,
316 0 /* try exact rate */); 329 0 /* try exact rate */);
317 if (err == 0) { 330 if (err == 0) {
318 unsigned_output_samples_per_second = sample_rate; 331 unsigned_output_samples_per_second = sample_rate;
319 break; 332 break;
320 } 333 }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 470
458 state_ = kStateNormalPlayback; 471 state_ = kStateNormalPlayback;
459 } 472 }
460 473
461 void StreamMixerAlsa::Stop() { 474 void StreamMixerAlsa::Stop() {
462 alsa_->PcmStatusFree(pcm_status_); 475 alsa_->PcmStatusFree(pcm_status_);
463 pcm_status_ = nullptr; 476 pcm_status_ = nullptr;
464 alsa_->PcmHwParamsFree(pcm_hw_params_); 477 alsa_->PcmHwParamsFree(pcm_hw_params_);
465 pcm_hw_params_ = nullptr; 478 pcm_hw_params_ = nullptr;
466 state_ = kStateUninitialized; 479 state_ = kStateUninitialized;
480 output_samples_per_second_ = kInvalidSampleRate;
467 481
468 if (!pcm_) 482 if (!pcm_)
469 return; 483 return;
470 484
471 // If |pcm_| is RUNNING, drain all pending data. 485 // If |pcm_| is RUNNING, drain all pending data.
472 if (alsa_->PcmState(pcm_) == SND_PCM_STATE_RUNNING) { 486 if (alsa_->PcmState(pcm_) == SND_PCM_STATE_RUNNING) {
473 int err = alsa_->PcmDrain(pcm_); 487 int err = alsa_->PcmDrain(pcm_);
474 if (err < 0) 488 if (err < 0)
475 LOG(ERROR) << "snd_pcm_drain error: " << alsa_->StrError(err); 489 LOG(ERROR) << "snd_pcm_drain error: " << alsa_->StrError(err);
476 } else { 490 } else {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 input_ptr->Initialize(rendering_delay_); 555 input_ptr->Initialize(rendering_delay_);
542 } else { 556 } else {
543 input_ptr->SignalError(); 557 input_ptr->SignalError();
544 } 558 }
545 } 559 }
546 560
547 void StreamMixerAlsa::CheckChangeOutputRate(int input_samples_per_second) { 561 void StreamMixerAlsa::CheckChangeOutputRate(int input_samples_per_second) {
548 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); 562 DCHECK(mixer_task_runner_->BelongsToCurrentThread());
549 if (!pcm_ || 563 if (!pcm_ ||
550 input_samples_per_second == requested_output_samples_per_second_ || 564 input_samples_per_second == requested_output_samples_per_second_ ||
551 input_samples_per_second == output_samples_per_second_) 565 input_samples_per_second == output_samples_per_second_ ||
566 input_samples_per_second < static_cast<int>(kLowSampleRateCutoff))
552 return; 567 return;
553 for (InputQueue* input : inputs_) { 568 for (InputQueue* input : inputs_) {
554 if (input->primary() && !input->IsDeleting()) 569 if (input->primary() && !input->IsDeleting())
555 return; 570 return;
556 } 571 }
557 572
558 // Move all current inputs to the ignored list 573 // Move all current inputs to the ignored list
559 for (InputQueue* input : inputs_) { 574 for (InputQueue* input : inputs_) {
560 LOG(INFO) << "Mixer input " << input 575 LOG(INFO) << "Mixer input " << input
561 << " now being ignored due to output sample rate change from " 576 << " now being ignored due to output sample rate change from "
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 rendering_delay_.timestamp_microseconds = 758 rendering_delay_.timestamp_microseconds =
744 TimespecToMicroseconds(status_timestamp); 759 TimespecToMicroseconds(status_timestamp);
745 snd_pcm_sframes_t delay_frames = alsa_->PcmStatusGetDelay(pcm_status_); 760 snd_pcm_sframes_t delay_frames = alsa_->PcmStatusGetDelay(pcm_status_);
746 rendering_delay_.delay_microseconds = static_cast<int64_t>(delay_frames) * 761 rendering_delay_.delay_microseconds = static_cast<int64_t>(delay_frames) *
747 base::Time::kMicrosecondsPerSecond / 762 base::Time::kMicrosecondsPerSecond /
748 output_samples_per_second_; 763 output_samples_per_second_;
749 } 764 }
750 765
751 } // namespace media 766 } // namespace media
752 } // namespace chromecast 767 } // namespace chromecast
OLDNEW
« no previous file with comments | « chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698