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 #include "media/audio/null_audio_sink.h" | 5 #include "media/audio/null_audio_sink.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
9 #include "base/sys_byteorder.h" | 9 #include "base/sys_byteorder.h" |
10 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
11 | 11 |
12 namespace media { | 12 namespace media { |
13 | 13 |
14 NullAudioSink::NullAudioSink() | 14 NullAudioSink::NullAudioSink() |
15 : initialized_(false), | 15 : initialized_(false), |
16 playing_(false), | 16 playing_(false), |
17 callback_(NULL), | 17 callback_(NULL), |
18 thread_("NullAudioThread"), | 18 thread_("NullAudioThread"), |
19 hash_audio_for_testing_(false) { | 19 hash_audio_for_testing_(false) { |
20 } | 20 } |
21 | 21 |
22 void NullAudioSink::Initialize(const AudioParameters& params, | 22 void NullAudioSink::Initialize(const AudioParameters& params, |
23 RenderCallback* callback) { | 23 RenderCallback* callback) { |
24 DCHECK(!initialized_); | 24 DCHECK(!initialized_); |
25 params_ = params; | 25 params_ = params; |
26 | 26 |
27 audio_data_.reserve(params.channels()); | 27 audio_bus_ = AudioBus::Create(params_); |
28 for (int i = 0; i < params.channels(); ++i) { | |
29 float* channel_data = new float[params.frames_per_buffer()]; | |
30 audio_data_.push_back(channel_data); | |
31 } | |
32 | 28 |
33 if (hash_audio_for_testing_) { | 29 if (hash_audio_for_testing_) { |
34 md5_channel_contexts_.reset(new base::MD5Context[params.channels()]); | 30 md5_channel_contexts_.reset(new base::MD5Context[params_.channels()]); |
35 for (int i = 0; i < params.channels(); i++) | 31 for (int i = 0; i < params_.channels(); i++) |
36 base::MD5Init(&md5_channel_contexts_[i]); | 32 base::MD5Init(&md5_channel_contexts_[i]); |
37 } | 33 } |
38 | 34 |
39 callback_ = callback; | 35 callback_ = callback; |
40 initialized_ = true; | 36 initialized_ = true; |
41 } | 37 } |
42 | 38 |
43 void NullAudioSink::Start() { | 39 void NullAudioSink::Start() { |
44 if (!thread_.Start()) | 40 if (!thread_.Start()) |
45 return; | 41 return; |
(...skipping 20 matching lines...) Expand all Loading... |
66 return volume == 0.0; | 62 return volume == 0.0; |
67 } | 63 } |
68 | 64 |
69 void NullAudioSink::SetPlaying(bool is_playing) { | 65 void NullAudioSink::SetPlaying(bool is_playing) { |
70 base::AutoLock auto_lock(lock_); | 66 base::AutoLock auto_lock(lock_); |
71 playing_ = is_playing; | 67 playing_ = is_playing; |
72 } | 68 } |
73 | 69 |
74 NullAudioSink::~NullAudioSink() { | 70 NullAudioSink::~NullAudioSink() { |
75 DCHECK(!thread_.IsRunning()); | 71 DCHECK(!thread_.IsRunning()); |
76 for (size_t i = 0; i < audio_data_.size(); ++i) | |
77 delete [] audio_data_[i]; | |
78 } | 72 } |
79 | 73 |
80 void NullAudioSink::FillBufferTask() { | 74 void NullAudioSink::FillBufferTask() { |
81 base::AutoLock auto_lock(lock_); | 75 base::AutoLock auto_lock(lock_); |
82 | 76 |
83 base::TimeDelta delay; | 77 base::TimeDelta delay; |
84 // Only consume buffers when actually playing. | 78 // Only consume buffers when actually playing. |
85 if (playing_) { | 79 if (playing_) { |
86 int requested_frames = params_.frames_per_buffer(); | 80 int frames_received = callback_->Render( |
87 int frames_received = callback_->Render(audio_data_, requested_frames, 0); | 81 audio_bus_.get(), audio_bus_->frames(), 0); |
88 int frames_per_millisecond = | 82 int frames_per_millisecond = |
89 params_.sample_rate() / base::Time::kMillisecondsPerSecond; | 83 params_.sample_rate() / base::Time::kMillisecondsPerSecond; |
90 | 84 |
91 if (hash_audio_for_testing_ && frames_received > 0) { | 85 if (hash_audio_for_testing_ && frames_received > 0) { |
92 DCHECK_EQ(sizeof(float), sizeof(uint32)); | 86 DCHECK_EQ(sizeof(float), sizeof(uint32)); |
93 int channels = audio_data_.size(); | 87 int channels = audio_bus_->channels(); |
94 for (int channel_idx = 0; channel_idx < channels; ++channel_idx) { | 88 for (int channel_idx = 0; channel_idx < channels; ++channel_idx) { |
95 float* channel = audio_data_[channel_idx]; | 89 float* channel = audio_bus_->channel(channel_idx); |
96 for (int frame_idx = 0; frame_idx < frames_received; frame_idx++) { | 90 for (int frame_idx = 0; frame_idx < frames_received; frame_idx++) { |
97 // Convert float to uint32 w/o conversion loss. | 91 // Convert float to uint32 w/o conversion loss. |
98 uint32 frame = base::ByteSwapToLE32( | 92 uint32 frame = base::ByteSwapToLE32( |
99 bit_cast<uint32>(channel[frame_idx])); | 93 bit_cast<uint32>(channel[frame_idx])); |
100 base::MD5Update( | 94 base::MD5Update( |
101 &md5_channel_contexts_[channel_idx], base::StringPiece( | 95 &md5_channel_contexts_[channel_idx], base::StringPiece( |
102 reinterpret_cast<char*>(&frame), sizeof(frame))); | 96 reinterpret_cast<char*>(&frame), sizeof(frame))); |
103 } | 97 } |
104 } | 98 } |
105 } | 99 } |
(...skipping 22 matching lines...) Expand all Loading... |
128 DCHECK(hash_audio_for_testing_); | 122 DCHECK(hash_audio_for_testing_); |
129 | 123 |
130 // If initialize failed or was never called, ensure we return an empty hash. | 124 // If initialize failed or was never called, ensure we return an empty hash. |
131 if (!initialized_) { | 125 if (!initialized_) { |
132 md5_channel_contexts_.reset(new base::MD5Context[1]); | 126 md5_channel_contexts_.reset(new base::MD5Context[1]); |
133 base::MD5Init(&md5_channel_contexts_[0]); | 127 base::MD5Init(&md5_channel_contexts_[0]); |
134 } | 128 } |
135 | 129 |
136 // Hash all channels into the first channel. | 130 // Hash all channels into the first channel. |
137 base::MD5Digest digest; | 131 base::MD5Digest digest; |
138 for (size_t i = 1; i < audio_data_.size(); i++) { | 132 for (int i = 1; i < audio_bus_->channels(); i++) { |
139 base::MD5Final(&digest, &md5_channel_contexts_[i]); | 133 base::MD5Final(&digest, &md5_channel_contexts_[i]); |
140 base::MD5Update(&md5_channel_contexts_[0], base::StringPiece( | 134 base::MD5Update(&md5_channel_contexts_[0], base::StringPiece( |
141 reinterpret_cast<char*>(&digest), sizeof(base::MD5Digest))); | 135 reinterpret_cast<char*>(&digest), sizeof(base::MD5Digest))); |
142 } | 136 } |
143 | 137 |
144 base::MD5Final(&digest, &md5_channel_contexts_[0]); | 138 base::MD5Final(&digest, &md5_channel_contexts_[0]); |
145 return base::MD5DigestToBase16(digest); | 139 return base::MD5DigestToBase16(digest); |
146 } | 140 } |
147 | 141 |
148 } // namespace media | 142 } // namespace media |
OLD | NEW |