- add sources.
[platform/framework/web/crosswalk.git] / src / content / renderer / media / webaudiosourceprovider_impl_unittest.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/media/webaudiosourceprovider_impl.h"
6 #include "media/audio/audio_parameters.h"
7 #include "media/base/fake_audio_render_callback.h"
8 #include "media/base/mock_audio_renderer_sink.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/WebKit/public/web/WebAudioSourceProviderClient.h"
12
13 namespace content {
14
15 namespace {
16 const float kTestVolume = 0.25;
17 }  // namespace
18
19 class WebAudioSourceProviderImplTest
20     : public testing::Test,
21       public WebKit::WebAudioSourceProviderClient {
22  public:
23   WebAudioSourceProviderImplTest()
24       : params_(media::AudioParameters::AUDIO_PCM_LINEAR,
25                 media::CHANNEL_LAYOUT_STEREO, 48000, 16, 64),
26         fake_callback_(0.1),
27         mock_sink_(new media::MockAudioRendererSink()),
28         wasp_impl_(new WebAudioSourceProviderImpl(mock_sink_)) {
29   }
30
31   virtual ~WebAudioSourceProviderImplTest() {}
32
33   void CallAllSinkMethodsAndVerify(bool verify) {
34     testing::InSequence s;
35
36     EXPECT_CALL(*mock_sink_.get(), Start()).Times(verify);
37     wasp_impl_->Start();
38
39     EXPECT_CALL(*mock_sink_.get(), Play()).Times(verify);
40     wasp_impl_->Play();
41
42     EXPECT_CALL(*mock_sink_.get(), Pause()).Times(verify);
43     wasp_impl_->Pause();
44
45     EXPECT_CALL(*mock_sink_.get(), SetVolume(kTestVolume)).Times(verify);
46     wasp_impl_->SetVolume(kTestVolume);
47
48     EXPECT_CALL(*mock_sink_.get(), Stop()).Times(verify);
49     wasp_impl_->Stop();
50
51     testing::Mock::VerifyAndClear(mock_sink_.get());
52   }
53
54   void SetClient(WebKit::WebAudioSourceProviderClient* client) {
55     testing::InSequence s;
56
57     if (client) {
58       EXPECT_CALL(*mock_sink_.get(), Stop());
59       EXPECT_CALL(*this, setFormat(params_.channels(), params_.sample_rate()));
60     }
61     wasp_impl_->setClient(client);
62
63     testing::Mock::VerifyAndClear(mock_sink_.get());
64     testing::Mock::VerifyAndClear(this);
65   }
66
67   bool CompareBusses(const media::AudioBus* bus1, const media::AudioBus* bus2) {
68     EXPECT_EQ(bus1->channels(), bus2->channels());
69     EXPECT_EQ(bus1->frames(), bus2->frames());
70     for (int ch = 0; ch < bus1->channels(); ++ch) {
71       if (memcmp(bus1->channel(ch), bus2->channel(ch),
72                  sizeof(*bus1->channel(ch)) * bus1->frames()) != 0) {
73         return false;
74       }
75     }
76     return true;
77   }
78
79   // WebKit::WebAudioSourceProviderClient implementation.
80   MOCK_METHOD2(setFormat, void(size_t numberOfChannels, float sampleRate));
81
82  protected:
83   media::AudioParameters params_;
84   media::FakeAudioRenderCallback fake_callback_;
85   scoped_refptr<media::MockAudioRendererSink> mock_sink_;
86   scoped_refptr<WebAudioSourceProviderImpl> wasp_impl_;
87
88   DISALLOW_COPY_AND_ASSIGN(WebAudioSourceProviderImplTest);
89 };
90
91 TEST_F(WebAudioSourceProviderImplTest, SetClientBeforeInitialize) {
92   // setClient() with a NULL client should do nothing if no client is set.
93   wasp_impl_->setClient(NULL);
94
95   EXPECT_CALL(*mock_sink_.get(), Stop());
96   wasp_impl_->setClient(this);
97
98   // When Initialize() is called after setClient(), the params should propagate
99   // to the client via setFormat() during the call.
100   EXPECT_CALL(*this, setFormat(params_.channels(), params_.sample_rate()));
101   wasp_impl_->Initialize(params_, &fake_callback_);
102
103   // setClient() with the same client should do nothing.
104   wasp_impl_->setClient(this);
105 }
106
107 // Verify AudioRendererSink functionality w/ and w/o a client.
108 TEST_F(WebAudioSourceProviderImplTest, SinkMethods) {
109   wasp_impl_->Initialize(params_, &fake_callback_);
110   ASSERT_EQ(mock_sink_->callback(), &fake_callback_);
111
112   // Without a client all WASP calls should fall through to the underlying sink.
113   CallAllSinkMethodsAndVerify(true);
114
115   // With a client no calls should reach the Stop()'d sink.  Also, setClient()
116   // should propagate the params provided during Initialize() at call time.
117   SetClient(this);
118   CallAllSinkMethodsAndVerify(false);
119
120   // Removing the client should cause WASP to revert to the underlying sink.
121   EXPECT_CALL(*mock_sink_.get(), SetVolume(kTestVolume));
122   SetClient(NULL);
123   CallAllSinkMethodsAndVerify(true);
124 }
125
126 // Verify underlying sink state is restored after client removal.
127 TEST_F(WebAudioSourceProviderImplTest, SinkStateRestored) {
128   wasp_impl_->Initialize(params_, &fake_callback_);
129
130   // Verify state set before the client is set propagates back afterward.
131   EXPECT_CALL(*mock_sink_.get(), Start());
132   wasp_impl_->Start();
133   SetClient(this);
134
135   EXPECT_CALL(*mock_sink_.get(), SetVolume(1.0));
136   EXPECT_CALL(*mock_sink_.get(), Start());
137   SetClient(NULL);
138
139   // Verify state set while the client was attached propagates back afterward.
140   SetClient(this);
141   wasp_impl_->Play();
142   wasp_impl_->SetVolume(kTestVolume);
143
144   EXPECT_CALL(*mock_sink_.get(), SetVolume(kTestVolume));
145   EXPECT_CALL(*mock_sink_.get(), Start());
146   EXPECT_CALL(*mock_sink_.get(), Play());
147   SetClient(NULL);
148 }
149
150 // Test the AudioRendererSink state machine and its effects on provideInput().
151 TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
152   scoped_ptr<media::AudioBus> bus1 = media::AudioBus::Create(params_);
153   scoped_ptr<media::AudioBus> bus2 = media::AudioBus::Create(params_);
154
155   // Point the WebVector into memory owned by |bus1|.
156   WebKit::WebVector<float*> audio_data(static_cast<size_t>(bus1->channels()));
157   for (size_t i = 0; i < audio_data.size(); ++i)
158     audio_data[i] = bus1->channel(i);
159
160   // Verify provideInput() works before Initialize() and returns silence.
161   bus1->channel(0)[0] = 1;
162   bus2->Zero();
163   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
164   ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
165
166   wasp_impl_->Initialize(params_, &fake_callback_);
167   SetClient(this);
168
169   // Verify provideInput() is muted prior to Start() and no calls to the render
170   // callback have occurred.
171   bus1->channel(0)[0] = 1;
172   bus2->Zero();
173   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
174   ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
175   ASSERT_EQ(fake_callback_.last_audio_delay_milliseconds(), -1);
176
177   wasp_impl_->Start();
178
179   // Ditto for Play().
180   bus1->channel(0)[0] = 1;
181   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
182   ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
183   ASSERT_EQ(fake_callback_.last_audio_delay_milliseconds(), -1);
184
185   wasp_impl_->Play();
186
187   // Now we should get real audio data.
188   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
189   ASSERT_FALSE(CompareBusses(bus1.get(), bus2.get()));
190
191   // Ensure volume adjustment is working.
192   fake_callback_.reset();
193   fake_callback_.Render(bus2.get(), 0);
194   bus2->Scale(kTestVolume);
195
196   fake_callback_.reset();
197   wasp_impl_->SetVolume(kTestVolume);
198   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
199   ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
200
201   // Pause should return to silence.
202   wasp_impl_->Pause();
203   bus1->channel(0)[0] = 1;
204   bus2->Zero();
205   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
206   ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
207
208   wasp_impl_->Play();
209
210   // Play should return real audio data again...
211   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
212   ASSERT_FALSE(CompareBusses(bus1.get(), bus2.get()));
213
214   // Stop() should return silence.
215   wasp_impl_->Stop();
216   bus1->channel(0)[0] = 1;
217   wasp_impl_->provideInput(audio_data, params_.frames_per_buffer());
218   ASSERT_TRUE(CompareBusses(bus1.get(), bus2.get()));
219 }
220
221 }  // namespace content