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

Side by Side Diff: media/base/audio_block_fifo.cc

Issue 2690793002: Add basic resample support to WASAPIAudioInputStream. (Closed)
Patch Set: Add check for unsupported channel layout Created 3 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 unified diff | Download patch
« no previous file with comments | « media/base/audio_block_fifo.h ('k') | media/base/audio_block_fifo_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #include <stdint.h> 5 #include <stdint.h>
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "media/base/audio_block_fifo.h" 9 #include "media/base/audio_block_fifo.h"
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 12
13 namespace media { 13 namespace media {
14 14
15 AudioBlockFifo::AudioBlockFifo(int channels, int frames, int blocks) 15 AudioBlockFifo::AudioBlockFifo(int channels, int frames, int blocks)
16 : channels_(channels), 16 : channels_(channels),
17 block_frames_(frames), 17 block_frames_(frames),
18 write_block_(0), 18 write_block_(0),
19 read_block_(0), 19 read_block_(0),
20 available_blocks_(0), 20 available_blocks_(0),
21 write_pos_(0) { 21 write_pos_(0) {
22 IncreaseCapacity(blocks); 22 IncreaseCapacity(blocks);
23 } 23 }
24 24
25 AudioBlockFifo::~AudioBlockFifo() {} 25 AudioBlockFifo::~AudioBlockFifo() {}
26 26
27 void AudioBlockFifo::Push(const void* source, 27 void AudioBlockFifo::Push(const void* source,
28 int frames, 28 int frames,
29 int bytes_per_sample) { 29 int bytes_per_sample) {
30 DCHECK(source); 30 PushInternal(source, frames, bytes_per_sample);
31 DCHECK_GT(frames, 0); 31 }
32 DCHECK_GT(bytes_per_sample, 0);
33 DCHECK_LT(available_blocks_, static_cast<int>(audio_blocks_.size()));
34 CHECK_LE(frames, GetUnfilledFrames());
35 32
36 const uint8_t* source_ptr = static_cast<const uint8_t*>(source); 33 void AudioBlockFifo::PushSilence(int frames) {
37 int frames_to_push = frames; 34 PushInternal(nullptr, frames, 0);
38 while (frames_to_push) {
39 // Get the current write block.
40 AudioBus* current_block = audio_blocks_[write_block_];
41
42 // Figure out what segment sizes we need when adding the new content to
43 // the FIFO.
44 const int push_frames =
45 std::min(block_frames_ - write_pos_, frames_to_push);
46
47 // Deinterleave the content to the FIFO and update the |write_pos_|.
48 current_block->FromInterleavedPartial(
49 source_ptr, write_pos_, push_frames, bytes_per_sample);
50 write_pos_ = (write_pos_ + push_frames) % block_frames_;
51 if (!write_pos_) {
52 // The current block is completely filled, increment |write_block_| and
53 // |available_blocks_|.
54 write_block_ = (write_block_ + 1) % audio_blocks_.size();
55 ++available_blocks_;
56 }
57
58 source_ptr += push_frames * bytes_per_sample * channels_;
59 frames_to_push -= push_frames;
60 DCHECK_GE(frames_to_push, 0);
61 }
62 } 35 }
63 36
64 const AudioBus* AudioBlockFifo::Consume() { 37 const AudioBus* AudioBlockFifo::Consume() {
65 DCHECK(available_blocks_); 38 DCHECK(available_blocks_);
66 AudioBus* audio_bus = audio_blocks_[read_block_]; 39 AudioBus* audio_bus = audio_blocks_[read_block_];
67 read_block_ = (read_block_ + 1) % audio_blocks_.size(); 40 read_block_ = (read_block_ + 1) % audio_blocks_.size();
68 --available_blocks_; 41 --available_blocks_;
69 return audio_bus; 42 return audio_bus;
70 } 43 }
71 44
(...skipping 24 matching lines...) Expand all
96 const int original_size = audio_blocks_.size(); 69 const int original_size = audio_blocks_.size();
97 for (int i = 0; i < blocks; ++i) { 70 for (int i = 0; i < blocks; ++i) {
98 audio_blocks_.push_back( 71 audio_blocks_.push_back(
99 AudioBus::Create(channels_, block_frames_).release()); 72 AudioBus::Create(channels_, block_frames_).release());
100 } 73 }
101 74
102 if (!original_size) 75 if (!original_size)
103 return; 76 return;
104 77
105 std::rotate(audio_blocks_.begin() + read_block_, 78 std::rotate(audio_blocks_.begin() + read_block_,
106 audio_blocks_.begin() + original_size, 79 audio_blocks_.begin() + original_size, audio_blocks_.end());
107 audio_blocks_.end());
108 80
109 // Update the write pointer if it is on top of the new inserted blocks. 81 // Update the write pointer if it is on top of the new inserted blocks.
110 if (write_block_ >= read_block_) 82 if (write_block_ >= read_block_)
111 write_block_ += blocks; 83 write_block_ += blocks;
112 84
113 // Update the read pointers correspondingly. 85 // Update the read pointers correspondingly.
114 read_block_ += blocks; 86 read_block_ += blocks;
115 87
116 DCHECK_LT(read_block_, static_cast<int>(audio_blocks_.size())); 88 DCHECK_LT(read_block_, static_cast<int>(audio_blocks_.size()));
117 DCHECK_LT(write_block_, static_cast<int>(audio_blocks_.size())); 89 DCHECK_LT(write_block_, static_cast<int>(audio_blocks_.size()));
118 } 90 }
119 91
92 void AudioBlockFifo::PushInternal(const void* source,
93 int frames,
94 int bytes_per_sample) {
95 // |source| may be nullptr if bytes_per_sample is 0. In that case,
96 // we inject silence.
97 DCHECK((source && bytes_per_sample > 0) || (!source && !bytes_per_sample));
98 DCHECK_GT(frames, 0);
99 DCHECK_LT(available_blocks_, static_cast<int>(audio_blocks_.size()));
100 CHECK_LE(frames, GetUnfilledFrames());
101
102 const uint8_t* source_ptr = static_cast<const uint8_t*>(source);
103 int frames_to_push = frames;
104 while (frames_to_push) {
105 // Get the current write block.
106 AudioBus* current_block = audio_blocks_[write_block_];
107
108 // Figure out what segment sizes we need when adding the new content to
109 // the FIFO.
110 const int push_frames =
111 std::min(block_frames_ - write_pos_, frames_to_push);
112
113 if (source) {
114 // Deinterleave the content to the FIFO and update the |write_pos_|.
115 current_block->FromInterleavedPartial(source_ptr, write_pos_, push_frames,
116 bytes_per_sample);
117 } else {
118 current_block->ZeroFramesPartial(write_pos_, push_frames);
119 }
120 write_pos_ = (write_pos_ + push_frames) % block_frames_;
121 if (!write_pos_) {
122 // The current block is completely filled, increment |write_block_| and
123 // |available_blocks_|.
124 write_block_ = (write_block_ + 1) % audio_blocks_.size();
125 ++available_blocks_;
126 }
127
128 if (source_ptr)
129 source_ptr += push_frames * bytes_per_sample * channels_;
130 frames_to_push -= push_frames;
131 DCHECK_GE(frames_to_push, 0);
132 }
133 }
134
120 } // namespace media 135 } // namespace media
OLDNEW
« no previous file with comments | « media/base/audio_block_fifo.h ('k') | media/base/audio_block_fifo_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698