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

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: Gotta catch'em all! 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
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, 67 int number_of_frames,
73 int audio_delay_milliseconds) { 68 int audio_delay_milliseconds) {
74 current_audio_delay_milliseconds_ = audio_delay_milliseconds; 69 current_audio_delay_milliseconds_ = audio_delay_milliseconds;
75 70
76 if (resampler_.get()) 71 if (resampler_.get())
77 resampler_->Resample(audio_data, number_of_frames); 72 resampler_->Resample(audio_bus, number_of_frames);
78 else 73 else
79 ProvideInput(audio_data, number_of_frames); 74 ProvideInput(audio_bus, number_of_frames);
80 75
81 // Always return the full number of frames requested, ProvideInput() will pad 76 // Always return the full number of frames requested, ProvideInput() will pad
82 // with silence if it wasn't able to acquire enough data. 77 // with silence if it wasn't able to acquire enough data.
83 return number_of_frames; 78 return number_of_frames;
84 } 79 }
85 80
86 void AudioRendererMixer::ProvideInput(const std::vector<float*>& audio_data, 81 void AudioRendererMixer::ProvideInput(AudioBus* audio_bus,
87 int number_of_frames) { 82 int number_of_frames) {
88 base::AutoLock auto_lock(mixer_inputs_lock_); 83 base::AutoLock auto_lock(mixer_inputs_lock_);
89 84
90 // Allocate staging area for each mixer input's audio data on first call. We 85 // 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. 86 // won't know how much to allocate until here because of resampling.
92 if (mixer_input_audio_data_.size() == 0) { 87 if (!mixer_input_audio_bus_.get()) {
93 mixer_input_audio_data_.reserve(audio_data.size()); 88 mixer_input_audio_bus_ =
94 for (size_t i = 0; i < audio_data.size(); ++i) { 89 AudioBus::Create(audio_bus->channels(), number_of_frames);
95 // Allocate audio data with a 16-byte alignment for SSE optimizations.
96 mixer_input_audio_data_.push_back(static_cast<float*>(
97 base::AlignedAlloc(sizeof(float) * number_of_frames, 16)));
98 }
99 mixer_input_audio_data_size_ = number_of_frames;
100 } 90 }
101 91
102 // Sanity check our inputs. 92 // Sanity check our inputs.
103 DCHECK_LE(number_of_frames, mixer_input_audio_data_size_); 93 DCHECK_LE(number_of_frames, audio_bus->frames());
104 DCHECK_EQ(audio_data.size(), mixer_input_audio_data_.size()); 94 DCHECK_LE(number_of_frames, mixer_input_audio_bus_->frames());
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->ZeroFrames(number_of_frames);
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(), number_of_frames,
125 current_audio_delay_milliseconds_); 115 current_audio_delay_milliseconds_);
126 if (frames_filled == 0) 116 if (frames_filled == 0)
127 continue; 117 continue;
128 118
129 // Volume adjust and mix each mixer input into |audio_data| after rendering. 119 // Volume adjust and mix each mixer input into |audio_bus| after rendering.
130 for (size_t j = 0; j < audio_data.size(); ++j) { 120 for (int i = 0; i < audio_bus->channels(); ++i) {
131 VectorFMAC( 121 VectorFMAC(mixer_input_audio_bus_->channel(i), volume, frames_filled,
132 mixer_input_audio_data_[j], volume, frames_filled, audio_data[j]); 122 audio_bus->channel(i));
133 } 123 }
134 124
135 // No need to clamp values as InterleaveFloatToInt() will take care of this 125 // No need to clamp values as InterleaveFloatToInt() will take care of this
136 // for us later when data is transferred to the browser process. 126 // for us later when data is transferred to the browser process.
137 } 127 }
138 } 128 }
139 129
140 void AudioRendererMixer::OnRenderError() { 130 void AudioRendererMixer::OnRenderError() {
141 base::AutoLock auto_lock(mixer_inputs_lock_); 131 base::AutoLock auto_lock(mixer_inputs_lock_);
142 132
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 _mm_mul_ps(_mm_load_ps(src + i), m_scale))); 173 _mm_mul_ps(_mm_load_ps(src + i), m_scale)));
184 } 174 }
185 175
186 // Handle any remaining values that wouldn't fit in an SSE pass. 176 // Handle any remaining values that wouldn't fit in an SSE pass.
187 if (rem) 177 if (rem)
188 VectorFMAC_C(src + len - rem, scale, rem, dest + len - rem); 178 VectorFMAC_C(src + len - rem, scale, rem, dest + len - rem);
189 } 179 }
190 #endif 180 #endif
191 181
192 } // namespace media 182 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698