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 // AudioRendererAlgorithm buffers and transforms audio data. The owner of
      6 // this object provides audio data to the object through EnqueueBuffer() and
      7 // requests data from the buffer via FillBuffer(). The owner also sets the
      8 // playback rate, and the AudioRendererAlgorithm will stretch or compress the
      9 // buffered audio as necessary to match the playback rate when fulfilling
     10 // FillBuffer() requests.
     11 //
     12 // This class is *not* thread-safe. Calls to enqueue and retrieve data must be
     13 // locked if called from multiple threads.
     14 //
     15 // AudioRendererAlgorithm uses a simple pitch-preservation algorithm to
     16 // stretch and compress audio data to meet playback speeds less than and
     17 // greater than the natural playback of the audio stream.
     18 //
     19 // Audio at very low or very high playback rates are muted to preserve quality.
     20 
     21 #ifndef MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_H_
     22 #define MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_H_
     23 
     24 #include "base/memory/ref_counted.h"
     25 #include "base/memory/scoped_ptr.h"
     26 #include "media/audio/audio_parameters.h"
     27 #include "media/base/audio_buffer.h"
     28 #include "media/base/audio_buffer_queue.h"
     29 
     30 namespace media {
     31 
     32 class AudioBus;
     33 
     34 class MEDIA_EXPORT AudioRendererAlgorithm {
     35  public:
     36   AudioRendererAlgorithm();
     37   ~AudioRendererAlgorithm();
     38 
     39   // Initializes this object with information about the audio stream.
     40   void Initialize(float initial_playback_rate, const AudioParameters& params);
     41 
     42   // Tries to fill |requested_frames| frames into |dest| with possibly scaled
     43   // data from our |audio_buffer_|. Data is scaled based on the playback rate,
     44   // using a variation of the Overlap-Add method to combine sample windows.
     45   //
     46   // Data from |audio_buffer_| is consumed in proportion to the playback rate.
     47   //
     48   // Returns the number of frames copied into |dest|. May request more reads via
     49   // |request_read_cb_| before returning.
     50   int FillBuffer(AudioBus* dest, int requested_frames);
     51 
     52   // Clears |audio_buffer_|.
     53   void FlushBuffers();
     54 
     55   // Returns the time of the next byte in our data or kNoTimestamp() if current
     56   // time is unknown.
     57   base::TimeDelta GetTime();
     58 
     59   // Enqueues a buffer. It is called from the owner of the algorithm after a
     60   // read completes.
     61   void EnqueueBuffer(const scoped_refptr<AudioBuffer>& buffer_in);
     62 
     63   float playback_rate() const { return playback_rate_; }
     64   void SetPlaybackRate(float new_rate);
     65 
     66   // Returns true if |audio_buffer_| is at or exceeds capacity.
     67   bool IsQueueFull();
     68 
     69   // Returns the capacity of |audio_buffer_| in frames.
     70   int QueueCapacity() const { return capacity_; }
     71 
     72   // Increase the capacity of |audio_buffer_| if possible.
     73   void IncreaseQueueCapacity();
     74 
     75   // Returns the number of frames left in |audio_buffer_|, which may be larger
     76   // than QueueCapacity() in the event that EnqueueBuffer() delivered more data
     77   // than |audio_buffer_| was intending to hold.
     78   int frames_buffered() { return audio_buffer_.frames(); }
     79 
     80   // Returns the samples per second for this audio stream.
     81   int samples_per_second() { return samples_per_second_; }
     82 
     83   // Is the sound currently muted?
     84   bool is_muted() { return muted_; }
     85 
     86  private:
     87   // Fills |dest| with up to |requested_frames| frames of audio data at faster
     88   // than normal speed. Returns the number of frames inserted into |dest|. If
     89   // not enough data available, returns 0.
     90   //
     91   // When the audio playback is > 1.0, we use a variant of Overlap-Add to squish
     92   // audio output while preserving pitch. Essentially, we play a bit of audio
     93   // data at normal speed, then we "fast forward" by dropping the next bit of
     94   // audio data, and then we stich the pieces together by crossfading from one
     95   // audio chunk to the next.
     96   int OutputFasterPlayback(AudioBus* dest,
     97                            int dest_offset,
     98                            int requested_frames,
     99                            int input_step,
    100                            int output_step);
    101 
    102   // Fills |dest| with up to |requested_frames| frames of audio data at slower
    103   // than normal speed. Returns the number of frames inserted into |dest|. If
    104   // not enough data available, returns 0.
    105   //
    106   // When the audio playback is < 1.0, we use a variant of Overlap-Add to
    107   // stretch audio output while preserving pitch. This works by outputting a
    108   // segment of audio data at normal speed. The next audio segment then starts
    109   // by repeating some of the audio data from the previous audio segment.
    110   // Segments are stiched together by crossfading from one audio chunk to the
    111   // next.
    112   int OutputSlowerPlayback(AudioBus* dest,
    113                            int dest_offset,
    114                            int requested_frames,
    115                            int input_step,
    116                            int output_step);
    117 
    118   // Resets the window state to the start of a new window.
    119   void ResetWindow();
    120 
    121   // Does a linear crossfade from |intro| into |outtro| for one frame.
    122   void CrossfadeFrame(AudioBus* intro,
    123                       int intro_offset,
    124                       AudioBus* outtro,
    125                       int outtro_offset,
    126                       int fade_offset);
    127 
    128   // Number of channels in audio stream.
    129   int channels_;
    130 
    131   // Sample rate of audio stream.
    132   int samples_per_second_;
    133 
    134   // Used by algorithm to scale output.
    135   float playback_rate_;
    136 
    137   // Buffered audio data.
    138   AudioBufferQueue audio_buffer_;
    139 
    140   // Length for crossfade in frames.
    141   int frames_in_crossfade_;
    142 
    143   // The current location in the audio window, between 0 and |window_size_|.
    144   // When |index_into_window_| reaches |window_size_|, the window resets.
    145   // Indexed by frame.
    146   int index_into_window_;
    147 
    148   // The frame number in the crossfade.
    149   int crossfade_frame_number_;
    150 
    151   // True if the audio should be muted.
    152   bool muted_;
    153 
    154   // If muted, keep track of partial frames that should have been skipped over.
    155   double muted_partial_frame_;
    156 
    157   // Temporary buffer to hold crossfade data.
    158   scoped_ptr<AudioBus> crossfade_buffer_;
    159 
    160   // Window size, in frames (calculated from audio properties).
    161   int window_size_;
    162 
    163   // How many frames to have in the queue before we report the queue is full.
    164   int capacity_;
    165 
    166   DISALLOW_COPY_AND_ASSIGN(AudioRendererAlgorithm);
    167 };
    168 
    169 }  // namespace media
    170 
    171 #endif  // MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_H_
    172