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 10 matching lines...) Expand all Loading... |
21 | 21 |
22 #ifndef MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_BASE_H_ | 22 #ifndef MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_BASE_H_ |
23 #define MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_BASE_H_ | 23 #define MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_BASE_H_ |
24 | 24 |
25 #include "base/callback.h" | 25 #include "base/callback.h" |
26 #include "base/gtest_prod_util.h" | 26 #include "base/gtest_prod_util.h" |
27 #include "media/base/seekable_buffer.h" | 27 #include "media/base/seekable_buffer.h" |
28 | 28 |
29 namespace media { | 29 namespace media { |
30 | 30 |
| 31 // Max/min supported playback rates for fast/slow audio. Audio outside of these |
| 32 // ranges are muted. |
| 33 // Audio at these speeds would sound better under a frequency domain algorithm. |
| 34 const float kMinPlaybackRate = 0.5f; |
| 35 const float kMaxPlaybackRate = 4.0f; |
| 36 |
31 class Buffer; | 37 class Buffer; |
32 | 38 |
| 39 // TODO(vrk): Remove all the uint32s from AudioRendererAlgorithmBase and |
| 40 // replace them with ints. |
33 class MEDIA_EXPORT AudioRendererAlgorithmBase { | 41 class MEDIA_EXPORT AudioRendererAlgorithmBase { |
34 public: | 42 public: |
35 AudioRendererAlgorithmBase(); | 43 AudioRendererAlgorithmBase(); |
36 ~AudioRendererAlgorithmBase(); | 44 ~AudioRendererAlgorithmBase(); |
37 | 45 |
38 // Call prior to Initialize() to validate configuration. Returns false if the | 46 // Call prior to Initialize() to validate configuration. Returns false if the |
39 // configuration is invalid. Detailed error information will be DVLOG'd. | 47 // configuration is invalid. Detailed error information will be DVLOG'd. |
40 static bool ValidateConfig(int channels, | 48 static bool ValidateConfig(int channels, |
41 int samples_per_second, | 49 int samples_per_second, |
42 int bits_per_channel); | 50 int bits_per_channel); |
43 | 51 |
44 // Initializes this object with information about the audio stream. | 52 // Initializes this object with information about the audio stream. |
45 // |samples_per_second| is in Hz. |read_request_callback| is called to | 53 // |samples_per_second| is in Hz. |read_request_callback| is called to |
46 // request more data from the client, requests that are fulfilled through | 54 // request more data from the client, requests that are fulfilled through |
47 // calls to EnqueueBuffer(). | 55 // calls to EnqueueBuffer(). |
48 void Initialize(int channels, | 56 void Initialize(int channels, |
49 int samples_per_second, | 57 int samples_per_second, |
50 int bits_per_channel, | 58 int bits_per_channel, |
51 float initial_playback_rate, | 59 float initial_playback_rate, |
52 const base::Closure& request_read_cb); | 60 const base::Closure& request_read_cb); |
53 | 61 |
54 // Tries to fill |length| bytes of |dest| with possibly scaled data from our | 62 // Tries to fill |requested_frames| frames into |dest| with possibly scaled |
55 // |audio_buffer_|. Data is scaled based on the playback rate, using a | 63 // data from our |audio_buffer_|. Data is scaled based on the playback rate, |
56 // variation of the Overlap-Add method to combine sample windows. | 64 // using a variation of the Overlap-Add method to combine sample windows. |
57 // | 65 // |
58 // Data from |audio_buffer_| is consumed in proportion to the playback rate. | 66 // 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 // | 67 // |
67 // Returns the number of bytes copied into |dest|. | 68 // Returns the number of frames copied into |dest|. |
68 // May request more reads via |request_read_cb_| before returning. | 69 // May request more reads via |request_read_cb_| before returning. |
69 uint32 FillBuffer(uint8* dest, uint32 length); | 70 uint32 FillBuffer(uint8* dest, uint32 requested_frames); |
70 | 71 |
71 // Clears |audio_buffer_|. | 72 // Clears |audio_buffer_|. |
72 void FlushBuffers(); | 73 void FlushBuffers(); |
73 | 74 |
74 // Returns the time of the next byte in our data or kNoTimestamp() if current | 75 // Returns the time of the next byte in our data or kNoTimestamp() if current |
75 // time is unknown. | 76 // time is unknown. |
76 base::TimeDelta GetTime(); | 77 base::TimeDelta GetTime(); |
77 | 78 |
78 // Enqueues a buffer. It is called from the owner of the algorithm after a | 79 // Enqueues a buffer. It is called from the owner of the algorithm after a |
79 // read completes. | 80 // read completes. |
80 void EnqueueBuffer(Buffer* buffer_in); | 81 void EnqueueBuffer(Buffer* buffer_in); |
81 | 82 |
82 float playback_rate() const { return playback_rate_; } | 83 float playback_rate() const { return playback_rate_; } |
83 void SetPlaybackRate(float new_rate); | 84 void SetPlaybackRate(float new_rate); |
84 | 85 |
85 // Returns whether |audio_buffer_| is empty. | 86 // Returns whether the algorithm needs more data to continue filling buffers. |
86 bool IsQueueEmpty(); | 87 bool NeedsMoreData(); |
87 | 88 |
88 // Returns true if |audio_buffer_| is at or exceeds capacity. | 89 // Returns true if |audio_buffer_| is at or exceeds capacity. |
89 bool IsQueueFull(); | 90 bool IsQueueFull(); |
90 | 91 |
91 // Returns the capacity of |audio_buffer_|. | 92 // Returns the capacity of |audio_buffer_|. |
92 uint32 QueueCapacity(); | 93 uint32 QueueCapacity(); |
93 | 94 |
94 // Increase the capacity of |audio_buffer_| if possible. | 95 // Increase the capacity of |audio_buffer_| if possible. |
95 void IncreaseQueueCapacity(); | 96 void IncreaseQueueCapacity(); |
96 | 97 |
97 // Returns the number of bytes left in |audio_buffer_|, which may be larger | 98 // 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 | 99 // than QueueCapacity() in the event that a read callback delivered more data |
99 // than |audio_buffer_| was intending to hold. | 100 // than |audio_buffer_| was intending to hold. |
100 uint32 bytes_buffered() { return audio_buffer_.forward_bytes(); } | 101 uint32 bytes_buffered() { return audio_buffer_.forward_bytes(); } |
101 | 102 |
102 uint32 window_size() { return window_size_; } | 103 uint32 bytes_per_frame() { return bytes_per_frame_; } |
| 104 |
| 105 uint32 bytes_per_channel() { return bytes_per_channel_; } |
103 | 106 |
104 private: | 107 private: |
105 // Advances |audio_buffer_|'s internal pointer by |bytes|. | 108 // Returns true if |audio_buffer_| is empty. |
106 void AdvanceBufferPosition(uint32 bytes); | 109 bool IsQueueEmpty(); |
107 | 110 |
108 // Tries to copy |bytes| bytes from |audio_buffer_| to |dest|. | 111 // Fills |dest| with one frame of audio data at normal speed. Returns true if |
109 // Returns the number of bytes successfully copied. | 112 // a frame was rendered, false otherwise. |
110 uint32 CopyFromAudioBuffer(uint8* dest, uint32 bytes); | 113 bool OutputNormalPlayback(uint8* dest); |
111 | 114 |
112 // Aligns |value| to a channel and sample boundary. | 115 // Fills |dest| with one frame of audio data at faster than normal speed. |
113 void AlignToSampleBoundary(uint32* value); | 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 squish |
| 119 // audio output while preserving pitch. Essentially, we play a bit of audio |
| 120 // data at normal speed, then we "fast forward" by dropping the next bit of |
| 121 // audio data, and then we stich the pieces together by crossfading from one |
| 122 // audio chunk to the next. |
| 123 bool OutputFasterPlayback(uint8* dest); |
114 | 124 |
115 // Attempts to write |length| bytes of muted audio into |dest|. | 125 // Fills |dest| with one frame of audio data at slower than normal speed. |
116 uint32 MuteBuffer(uint8* dest, uint32 length); | 126 // Returns true if a frame was rendered, false otherwise. |
| 127 // |
| 128 // When the audio playback is < 1.0, we use a variant of Overlap-Add to |
| 129 // stretch audio output while preserving pitch. This works by outputting a |
| 130 // segment of audio data at normal speed. The next audio segment then starts |
| 131 // by repeating some of the audio data from the previous audio segment. |
| 132 // Segments are stiched together by crossfading from one audio chunk to the |
| 133 // next. |
| 134 bool OutputSlowerPlayback(uint8* dest); |
| 135 |
| 136 // Resets the window state to the start of a new window. |
| 137 void ResetWindow(); |
| 138 |
| 139 // Copies a raw frame from |audio_buffer_| into |dest| without progressing |
| 140 // |audio_buffer_|'s internal "current" cursor. Optionally peeks at a forward |
| 141 // byte |offset|. |
| 142 void CopyWithoutAdvance(uint8* dest); |
| 143 void CopyWithoutAdvance(uint8* dest, uint32 offset); |
| 144 |
| 145 // Copies a raw frame from |audio_buffer_| into |dest| and progresses the |
| 146 // |audio_buffer_| forward. |
| 147 void CopyWithAdvance(uint8* dest); |
| 148 |
| 149 // Moves the |audio_buffer_| forward by one frame. |
| 150 void DropFrame(); |
| 151 |
| 152 // Does a linear crossfade from |intro| into |outtro| for one frame. |
| 153 // Assumes pointers are valid and are at least size of |bytes_per_frame_|. |
| 154 void OutputCrossfadedFrame(uint8* outtro, const uint8* intro); |
| 155 template <class Type> |
| 156 void CrossfadeFrame(uint8* outtro, const uint8* intro); |
| 157 |
| 158 // Rounds |*value| down to the nearest frame boundary. |
| 159 void AlignToFrameBoundary(uint32* value); |
117 | 160 |
118 // Number of channels in audio stream. | 161 // Number of channels in audio stream. |
119 int channels_; | 162 int channels_; |
120 | 163 |
121 // Sample rate of audio stream. | 164 // Sample rate of audio stream. |
122 int samples_per_second_; | 165 int samples_per_second_; |
123 | 166 |
124 // Byte depth of audio. | 167 // Byte depth of audio. |
125 int bytes_per_channel_; | 168 int bytes_per_channel_; |
126 | 169 |
127 // Used by algorithm to scale output. | 170 // Used by algorithm to scale output. |
128 float playback_rate_; | 171 float playback_rate_; |
129 | 172 |
130 // Used to request more data. | 173 // Used to request more data. |
131 base::Closure request_read_cb_; | 174 base::Closure request_read_cb_; |
132 | 175 |
133 // Buffered audio data. | 176 // Buffered audio data. |
134 SeekableBuffer audio_buffer_; | 177 SeekableBuffer audio_buffer_; |
135 | 178 |
136 // Length for crossfade in bytes. | 179 // Length for crossfade in bytes. |
137 uint32 crossfade_size_; | 180 uint32 bytes_in_crossfade_; |
| 181 |
| 182 // Length of frame in bytes. |
| 183 uint32 bytes_per_frame_; |
| 184 |
| 185 // The current location in the audio window, between 0 and |window_size_|. |
| 186 // When |index_into_window_| reaches |window_size_|, the window resets. |
| 187 // Indexed by byte. |
| 188 uint32 index_into_window_; |
| 189 |
| 190 // The frame number in the crossfade. |
| 191 uint32 crossfade_frame_number_; |
| 192 |
| 193 // True if the audio should be muted. |
| 194 bool muted_; |
| 195 |
| 196 bool needs_more_data_; |
| 197 |
| 198 // Temporary buffer to hold crossfade data. |
| 199 scoped_array<uint8> crossfade_buffer_; |
138 | 200 |
139 // Window size, in bytes (calculated from audio properties). | 201 // Window size, in bytes (calculated from audio properties). |
140 uint32 window_size_; | 202 uint32 window_size_; |
141 | 203 |
142 DISALLOW_COPY_AND_ASSIGN(AudioRendererAlgorithmBase); | 204 DISALLOW_COPY_AND_ASSIGN(AudioRendererAlgorithmBase); |
143 }; | 205 }; |
144 | 206 |
145 } // namespace media | 207 } // namespace media |
146 | 208 |
147 #endif // MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_BASE_H_ | 209 #endif // MEDIA_FILTERS_AUDIO_RENDERER_ALGORITHM_BASE_H_ |
OLD | NEW |