Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(616)

Unified Diff: media/filters/audio_renderer_algorithm_base.h

Issue 9395057: Fix muted audio when playback rate != 1.0 or 0.0 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/audio_renderer_algorithm_base.h
diff --git a/media/filters/audio_renderer_algorithm_base.h b/media/filters/audio_renderer_algorithm_base.h
index a7325dac2ba4392a5a5354fbb250c5a683ac4b06..ac6a35938829d8c2ed0a162b5934cab7f8de3d10 100644
--- a/media/filters/audio_renderer_algorithm_base.h
+++ b/media/filters/audio_renderer_algorithm_base.h
@@ -51,22 +51,15 @@ class MEDIA_EXPORT AudioRendererAlgorithmBase {
float initial_playback_rate,
const base::Closure& request_read_cb);
- // Tries to fill |length| bytes of |dest| with possibly scaled data from our
- // |audio_buffer_|. Data is scaled based on the playback rate, using a
- // variation of the Overlap-Add method to combine sample windows.
+ // Tries to fill |requested_frames| frames into |dest| with possibly scaled
+ // data from our |audio_buffer_|. Data is scaled based on the playback rate,
+ // using a variation of the Overlap-Add method to combine sample windows.
//
// Data from |audio_buffer_| is consumed in proportion to the playback rate.
- // FillBuffer() will fit |playback_rate_| * |length| bytes of raw data from
- // |audio_buffer| into |length| bytes of output data in |dest| by chopping up
- // the buffered data into windows and crossfading from one window to the next.
- // For speeds greater than 1.0f, FillBuffer() "squish" the windows, dropping
- // some data in between windows to meet the sped-up playback. For speeds less
- // than 1.0f, FillBuffer() will "stretch" the window by copying and
- // overlapping data at the window boundaries, crossfading in between.
//
- // Returns the number of bytes copied into |dest|.
+ // Returns the number of frames copied into |dest|.
// May request more reads via |request_read_cb_| before returning.
- uint32 FillBuffer(uint8* dest, uint32 length);
+ uint32 FillBuffer(uint8* dest, uint32 requested_frames);
// Clears |audio_buffer_|.
void FlushBuffers();
@@ -82,7 +75,10 @@ class MEDIA_EXPORT AudioRendererAlgorithmBase {
float playback_rate() const { return playback_rate_; }
void SetPlaybackRate(float new_rate);
- // Returns whether |audio_buffer_| is empty.
+ // Returns whether the algorithm needs more data to continue filling buffers.
+ bool NeedsMoreData();
+
+ // Returns true if |audio_buffer_| is empty.
bool IsQueueEmpty();
// Returns true if |audio_buffer_| is at or exceeds capacity.
@@ -102,18 +98,55 @@ class MEDIA_EXPORT AudioRendererAlgorithmBase {
uint32 window_size() { return window_size_; }
private:
- // Advances |audio_buffer_|'s internal pointer by |bytes|.
- void AdvanceBufferPosition(uint32 bytes);
+ // Fills |dest| with one frame of audio data at normal speed. Returns true if
+ // a frame was rendered, false otherwise.
+ bool OutputNormalPlayback(uint8* dest);
- // Tries to copy |bytes| bytes from |audio_buffer_| to |dest|.
- // Returns the number of bytes successfully copied.
- uint32 CopyFromAudioBuffer(uint8* dest, uint32 bytes);
+ // Fills |dest| with one frame of audio data at faster than normal speed.
+ // Returns true if a frame was rendered, false otherwise.
+ //
+ // When the audio playback is > 1.0, we use a variant of Overlap-Add to squish
+ // audio output while preserving pitch. Essentially, we play a bit of audio
+ // data at normal speed, then we "fast forward" by dropping the next bit of
+ // audio data, and then we stich the pieces together by crossfading from one
+ // audio chunk to the next.
+ bool OutputFasterPlayback(uint8* dest);
+
+ // Fills |dest| with one frame of audio data at slower than normal speed.
+ // Returns true if a frame was rendered, false otherwise.
+ //
+ // 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.
+ // stretch audio output while preserving pitch. This works by outputting a
+ // segment of audio data at normal speed. The next audio segment then starts
+ // by repeating some of the audio data from the previous audio segment.
+ // Segments are stiched together by crossfading from one audio chunk to the
+ // next.
+ bool OutputSlowerPlayback(uint8* dest);
+
+ // Resets the window state to the start of a new window.
+ void ResetWindow();
+
+ // Copies a raw frame from |audio_buffer_| into |dest| without progressing
+ // |audio_buffer_|'s internal "current" cursor. Optionally peeks at a forward
+ // byte |offset|.
+ 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.
+ void PeekRawFrame(uint8* dest, uint32 offset);
+
+ // Copies a raw frame from |audio_buffer_| into |dest| and progresses the
+ // |audio_buffer_| forward.
+ 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.
+
+ // Moves the |audio_buffer_| forward by one frame.
+ void DropFrame();
+
+ // Does a linear crossfade from |intro| into |outtro| for one frame.
+ // Assumes pointers are valid and are at least size of |bytes_per_frame_|.
+ void OutputCrossfadedFrame(uint8* outtro, const uint8* intro);
+ template <class Type>
+ void CrossfadeFrame(Type* outtro, const Type* intro);
// 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.
- void AlignToSampleBoundary(uint32* value);
-
- // Attempts to write |length| bytes of muted audio into |dest|.
- uint32 MuteBuffer(uint8* dest, uint32 length);
+ void AlignToFrameBoundary(uint32* value);
// Number of channels in audio stream.
int channels_;
@@ -134,7 +167,26 @@ class MEDIA_EXPORT AudioRendererAlgorithmBase {
SeekableBuffer audio_buffer_;
// Length for crossfade in bytes.
- uint32 crossfade_size_;
+ uint32 bytes_in_crossfade_;
+
+ // Length of frame in bytes.
+ uint32 bytes_per_frame_;
+
+ // The current location in the audio window, between 0 and |window_size_|.
+ // When |index_into_window_| reaches |window_size_|, the window resets.
+ // Indexed by byte.
+ uint32 index_into_window_;
+
+ // The frame number in the crossfade.
+ uint32 crossfade_frame_number_;
+
+ // True if the audio should be muted.
+ bool muted_;
+
+ bool needs_more_data_;
+
+ // Temporary buffer to hold crossfade data.
+ scoped_array<uint8> crossfade_buffer_;
// Window size, in bytes (calculated from audio properties).
uint32 window_size_;

Powered by Google App Engine
This is Rietveld 408576698