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