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 5 #include "media/filters/audio_renderer_algorithm.h" 6 7 #include <algorithm> 8 #include <cmath> 9 10 #include "base/logging.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "media/audio/audio_util.h" 13 #include "media/base/audio_buffer.h" 14 #include "media/base/audio_bus.h" 15 16 namespace media { 17 18 // The starting size in frames for |audio_buffer_|. Previous usage maintained a 19 // queue of 16 AudioBuffers, each of 512 frames. This worked well, so we 20 // maintain this number of frames. 21 static const int kStartingBufferSizeInFrames = 16 * 512; 22 23 // The maximum size in frames for the |audio_buffer_|. Arbitrarily determined. 24 // This number represents 3 seconds of 96kHz/16 bit 7.1 surround sound. 25 static const int kMaxBufferSizeInFrames = 3 * 96000; 26 27 // Duration of audio segments used for crossfading (in seconds). 28 static const double kWindowDuration = 0.08; 29 30 // Duration of crossfade between audio segments (in seconds). 31 static const double kCrossfadeDuration = 0.008; 32 33 // Max/min supported playback rates for fast/slow audio. Audio outside of these 34 // ranges are muted. 35 // Audio at these speeds would sound better under a frequency domain algorithm. 36 static const float kMinPlaybackRate = 0.5f; 37 static const float kMaxPlaybackRate = 4.0f; 38 39 AudioRendererAlgorithm::AudioRendererAlgorithm() 40 : channels_(0), 41 samples_per_second_(0), 42 playback_rate_(0), 43 frames_in_crossfade_(0), 44 index_into_window_(0), 45 crossfade_frame_number_(0), 46 muted_(false), 47 muted_partial_frame_(0), 48 window_size_(0), 49 capacity_(kStartingBufferSizeInFrames) { 50 } 51 52 AudioRendererAlgorithm::~AudioRendererAlgorithm() {} 53 54 void AudioRendererAlgorithm::Initialize(float initial_playback_rate, 55 const AudioParameters& params) { 56 CHECK(params.IsValid()); 57 58 channels_ = params.channels(); 59 samples_per_second_ = params.sample_rate(); 60 SetPlaybackRate(initial_playback_rate); 61 62 window_size_ = samples_per_second_ * kWindowDuration; 63 frames_in_crossfade_ = samples_per_second_ * kCrossfadeDuration; 64 crossfade_buffer_ = AudioBus::Create(channels_, frames_in_crossfade_); 65 } 66 67 int AudioRendererAlgorithm::FillBuffer(AudioBus* dest, int requested_frames) { 68 if (playback_rate_ == 0) 69 return 0; 70 71 // Optimize the |muted_| case to issue a single clear instead of performing 72 // the full crossfade and clearing each crossfaded frame. 73 if (muted_) { 74 int frames_to_render = 75 std::min(static_cast<int>(audio_buffer_.frames() / playback_rate_), 76 requested_frames); 77 78 // Compute accurate number of frames to actually skip in the source data. 79 // Includes the leftover partial frame from last request. However, we can 80 // only skip over complete frames, so a partial frame may remain for next 81 // time. 82 muted_partial_frame_ += frames_to_render * playback_rate_; 83 int seek_frames = static_cast<int>(muted_partial_frame_); 84 dest->ZeroFrames(frames_to_render); 85 audio_buffer_.SeekFrames(seek_frames); 86 87 // Determine the partial frame that remains to be skipped for next call. If 88 // the user switches back to playing, it may be off time by this partial 89 // frame, which would be undetectable. If they subsequently switch to 90 // another playback rate that mutes, the code will attempt to line up the 91 // frames again. 92 muted_partial_frame_ -= seek_frames; 93 return frames_to_render; 94 } 95 96 int slower_step = ceil(window_size_ * playback_rate_); 97 int faster_step = ceil(window_size_ / playback_rate_); 98 99 // Optimize the most common |playback_rate_| ~= 1 case to use a single copy 100 // instead of copying frame by frame. 101 if (window_size_ <= faster_step && slower_step >= window_size_) { 102 const int frames_to_copy = 103 std::min(audio_buffer_.frames(), requested_frames); 104 const int frames_read = audio_buffer_.ReadFrames(frames_to_copy, 0, dest); 105 DCHECK_EQ(frames_read, frames_to_copy); 106 return frames_read; 107 } 108 109 int total_frames_rendered = 0; 110 while (total_frames_rendered < requested_frames) { 111 if (index_into_window_ >= window_size_) 112 ResetWindow(); 113 114 int rendered_frames = 0; 115 if (window_size_ > faster_step) { 116 rendered_frames = 117 OutputFasterPlayback(dest, 118 total_frames_rendered, 119 requested_frames - total_frames_rendered, 120 window_size_, 121 faster_step); 122 } else if (slower_step < window_size_) { 123 rendered_frames = 124 OutputSlowerPlayback(dest, 125 total_frames_rendered, 126 requested_frames - total_frames_rendered, 127 slower_step, 128 window_size_); 129 } else { 130 NOTREACHED(); 131 } 132 133 if (rendered_frames == 0) 134 break; 135 136 total_frames_rendered += rendered_frames; 137 } 138 return total_frames_rendered; 139 } 140 141 void AudioRendererAlgorithm::ResetWindow() { 142 DCHECK_LE(index_into_window_, window_size_); 143 index_into_window_ = 0; 144 crossfade_frame_number_ = 0; 145 } 146 147 int AudioRendererAlgorithm::OutputFasterPlayback(AudioBus* dest, 148 int dest_offset, 149 int requested_frames, 150 int input_step, 151 int output_step) { 152 // Ensure we don't run into OOB read/write situation. 153 CHECK_GT(input_step, output_step); 154 DCHECK_LT(index_into_window_, window_size_); 155 DCHECK_GT(playback_rate_, 1.0); 156 DCHECK(!muted_); 157 158 if (audio_buffer_.frames() < 1) 159 return 0; 160 161 // The audio data is output in a series of windows. For sped-up playback, 162 // the window is comprised of the following phases: 163 // 164 // a) Output raw data. 165 // b) Save bytes for crossfade in |crossfade_buffer_|. 166 // c) Drop data. 167 // d) Output crossfaded audio leading up to the next window. 168 // 169 // The duration of each phase is computed below based on the |window_size_| 170 // and |playback_rate_|. 171 DCHECK_LE(frames_in_crossfade_, output_step); 172 173 // This is the index of the end of phase a, beginning of phase b. 174 int outtro_crossfade_begin = output_step - frames_in_crossfade_; 175 176 // This is the index of the end of phase b, beginning of phase c. 177 int outtro_crossfade_end = output_step; 178 179 // This is the index of the end of phase c, beginning of phase d. 180 // This phase continues until |index_into_window_| reaches |window_size_|, at 181 // which point the window restarts. 182 int intro_crossfade_begin = input_step - frames_in_crossfade_; 183 184 // a) Output raw frames if we haven't reached the crossfade section. 185 if (index_into_window_ < outtro_crossfade_begin) { 186 // Read as many frames as we can and return the count. If it's not enough, 187 // we will get called again. 188 const int frames_to_copy = 189 std::min(requested_frames, outtro_crossfade_begin - index_into_window_); 190 int copied = audio_buffer_.ReadFrames(frames_to_copy, dest_offset, dest); 191 index_into_window_ += copied; 192 return copied; 193 } 194 195 // b) Save outtro crossfade frames into intermediate buffer, but do not output 196 // anything to |dest|. 197 if (index_into_window_ < outtro_crossfade_end) { 198 // This phase only applies if there are bytes to crossfade. 199 DCHECK_GT(frames_in_crossfade_, 0); 200 int crossfade_start = index_into_window_ - outtro_crossfade_begin; 201 int crossfade_count = outtro_crossfade_end - index_into_window_; 202 int copied = audio_buffer_.ReadFrames( 203 crossfade_count, crossfade_start, crossfade_buffer_.get()); 204 index_into_window_ += copied; 205 206 // Did we get all the frames we need? If not, return and let subsequent 207 // calls try to get the rest. 208 if (copied != crossfade_count) 209 return 0; 210 } 211 212 // c) Drop frames until we reach the intro crossfade section. 213 if (index_into_window_ < intro_crossfade_begin) { 214 // Check if there is enough data to skip all the frames needed. If not, 215 // return 0 and let subsequent calls try to skip it all. 216 int seek_frames = intro_crossfade_begin - index_into_window_; 217 if (audio_buffer_.frames() < seek_frames) 218 return 0; 219 audio_buffer_.SeekFrames(seek_frames); 220 221 // We've dropped all the frames that need to be dropped. 222 index_into_window_ += seek_frames; 223 } 224 225 // d) Crossfade and output a frame, as long as we have data. 226 if (audio_buffer_.frames() < 1) 227 return 0; 228 DCHECK_GT(frames_in_crossfade_, 0); 229 DCHECK_LT(index_into_window_, window_size_); 230 231 int offset_into_buffer = index_into_window_ - intro_crossfade_begin; 232 int copied = audio_buffer_.ReadFrames(1, dest_offset, dest); 233 DCHECK_EQ(copied, 1); 234 CrossfadeFrame(crossfade_buffer_.get(), 235 offset_into_buffer, 236 dest, 237 dest_offset, 238 offset_into_buffer); 239 index_into_window_ += copied; 240 return copied; 241 } 242 243 int AudioRendererAlgorithm::OutputSlowerPlayback(AudioBus* dest, 244 int dest_offset, 245 int requested_frames, 246 int input_step, 247 int output_step) { 248 // Ensure we don't run into OOB read/write situation. 249 CHECK_LT(input_step, output_step); 250 DCHECK_LT(index_into_window_, window_size_); 251 DCHECK_LT(playback_rate_, 1.0); 252 DCHECK_NE(playback_rate_, 0); 253 DCHECK(!muted_); 254 255 if (audio_buffer_.frames() < 1) 256 return 0; 257 258 // The audio data is output in a series of windows. For slowed down playback, 259 // the window is comprised of the following phases: 260 // 261 // a) Output raw data. 262 // b) Output and save bytes for crossfade in |crossfade_buffer_|. 263 // c) Output* raw data. 264 // d) Output* crossfaded audio leading up to the next window. 265 // 266 // * Phases c) and d) do not progress |audio_buffer_|'s cursor so that the 267 // |audio_buffer_|'s cursor is in the correct place for the next window. 268 // 269 // The duration of each phase is computed below based on the |window_size_| 270 // and |playback_rate_|. 271 DCHECK_LE(frames_in_crossfade_, input_step); 272 273 // This is the index of the end of phase a, beginning of phase b. 274 int intro_crossfade_begin = input_step - frames_in_crossfade_; 275 276 // This is the index of the end of phase b, beginning of phase c. 277 int intro_crossfade_end = input_step; 278 279 // This is the index of the end of phase c, beginning of phase d. 280 // This phase continues until |index_into_window_| reaches |window_size_|, at 281 // which point the window restarts. 282 int outtro_crossfade_begin = output_step - frames_in_crossfade_; 283 284 // a) Output raw frames. 285 if (index_into_window_ < intro_crossfade_begin) { 286 // Read as many frames as we can and return the count. If it's not enough, 287 // we will get called again. 288 const int frames_to_copy = 289 std::min(requested_frames, intro_crossfade_begin - index_into_window_); 290 int copied = audio_buffer_.ReadFrames(frames_to_copy, dest_offset, dest); 291 index_into_window_ += copied; 292 return copied; 293 } 294 295 // b) Save the raw frames for the intro crossfade section, then copy the 296 // same frames to |dest|. 297 if (index_into_window_ < intro_crossfade_end) { 298 const int frames_to_copy = 299 std::min(requested_frames, intro_crossfade_end - index_into_window_); 300 int offset = index_into_window_ - intro_crossfade_begin; 301 int copied = audio_buffer_.ReadFrames( 302 frames_to_copy, offset, crossfade_buffer_.get()); 303 crossfade_buffer_->CopyPartialFramesTo(offset, copied, dest_offset, dest); 304 index_into_window_ += copied; 305 return copied; 306 } 307 308 // c) Output a raw frame into |dest| without advancing the |audio_buffer_| 309 // cursor. 310 int audio_buffer_offset = index_into_window_ - intro_crossfade_end; 311 DCHECK_GE(audio_buffer_offset, 0); 312 if (audio_buffer_.frames() <= audio_buffer_offset) 313 return 0; 314 int copied = 315 audio_buffer_.PeekFrames(1, audio_buffer_offset, dest_offset, dest); 316 DCHECK_EQ(1, copied); 317 318 // d) Crossfade the next frame of |crossfade_buffer_| into |dest| if we've 319 // reached the outtro crossfade section of the window. 320 if (index_into_window_ >= outtro_crossfade_begin) { 321 int offset_into_crossfade_buffer = 322 index_into_window_ - outtro_crossfade_begin; 323 CrossfadeFrame(dest, 324 dest_offset, 325 crossfade_buffer_.get(), 326 offset_into_crossfade_buffer, 327 offset_into_crossfade_buffer); 328 } 329 330 index_into_window_ += copied; 331 return copied; 332 } 333 334 void AudioRendererAlgorithm::CrossfadeFrame(AudioBus* intro, 335 int intro_offset, 336 AudioBus* outtro, 337 int outtro_offset, 338 int fade_offset) { 339 float crossfade_ratio = 340 static_cast<float>(fade_offset) / frames_in_crossfade_; 341 for (int channel = 0; channel < channels_; ++channel) { 342 outtro->channel(channel)[outtro_offset] = 343 (1.0f - crossfade_ratio) * intro->channel(channel)[intro_offset] + 344 (crossfade_ratio) * outtro->channel(channel)[outtro_offset]; 345 } 346 } 347 348 void AudioRendererAlgorithm::SetPlaybackRate(float new_rate) { 349 DCHECK_GE(new_rate, 0); 350 playback_rate_ = new_rate; 351 muted_ = 352 playback_rate_ < kMinPlaybackRate || playback_rate_ > kMaxPlaybackRate; 353 354 ResetWindow(); 355 } 356 357 void AudioRendererAlgorithm::FlushBuffers() { 358 ResetWindow(); 359 360 // Clear the queue of decoded packets (releasing the buffers). 361 audio_buffer_.Clear(); 362 } 363 364 base::TimeDelta AudioRendererAlgorithm::GetTime() { 365 return audio_buffer_.current_time(); 366 } 367 368 void AudioRendererAlgorithm::EnqueueBuffer( 369 const scoped_refptr<AudioBuffer>& buffer_in) { 370 DCHECK(!buffer_in->end_of_stream()); 371 audio_buffer_.Append(buffer_in); 372 } 373 374 bool AudioRendererAlgorithm::IsQueueFull() { 375 return audio_buffer_.frames() >= capacity_; 376 } 377 378 void AudioRendererAlgorithm::IncreaseQueueCapacity() { 379 capacity_ = std::min(2 * capacity_, kMaxBufferSizeInFrames); 380 } 381 382 } // namespace media 383