OLD | NEW |
---|---|
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_input_impl.h" | 5 #include "chromecast/media/cma/backend/alsa/stream_mixer_alsa_input_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 const int kNumOutputChannels = 2; | 49 const int kNumOutputChannels = 2; |
50 const int64_t kMaxInputQueueUs = 90000; | 50 const int64_t kMaxInputQueueUs = 90000; |
51 const int64_t kFadeMs = 15; | 51 const int64_t kFadeMs = 15; |
52 // Number of samples to report as readable when paused. When paused, the mixer | 52 // Number of samples to report as readable when paused. When paused, the mixer |
53 // will still pull this many frames each time it tries to write frames, but we | 53 // will still pull this many frames each time it tries to write frames, but we |
54 // fill the frames with silence. | 54 // fill the frames with silence. |
55 const int kPausedReadSamples = 512; | 55 const int kPausedReadSamples = 512; |
56 const int kDefaultReadSize = ::media::SincResampler::kDefaultRequestSize; | 56 const int kDefaultReadSize = ::media::SincResampler::kDefaultRequestSize; |
57 const int64_t kNoTimestamp = std::numeric_limits<int64_t>::min(); | 57 const int64_t kNoTimestamp = std::numeric_limits<int64_t>::min(); |
58 | 58 |
59 const int kMaxSlewTimeUpMs = 100; | |
60 const int kMaxSlewTimeDownMs = 100; | |
61 | |
59 } // namespace | 62 } // namespace |
60 | 63 |
61 StreamMixerAlsaInputImpl::StreamMixerAlsaInputImpl( | 64 StreamMixerAlsaInputImpl::StreamMixerAlsaInputImpl( |
62 StreamMixerAlsaInput::Delegate* delegate, | 65 StreamMixerAlsaInput::Delegate* delegate, |
63 int input_samples_per_second, | 66 int input_samples_per_second, |
64 bool primary, | 67 bool primary, |
65 StreamMixerAlsa* mixer) | 68 StreamMixerAlsa* mixer) |
66 : delegate_(delegate), | 69 : delegate_(delegate), |
67 input_samples_per_second_(input_samples_per_second), | 70 input_samples_per_second_(input_samples_per_second), |
68 primary_(primary), | 71 primary_(primary), |
69 mixer_(mixer), | 72 mixer_(mixer), |
70 mixer_task_runner_(mixer_->task_runner()), | 73 mixer_task_runner_(mixer_->task_runner()), |
71 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 74 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
72 resample_ratio_(1.0), | 75 resample_ratio_(1.0), |
73 state_(kStateUninitialized), | 76 state_(kStateUninitialized), |
77 slew_volume_(kMaxSlewTimeUpMs, kMaxSlewTimeDownMs), | |
74 volume_multiplier_(1.0f), | 78 volume_multiplier_(1.0f), |
75 queued_frames_(0), | 79 queued_frames_(0), |
76 queued_frames_including_resampler_(0), | 80 queued_frames_including_resampler_(0), |
77 current_buffer_offset_(0), | 81 current_buffer_offset_(0), |
78 max_queued_frames_(kMaxInputQueueUs * input_samples_per_second / | 82 max_queued_frames_(kMaxInputQueueUs * input_samples_per_second / |
79 base::Time::kMicrosecondsPerSecond), | 83 base::Time::kMicrosecondsPerSecond), |
80 fade_frames_remaining_(0), | 84 fade_frames_remaining_(0), |
81 fade_out_frames_total_(0), | 85 fade_out_frames_total_(0), |
82 zeroed_frames_(0), | 86 zeroed_frames_(0), |
83 weak_factory_(this) { | 87 weak_factory_(this) { |
84 LOG(INFO) << "Create " << this; | 88 LOG(INFO) << "Create " << this; |
85 DCHECK(delegate_); | 89 DCHECK(delegate_); |
86 DCHECK(mixer_); | 90 DCHECK(mixer_); |
87 weak_this_ = weak_factory_.GetWeakPtr(); | 91 weak_this_ = weak_factory_.GetWeakPtr(); |
92 slew_volume_.SetSampleRate(input_samples_per_second_); | |
kmackay
2016/09/14 20:48:15
this doesn't seem right. It is initialized correct
jyw
2016/09/15 01:12:15
Done.
| |
88 } | 93 } |
89 | 94 |
90 StreamMixerAlsaInputImpl::~StreamMixerAlsaInputImpl() { | 95 StreamMixerAlsaInputImpl::~StreamMixerAlsaInputImpl() { |
91 LOG(INFO) << "Destroy " << this; | 96 LOG(INFO) << "Destroy " << this; |
92 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); | 97 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); |
93 } | 98 } |
94 | 99 |
95 int StreamMixerAlsaInputImpl::input_samples_per_second() const { | 100 int StreamMixerAlsaInputImpl::input_samples_per_second() const { |
96 return input_samples_per_second_; | 101 return input_samples_per_second_; |
97 } | 102 } |
(...skipping 15 matching lines...) Expand all Loading... | |
113 const MediaPipelineBackendAlsa::RenderingDelay& mixer_rendering_delay) { | 118 const MediaPipelineBackendAlsa::RenderingDelay& mixer_rendering_delay) { |
114 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); | 119 DCHECK(mixer_task_runner_->BelongsToCurrentThread()); |
115 DCHECK(!IsDeleting()); | 120 DCHECK(!IsDeleting()); |
116 if (mixer_->output_samples_per_second() != input_samples_per_second_) { | 121 if (mixer_->output_samples_per_second() != input_samples_per_second_) { |
117 resample_ratio_ = static_cast<double>(input_samples_per_second_) / | 122 resample_ratio_ = static_cast<double>(input_samples_per_second_) / |
118 mixer_->output_samples_per_second(); | 123 mixer_->output_samples_per_second(); |
119 resampler_.reset(new ::media::MultiChannelResampler( | 124 resampler_.reset(new ::media::MultiChannelResampler( |
120 kNumOutputChannels, resample_ratio_, kDefaultReadSize, | 125 kNumOutputChannels, resample_ratio_, kDefaultReadSize, |
121 base::Bind(&StreamMixerAlsaInputImpl::ReadCB, base::Unretained(this)))); | 126 base::Bind(&StreamMixerAlsaInputImpl::ReadCB, base::Unretained(this)))); |
122 resampler_->PrimeWithSilence(); | 127 resampler_->PrimeWithSilence(); |
128 slew_volume_.SetSampleRate(mixer_->output_samples_per_second()); | |
123 } | 129 } |
124 mixer_rendering_delay_ = mixer_rendering_delay; | 130 mixer_rendering_delay_ = mixer_rendering_delay; |
125 fade_out_frames_total_ = NormalFadeFrames(); | 131 fade_out_frames_total_ = NormalFadeFrames(); |
126 fade_frames_remaining_ = NormalFadeFrames(); | 132 fade_frames_remaining_ = NormalFadeFrames(); |
127 } | 133 } |
128 | 134 |
129 void StreamMixerAlsaInputImpl::PreventDelegateCalls() { | 135 void StreamMixerAlsaInputImpl::PreventDelegateCalls() { |
130 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 136 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
131 weak_factory_.InvalidateWeakPtrs(); | 137 weak_factory_.InvalidateWeakPtrs(); |
132 | 138 |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
497 | 503 |
498 void StreamMixerAlsaInputImpl::SetVolumeMultiplier(float multiplier) { | 504 void StreamMixerAlsaInputImpl::SetVolumeMultiplier(float multiplier) { |
499 RUN_ON_MIXER_THREAD(SetVolumeMultiplier, multiplier); | 505 RUN_ON_MIXER_THREAD(SetVolumeMultiplier, multiplier); |
500 LOG(INFO) << this << ": stream volume = " << multiplier; | 506 LOG(INFO) << this << ": stream volume = " << multiplier; |
501 DCHECK(!IsDeleting()); | 507 DCHECK(!IsDeleting()); |
502 if (multiplier > 1.0f) | 508 if (multiplier > 1.0f) |
503 multiplier = 1.0f; | 509 multiplier = 1.0f; |
504 if (multiplier < 0.0f) | 510 if (multiplier < 0.0f) |
505 multiplier = 0.0f; | 511 multiplier = 0.0f; |
506 volume_multiplier_ = multiplier; | 512 volume_multiplier_ = multiplier; |
513 slew_volume_.SetVolume(volume_multiplier_); | |
514 } | |
515 | |
516 bool StreamMixerAlsaInputImpl::VolumeScaleAccumulate(const float* src, | |
517 int frames, | |
518 float* dest) { | |
519 return slew_volume_.ProcessFMAC(src, frames, dest); | |
507 } | 520 } |
508 | 521 |
509 } // namespace media | 522 } // namespace media |
510 } // namespace chromecast | 523 } // namespace chromecast |
OLD | NEW |