Home | History | Annotate | Download | only in filters
      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