Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 // AudioRendererAlgorithmBase buffers and transforms audio data. The owner of | 5 // AudioRendererAlgorithmBase buffers and transforms audio data. The owner of |
| 6 // this object provides audio data to the object through EnqueueBuffer() and | 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 | 7 // requests data from the buffer via FillBuffer(). The owner also sets the |
| 8 // playback rate, and the AudioRendererAlgorithm will stretch or compress the | 8 // playback rate, and the AudioRendererAlgorithm will stretch or compress the |
| 9 // buffered audio as necessary to match the playback rate when fulfilling | 9 // buffered audio as necessary to match the playback rate when fulfilling |
| 10 // FillBuffer() requests. AudioRendererAlgorithm can request more data to be | 10 // FillBuffer() requests. AudioRendererAlgorithm can request more data to be |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 // Initializes this object with information about the audio stream. | 44 // Initializes this object with information about the audio stream. |
| 45 // |samples_per_second| is in Hz. |read_request_callback| is called to | 45 // |samples_per_second| is in Hz. |read_request_callback| is called to |
| 46 // request more data from the client, requests that are fulfilled through | 46 // request more data from the client, requests that are fulfilled through |
| 47 // calls to EnqueueBuffer(). | 47 // calls to EnqueueBuffer(). |
| 48 void Initialize(int channels, | 48 void Initialize(int channels, |
| 49 int samples_per_second, | 49 int samples_per_second, |
| 50 int bits_per_channel, | 50 int bits_per_channel, |
| 51 float initial_playback_rate, | 51 float initial_playback_rate, |
| 52 const base::Closure& request_read_cb); | 52 const base::Closure& request_read_cb); |
| 53 | 53 |
| 54 // Tries to fill |length| bytes of |dest| with possibly scaled data from our | 54 // Tries to fill |requested_frames| frames into |dest| with possibly scaled |
| 55 // |audio_buffer_|. Data is scaled based on the playback rate, using a | 55 // data from our |audio_buffer_|. Data is scaled based on the playback rate, |
| 56 // variation of the Overlap-Add method to combine sample windows. | 56 // using a variation of the Overlap-Add method to combine sample windows. |
| 57 // | 57 // |
| 58 // Data from |audio_buffer_| is consumed in proportion to the playback rate. | 58 // Data from |audio_buffer_| is consumed in proportion to the playback rate. |
| 59 // FillBuffer() will fit |playback_rate_| * |length| bytes of raw data from | |
| 60 // |audio_buffer| into |length| bytes of output data in |dest| by chopping up | |
| 61 // the buffered data into windows and crossfading from one window to the next. | |
| 62 // For speeds greater than 1.0f, FillBuffer() "squish" the windows, dropping | |
| 63 // some data in between windows to meet the sped-up playback. For speeds less | |
| 64 // than 1.0f, FillBuffer() will "stretch" the window by copying and | |
| 65 // overlapping data at the window boundaries, crossfading in between. | |
| 66 // | 59 // |
| 67 // Returns the number of bytes copied into |dest|. | 60 // Returns the number of frames copied into |dest|. |
| 68 // May request more reads via |request_read_cb_| before returning. | 61 // May request more reads via |request_read_cb_| before returning. |
| 69 uint32 FillBuffer(uint8* dest, uint32 length); | 62 uint32 FillBuffer(uint8* dest, uint32 requested_frames); |
| 70 | 63 |
| 71 // Clears |audio_buffer_|. | 64 // Clears |audio_buffer_|. |
| 72 void FlushBuffers(); | 65 void FlushBuffers(); |
| 73 | 66 |
| 74 // Returns the time of the next byte in our data or kNoTimestamp() if current | 67 // Returns the time of the next byte in our data or kNoTimestamp() if current |
| 75 // time is unknown. | 68 // time is unknown. |
| 76 base::TimeDelta GetTime(); | 69 base::TimeDelta GetTime(); |
| 77 | 70 |
| 78 // Enqueues a buffer. It is called from the owner of the algorithm after a | 71 // Enqueues a buffer. It is called from the owner of the algorithm after a |
| 79 // read completes. | 72 // read completes. |
| 80 void EnqueueBuffer(Buffer* buffer_in); | 73 void EnqueueBuffer(Buffer* buffer_in); |
| 81 | 74 |
| 82 float playback_rate() const { return playback_rate_; } | 75 float playback_rate() const { return playback_rate_; } |
| 83 void SetPlaybackRate(float new_rate); | 76 void SetPlaybackRate(float new_rate); |
| 84 | 77 |
| 85 // Returns whether |audio_buffer_| is empty. | 78 // Returns whether the algorithm needs more data to continue filling buffers. |
| 79 bool NeedsMoreData(); | |
| 80 | |
| 81 // Returns true if |audio_buffer_| is empty. | |
| 86 bool IsQueueEmpty(); | 82 bool IsQueueEmpty(); |
| 87 | 83 |
| 88 // Returns true if |audio_buffer_| is at or exceeds capacity. | 84 // Returns true if |audio_buffer_| is at or exceeds capacity. |
| 89 bool IsQueueFull(); | 85 bool IsQueueFull(); |
| 90 | 86 |
| 91 // Returns the capacity of |audio_buffer_|. | 87 // Returns the capacity of |audio_buffer_|. |
| 92 uint32 QueueCapacity(); | 88 uint32 QueueCapacity(); |
| 93 | 89 |
| 94 // Increase the capacity of |audio_buffer_| if possible. | 90 // Increase the capacity of |audio_buffer_| if possible. |
| 95 void IncreaseQueueCapacity(); | 91 void IncreaseQueueCapacity(); |
| 96 | 92 |
| 97 // Returns the number of bytes left in |audio_buffer_|, which may be larger | 93 // Returns the number of bytes left in |audio_buffer_|, which may be larger |
| 98 // than QueueCapacity() in the event that a read callback delivered more data | 94 // than QueueCapacity() in the event that a read callback delivered more data |
| 99 // than |audio_buffer_| was intending to hold. | 95 // than |audio_buffer_| was intending to hold. |
| 100 uint32 bytes_buffered() { return audio_buffer_.forward_bytes(); } | 96 uint32 bytes_buffered() { return audio_buffer_.forward_bytes(); } |
| 101 | 97 |
| 102 uint32 window_size() { return window_size_; } | 98 uint32 window_size() { return window_size_; } |
| 103 | 99 |
| 104 private: | 100 private: |
| 105 // Advances |audio_buffer_|'s internal pointer by |bytes|. | 101 // Fills |dest| with one frame of audio data at normal speed. Returns true if |
| 106 void AdvanceBufferPosition(uint32 bytes); | 102 // a frame was rendered, false otherwise. |
| 103 bool OutputNormalPlayback(uint8* dest); | |
| 107 | 104 |
| 108 // Tries to copy |bytes| bytes from |audio_buffer_| to |dest|. | 105 // Fills |dest| with one frame of audio data at faster than normal speed. |
| 109 // Returns the number of bytes successfully copied. | 106 // Returns true if a frame was rendered, false otherwise. |
| 110 uint32 CopyFromAudioBuffer(uint8* dest, uint32 bytes); | 107 // |
| 108 // When the audio playback is > 1.0, we use a variant of Overlap-Add to squish | |
| 109 // audio output while preserving pitch. Essentially, we play a bit of audio | |
| 110 // data at normal speed, then we "fast forward" by dropping the next bit of | |
| 111 // audio data, and then we stich the pieces together by crossfading from one | |
| 112 // audio chunk to the next. | |
| 113 bool OutputFasterPlayback(uint8* dest); | |
| 114 | |
| 115 // Fills |dest| with one frame of audio data at slower than normal speed. | |
| 116 // Returns true if a frame was rendered, false otherwise. | |
| 117 // | |
| 118 // When the audio playback is > 1.0, we use a variant of Overlap-Add to | |
|
acolwell GONE FROM CHROMIUM
2012/02/22 07:51:40
is < 1.0 ?
vrk (LEFT CHROMIUM)
2012/02/23 20:33:06
Whoops, yes! Done.
| |
| 119 // stretch audio output while preserving pitch. This works by outputting a | |
| 120 // segment of audio data at normal speed. The next audio segment then starts | |
| 121 // by repeating some of the audio data from the previous audio segment. | |
| 122 // Segments are stiched together by crossfading from one audio chunk to the | |
| 123 // next. | |
| 124 bool OutputSlowerPlayback(uint8* dest); | |
| 125 | |
| 126 // Resets the window state to the start of a new window. | |
| 127 void ResetWindow(); | |
| 128 | |
| 129 // Copies a raw frame from |audio_buffer_| into |dest| without progressing | |
| 130 // |audio_buffer_|'s internal "current" cursor. Optionally peeks at a forward | |
| 131 // byte |offset|. | |
| 132 void PeekRawFrame(uint8* dest); | |
|
acolwell GONE FROM CHROMIUM
2012/02/22 07:51:40
nit: Rename to CopyWithoutAdvance or something sim
vrk (LEFT CHROMIUM)
2012/02/23 20:33:06
Much better name, thanks! Done.
| |
| 133 void PeekRawFrame(uint8* dest, uint32 offset); | |
| 134 | |
| 135 // Copies a raw frame from |audio_buffer_| into |dest| and progresses the | |
| 136 // |audio_buffer_| forward. | |
| 137 void ReadRawFrame(uint8* dest); | |
|
acolwell GONE FROM CHROMIUM
2012/02/22 07:51:40
nit: Rename to CopyWithAdvance to be more descript
vrk (LEFT CHROMIUM)
2012/02/23 20:33:06
Done.
| |
| 138 | |
| 139 // Moves the |audio_buffer_| forward by one frame. | |
| 140 void DropFrame(); | |
| 141 | |
| 142 // Does a linear crossfade from |intro| into |outtro| for one frame. | |
| 143 // Assumes pointers are valid and are at least size of |bytes_per_frame_|. | |
| 144 void OutputCrossfadedFrame(uint8* outtro, const uint8* intro); | |
| 145 template <class Type> | |
| 146 void CrossfadeFrame(Type* outtro, const Type* intro); | |
| 111 | 147 |
| 112 // Aligns |value| to a channel and sample boundary. | 148 // Aligns |value| to a channel and sample boundary. |
|
acolwell GONE FROM CHROMIUM
2012/02/22 07:51:40
nit: How about "Round |*value| down to the nearest
vrk (LEFT CHROMIUM)
2012/02/23 20:33:06
Done.
| |
| 113 void AlignToSampleBoundary(uint32* value); | 149 void AlignToFrameBoundary(uint32* value); |
| 114 | |
| 115 // Attempts to write |length| bytes of muted audio into |dest|. | |
| 116 uint32 MuteBuffer(uint8* dest, uint32 length); | |
| 117 | 150 |
| 118 // Number of channels in audio stream. | 151 // Number of channels in audio stream. |
| 119 int channels_; | 152 int channels_; |
| 120 | 153 |
| 121 // Sample rate of audio stream. | 154 // Sample rate of audio stream. |
| 122 int samples_per_second_; | 155 int samples_per_second_; |
| 123 | 156 |
| 124 // Byte depth of audio. | 157 // Byte depth of audio. |
| 125 int bytes_per_channel_; | 158 int bytes_per_channel_; |
| 126 | 159 |
| 127 // Used by algorithm to scale output. | 160 // Used by algorithm to scale output. |
| 128 float playback_rate_; | 161 float playback_rate_; |
| 129 | 162 |
| 130 // Used to request more data. | 163 // Used to request more data. |
| 131 base::Closure request_read_cb_; | 164 base::Closure request_read_cb_; |
| 132 | 165 |
| 133 // Buffered audio data. | 166 // Buffered audio data. |
| 134 SeekableBuffer audio_buffer_; | 167 SeekableBuffer audio_buffer_; |
| 135 | 168 |
| 136 // Length for crossfade in bytes. | 169 // Length for crossfade in bytes. |
| 137 uint32 crossfade_size_; | 170 uint32 bytes_in_crossfade_; |
| 171 | |
| 172 // Length of frame in bytes. | |
| 173 uint32 bytes_per_frame_; | |
| 174 | |
| 175 // The current location in the audio window, between 0 and |window_size_|. | |
| 176 // When |index_into_window_| reaches |window_size_|, the window resets. | |
| 177 // Indexed by byte. | |
| 178 uint32 index_into_window_; | |
| 179 | |
| 180 // The frame number in the crossfade. | |
| 181 uint32 crossfade_frame_number_; | |
| 182 | |
| 183 // True if the audio should be muted. | |
| 184 bool muted_; | |
| 185 | |
| 186 bool needs_more_data_; | |
| 187 | |
| 188 // Temporary buffer to hold crossfade data. | |
| 189 scoped_array<uint8> crossfade_buffer_; | |
| 138 | 190 |
| 139 // Window size, in bytes (calculated from audio properties). | 191 // Window size, in bytes (calculated from audio properties). |
| 140 uint32 window_size_; | 192 uint32 window_size_; |
| 141 | 193 |
| 142 DISALLOW_COPY_AND_ASSIGN(AudioRendererAlgorithmBase); | 194 DISALLOW_COPY_AND_ASSIGN(AudioRendererAlgorithmBase); |
| 143 }; | 195 }; |
| 144 | 196 |
| 145 } // namespace media | 197 } // namespace media |
| 146 | 198 |
| 147 #endif // MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_BASE_H_ | 199 #endif // MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_BASE_H_ |
| OLD | NEW |