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 |