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

Side by Side Diff: media/base/audio_renderer_mixer.cc

Issue 10823175: Switch AudioRenderSink::Callback to use AudioBus. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup MCR AudioBus usage. Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « media/base/audio_renderer_mixer.h ('k') | media/base/audio_renderer_mixer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "media/base/audio_renderer_mixer.h" 5 #include "media/base/audio_renderer_mixer.h"
6 6
7 #if defined(ARCH_CPU_X86_FAMILY) && defined(__SSE__) 7 #if defined(ARCH_CPU_X86_FAMILY) && defined(__SSE__)
8 #include <xmmintrin.h> 8 #include <xmmintrin.h>
9 #endif 9 #endif
10 10
(...skipping 28 matching lines...) Expand all
39 } 39 }
40 40
41 audio_sink_->Initialize(output_params, this); 41 audio_sink_->Initialize(output_params, this);
42 audio_sink_->Start(); 42 audio_sink_->Start();
43 } 43 }
44 44
45 AudioRendererMixer::~AudioRendererMixer() { 45 AudioRendererMixer::~AudioRendererMixer() {
46 // AudioRendererSinks must be stopped before being destructed. 46 // AudioRendererSinks must be stopped before being destructed.
47 audio_sink_->Stop(); 47 audio_sink_->Stop();
48 48
49 // Clean up |mixer_input_audio_data_|.
50 for (size_t i = 0; i < mixer_input_audio_data_.size(); ++i)
51 base::AlignedFree(mixer_input_audio_data_[i]);
52 mixer_input_audio_data_.clear();
53
54 // Ensures that all mixer inputs have stopped themselves prior to destruction 49 // Ensures that all mixer inputs have stopped themselves prior to destruction
55 // and have called RemoveMixerInput(). 50 // and have called RemoveMixerInput().
56 DCHECK_EQ(mixer_inputs_.size(), 0U); 51 DCHECK_EQ(mixer_inputs_.size(), 0U);
57 } 52 }
58 53
59 void AudioRendererMixer::AddMixerInput( 54 void AudioRendererMixer::AddMixerInput(
60 const scoped_refptr<AudioRendererMixerInput>& input) { 55 const scoped_refptr<AudioRendererMixerInput>& input) {
61 base::AutoLock auto_lock(mixer_inputs_lock_); 56 base::AutoLock auto_lock(mixer_inputs_lock_);
62 mixer_inputs_.insert(input); 57 mixer_inputs_.insert(input);
63 } 58 }
64 59
65 void AudioRendererMixer::RemoveMixerInput( 60 void AudioRendererMixer::RemoveMixerInput(
66 const scoped_refptr<AudioRendererMixerInput>& input) { 61 const scoped_refptr<AudioRendererMixerInput>& input) {
67 base::AutoLock auto_lock(mixer_inputs_lock_); 62 base::AutoLock auto_lock(mixer_inputs_lock_);
68 mixer_inputs_.erase(input); 63 mixer_inputs_.erase(input);
69 } 64 }
70 65
71 int AudioRendererMixer::Render(const std::vector<float*>& audio_data, 66 int AudioRendererMixer::Render(AudioBus* audio_bus,
72 int number_of_frames,
73 int audio_delay_milliseconds) { 67 int audio_delay_milliseconds) {
74 current_audio_delay_milliseconds_ = audio_delay_milliseconds; 68 current_audio_delay_milliseconds_ = audio_delay_milliseconds;
75 69
76 if (resampler_.get()) 70 if (resampler_.get())
77 resampler_->Resample(audio_data, number_of_frames); 71 resampler_->Resample(audio_bus, audio_bus->frames());
78 else 72 else
79 ProvideInput(audio_data, number_of_frames); 73 ProvideInput(audio_bus);
80 74
81 // Always return the full number of frames requested, ProvideInput() will pad 75 // Always return the full number of frames requested, ProvideInput() will pad
82 // with silence if it wasn't able to acquire enough data. 76 // with silence if it wasn't able to acquire enough data.
83 return number_of_frames; 77 return audio_bus->frames();
84 } 78 }
85 79
86 void AudioRendererMixer::ProvideInput(const std::vector<float*>& audio_data, 80 void AudioRendererMixer::ProvideInput(AudioBus* audio_bus) {
87 int number_of_frames) {
88 base::AutoLock auto_lock(mixer_inputs_lock_); 81 base::AutoLock auto_lock(mixer_inputs_lock_);
89 82
90 // Allocate staging area for each mixer input's audio data on first call. We 83 // Allocate staging area for each mixer input's audio data on first call. We
91 // won't know how much to allocate until here because of resampling. 84 // won't know how much to allocate until here because of resampling. Ensure
92 if (mixer_input_audio_data_.size() == 0) { 85 // our intermediate AudioBus is sized exactly as the original. Resize should
93 mixer_input_audio_data_.reserve(audio_data.size()); 86 // only happen once due to the way the resampler works.
94 for (size_t i = 0; i < audio_data.size(); ++i) { 87 if (!mixer_input_audio_bus_.get() ||
95 // Allocate audio data with a 16-byte alignment for SSE optimizations. 88 mixer_input_audio_bus_->frames() != audio_bus->frames()) {
96 mixer_input_audio_data_.push_back(static_cast<float*>( 89 mixer_input_audio_bus_ =
97 base::AlignedAlloc(sizeof(float) * number_of_frames, 16))); 90 AudioBus::Create(audio_bus->channels(), audio_bus->frames());
98 }
99 mixer_input_audio_data_size_ = number_of_frames;
100 } 91 }
101 92
102 // Sanity check our inputs. 93 // Sanity check our inputs.
103 DCHECK_LE(number_of_frames, mixer_input_audio_data_size_); 94 DCHECK_EQ(audio_bus->frames(), mixer_input_audio_bus_->frames());
104 DCHECK_EQ(audio_data.size(), mixer_input_audio_data_.size()); 95 DCHECK_EQ(audio_bus->channels(), mixer_input_audio_bus_->channels());
105 96
106 // Zero |audio_data| so we're mixing into a clean buffer and return silence if 97 // Zero |audio_bus| so we're mixing into a clean buffer and return silence if
107 // we couldn't get enough data from our inputs. 98 // we couldn't get enough data from our inputs.
108 for (size_t i = 0; i < audio_data.size(); ++i) 99 audio_bus->Zero();
109 memset(audio_data[i], 0, number_of_frames * sizeof(*audio_data[i]));
110 100
111 // Have each mixer render its data into an output buffer then mix the result. 101 // Have each mixer render its data into an output buffer then mix the result.
112 for (AudioRendererMixerInputSet::iterator it = mixer_inputs_.begin(); 102 for (AudioRendererMixerInputSet::iterator it = mixer_inputs_.begin();
113 it != mixer_inputs_.end(); ++it) { 103 it != mixer_inputs_.end(); ++it) {
114 const scoped_refptr<AudioRendererMixerInput>& input = *it; 104 const scoped_refptr<AudioRendererMixerInput>& input = *it;
115 105
116 double volume; 106 double volume;
117 input->GetVolume(&volume); 107 input->GetVolume(&volume);
118 108
119 // Nothing to do if the input isn't playing. 109 // Nothing to do if the input isn't playing.
120 if (!input->playing()) 110 if (!input->playing())
121 continue; 111 continue;
122 112
123 int frames_filled = input->callback()->Render( 113 int frames_filled = input->callback()->Render(
124 mixer_input_audio_data_, number_of_frames, 114 mixer_input_audio_bus_.get(), current_audio_delay_milliseconds_);
125 current_audio_delay_milliseconds_);
126 if (frames_filled == 0) 115 if (frames_filled == 0)
127 continue; 116 continue;
128 117
129 // Volume adjust and mix each mixer input into |audio_data| after rendering. 118 // Volume adjust and mix each mixer input into |audio_bus| after rendering.
130 for (size_t j = 0; j < audio_data.size(); ++j) { 119 for (int i = 0; i < audio_bus->channels(); ++i) {
131 VectorFMAC( 120 VectorFMAC(mixer_input_audio_bus_->channel(i), volume, frames_filled,
132 mixer_input_audio_data_[j], volume, frames_filled, audio_data[j]); 121 audio_bus->channel(i));
133 } 122 }
134 123
135 // No need to clamp values as InterleaveFloatToInt() will take care of this 124 // No need to clamp values as InterleaveFloatToInt() will take care of this
136 // for us later when data is transferred to the browser process. 125 // for us later when data is transferred to the browser process.
137 } 126 }
138 } 127 }
139 128
140 void AudioRendererMixer::OnRenderError() { 129 void AudioRendererMixer::OnRenderError() {
141 base::AutoLock auto_lock(mixer_inputs_lock_); 130 base::AutoLock auto_lock(mixer_inputs_lock_);
142 131
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 _mm_mul_ps(_mm_load_ps(src + i), m_scale))); 172 _mm_mul_ps(_mm_load_ps(src + i), m_scale)));
184 } 173 }
185 174
186 // Handle any remaining values that wouldn't fit in an SSE pass. 175 // Handle any remaining values that wouldn't fit in an SSE pass.
187 if (rem) 176 if (rem)
188 VectorFMAC_C(src + len - rem, scale, rem, dest + len - rem); 177 VectorFMAC_C(src + len - rem, scale, rem, dest + len - rem);
189 } 178 }
190 #endif 179 #endif
191 180
192 } // namespace media 181 } // namespace media
OLDNEW
« no previous file with comments | « media/base/audio_renderer_mixer.h ('k') | media/base/audio_renderer_mixer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698