Fix build break
[chromium-blink-merge.git] / ppapi / tests / test_audio.cc
blobb3853eaa00c0d6ed5154a8eb5068e9a80d821c94
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
3 // found in the LICENSE file.
5 #include "ppapi/tests/test_audio.h"
7 #include <string.h>
9 #include "ppapi/c/ppb_audio_config.h"
10 #include "ppapi/c/ppb_audio.h"
11 #include "ppapi/cpp/module.h"
12 #include "ppapi/tests/testing_instance.h"
13 #include "ppapi/tests/test_utils.h"
15 #define ARRAYSIZE_UNSAFE(a) \
16 ((sizeof(a) / sizeof(*(a))) / \
17 static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
19 REGISTER_TEST_CASE(Audio);
21 const int32_t kMagicValue = 12345;
23 TestAudio::TestAudio(TestingInstance* instance)
24 : TestCase(instance),
25 audio_callback_method_(NULL),
26 audio_callback_event_(instance->pp_instance()),
27 test_done_(false) {
30 TestAudio::~TestAudio() {
33 bool TestAudio::Init() {
34 audio_interface_ = static_cast<const PPB_Audio*>(
35 pp::Module::Get()->GetBrowserInterface(PPB_AUDIO_INTERFACE));
36 audio_config_interface_ = static_cast<const PPB_AudioConfig*>(
37 pp::Module::Get()->GetBrowserInterface(PPB_AUDIO_CONFIG_INTERFACE));
38 core_interface_ = static_cast<const PPB_Core*>(
39 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
40 return audio_interface_ && audio_config_interface_ && core_interface_;
43 void TestAudio::RunTests(const std::string& filter) {
44 RUN_TEST(Creation, filter);
45 RUN_TEST(DestroyNoStop, filter);
46 RUN_TEST(Failures, filter);
47 RUN_TEST(AudioCallback1, filter);
48 RUN_TEST(AudioCallback2, filter);
49 RUN_TEST(AudioCallback3, filter);
52 // Test creating audio resources for all guaranteed sample rates and various
53 // frame counts.
54 std::string TestAudio::TestCreation() {
55 static const PP_AudioSampleRate kSampleRates[] = {
56 PP_AUDIOSAMPLERATE_44100,
57 PP_AUDIOSAMPLERATE_48000
59 static const uint32_t kRequestFrameCounts[] = {
60 PP_AUDIOMINSAMPLEFRAMECOUNT,
61 PP_AUDIOMAXSAMPLEFRAMECOUNT,
62 // Include some "okay-looking" frame counts; check their validity below.
63 PP_AUDIOSAMPLERATE_44100 / 100, // 10ms @ 44.1kHz
64 PP_AUDIOSAMPLERATE_48000 / 100, // 10ms @ 48kHz
65 2 * PP_AUDIOSAMPLERATE_44100 / 100, // 20ms @ 44.1kHz
66 2 * PP_AUDIOSAMPLERATE_48000 / 100, // 20ms @ 48kHz
67 1024,
68 2048,
69 4096
71 PP_AudioSampleRate sample_rate = audio_config_interface_->RecommendSampleRate(
72 instance_->pp_instance());
73 ASSERT_TRUE(sample_rate == PP_AUDIOSAMPLERATE_NONE ||
74 sample_rate == PP_AUDIOSAMPLERATE_44100 ||
75 sample_rate == PP_AUDIOSAMPLERATE_48000);
76 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSampleRates); i++) {
77 PP_AudioSampleRate sample_rate = kSampleRates[i];
79 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kRequestFrameCounts); j++) {
80 // Make a config, create the audio resource, and release the config.
81 uint32_t request_frame_count = kRequestFrameCounts[j];
82 uint32_t frame_count = audio_config_interface_->RecommendSampleFrameCount(
83 instance_->pp_instance(), sample_rate, request_frame_count);
84 PP_Resource ac = audio_config_interface_->CreateStereo16Bit(
85 instance_->pp_instance(), sample_rate, frame_count);
86 ASSERT_TRUE(ac);
87 PP_Resource audio = audio_interface_->Create(
88 instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
89 core_interface_->ReleaseResource(ac);
90 ac = 0;
92 ASSERT_TRUE(audio);
93 ASSERT_TRUE(audio_interface_->IsAudio(audio));
95 // Check that the config returned for |audio| matches what we gave it.
96 ac = audio_interface_->GetCurrentConfig(audio);
97 ASSERT_TRUE(ac);
98 ASSERT_TRUE(audio_config_interface_->IsAudioConfig(ac));
99 ASSERT_EQ(sample_rate, audio_config_interface_->GetSampleRate(ac));
100 ASSERT_EQ(frame_count, audio_config_interface_->GetSampleFrameCount(ac));
101 core_interface_->ReleaseResource(ac);
102 ac = 0;
104 // Start and stop audio playback. The documentation indicates that
105 // |StartPlayback()| and |StopPlayback()| may fail, but gives no
106 // indication as to why ... so check that they succeed.
107 audio_callback_method_ = &TestAudio::AudioCallbackTrivial;
108 ASSERT_TRUE(audio_interface_->StartPlayback(audio));
109 ASSERT_TRUE(audio_interface_->StopPlayback(audio));
110 audio_callback_method_ = NULL;
112 core_interface_->ReleaseResource(audio);
116 PASS();
119 // Test that releasing the resource without calling |StopPlayback()| "works".
120 std::string TestAudio::TestDestroyNoStop() {
121 const PP_AudioSampleRate kSampleRate = PP_AUDIOSAMPLERATE_44100;
122 const uint32_t kRequestFrameCount = 2048;
124 uint32_t frame_count = audio_config_interface_->RecommendSampleFrameCount(
125 instance_->pp_instance(), kSampleRate, kRequestFrameCount);
126 PP_Resource ac = audio_config_interface_->CreateStereo16Bit(
127 instance_->pp_instance(), kSampleRate, frame_count);
128 ASSERT_TRUE(ac);
129 audio_callback_method_ = NULL;
130 PP_Resource audio = audio_interface_->Create(
131 instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
132 core_interface_->ReleaseResource(ac);
133 ac = 0;
135 ASSERT_TRUE(audio);
136 ASSERT_TRUE(audio_interface_->IsAudio(audio));
138 // Start playback and release the resource.
139 audio_callback_method_ = &TestAudio::AudioCallbackTrivial;
140 ASSERT_TRUE(audio_interface_->StartPlayback(audio));
141 core_interface_->ReleaseResource(audio);
142 audio_callback_method_ = NULL;
144 PASS();
147 std::string TestAudio::TestFailures() {
148 const PP_AudioSampleRate kSampleRate = PP_AUDIOSAMPLERATE_44100;
149 const uint32_t kRequestFrameCount = 2048;
151 // Test invalid parameters to |Create()|.
153 // We want a valid config for some of our tests of |Create()|.
154 uint32_t frame_count = audio_config_interface_->RecommendSampleFrameCount(
155 instance_->pp_instance(), kSampleRate, kRequestFrameCount);
156 PP_Resource ac = audio_config_interface_->CreateStereo16Bit(
157 instance_->pp_instance(), kSampleRate, frame_count);
158 ASSERT_TRUE(ac);
160 // Failure cases should never lead to the callback being called.
161 audio_callback_method_ = NULL;
163 // Invalid instance -> failure.
164 PP_Resource audio = audio_interface_->Create(
165 0, ac, AudioCallbackTrampoline, this);
166 ASSERT_EQ(0, audio);
168 // Invalid config -> failure.
169 audio = audio_interface_->Create(
170 instance_->pp_instance(), 0, AudioCallbackTrampoline, this);
171 ASSERT_EQ(0, audio);
173 // Null callback -> failure.
174 audio = audio_interface_->Create(
175 instance_->pp_instance(), ac, NULL, NULL);
176 ASSERT_EQ(0, audio);
178 core_interface_->ReleaseResource(ac);
179 ac = 0;
181 // Test the other functions with an invalid audio resource.
182 ASSERT_FALSE(audio_interface_->IsAudio(0));
183 ASSERT_EQ(0, audio_interface_->GetCurrentConfig(0));
184 ASSERT_FALSE(audio_interface_->StartPlayback(0));
185 ASSERT_FALSE(audio_interface_->StopPlayback(0));
187 PASS();
190 // NOTE: |TestAudioCallback1| and |TestAudioCallback2| assume that the audio
191 // callback is called at least once. If the audio stream does not start up
192 // correctly or is interrupted this may not be the case and these tests will
193 // fail. However, in order to properly test the audio callbacks, we must have
194 // a configuration where audio can successfully play, so we assume this is the
195 // case on bots.
197 // This test starts playback and verifies that:
198 // 1) the audio callback is actually called;
199 // 2) that |StopPlayback()| waits for the audio callback to finish.
200 std::string TestAudio::TestAudioCallback1() {
201 const PP_AudioSampleRate kSampleRate = PP_AUDIOSAMPLERATE_44100;
202 const uint32_t kRequestFrameCount = 1024;
204 uint32_t frame_count = audio_config_interface_->RecommendSampleFrameCount(
205 instance_->pp_instance(), kSampleRate, kRequestFrameCount);
206 PP_Resource ac = audio_config_interface_->CreateStereo16Bit(
207 instance_->pp_instance(), kSampleRate, frame_count);
208 ASSERT_TRUE(ac);
209 audio_callback_method_ = NULL;
210 PP_Resource audio = audio_interface_->Create(
211 instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
212 core_interface_->ReleaseResource(ac);
213 ac = 0;
215 audio_callback_event_.Reset();
216 test_done_ = false;
218 audio_callback_method_ = &TestAudio::AudioCallbackTest;
219 ASSERT_TRUE(audio_interface_->StartPlayback(audio));
221 // Wait for the audio callback to be called.
222 audio_callback_event_.Wait();
223 ASSERT_TRUE(audio_interface_->StopPlayback(audio));
224 test_done_ = true;
226 // If any more audio callbacks are generated, we should crash (which is good).
227 audio_callback_method_ = NULL;
229 core_interface_->ReleaseResource(audio);
231 PASS();
234 // This is the same as |TestAudioCallback1()|, except that instead of calling
235 // |StopPlayback()|, it just releases the resource.
236 std::string TestAudio::TestAudioCallback2() {
237 const PP_AudioSampleRate kSampleRate = PP_AUDIOSAMPLERATE_44100;
238 const uint32_t kRequestFrameCount = 1024;
240 uint32_t frame_count = audio_config_interface_->RecommendSampleFrameCount(
241 instance_->pp_instance(), kSampleRate, kRequestFrameCount);
242 PP_Resource ac = audio_config_interface_->CreateStereo16Bit(
243 instance_->pp_instance(), kSampleRate, frame_count);
244 ASSERT_TRUE(ac);
245 audio_callback_method_ = NULL;
246 PP_Resource audio = audio_interface_->Create(
247 instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
248 core_interface_->ReleaseResource(ac);
249 ac = 0;
251 audio_callback_event_.Reset();
252 test_done_ = false;
253 callback_fired_ = false;
255 audio_callback_method_ = &TestAudio::AudioCallbackTest;
256 ASSERT_TRUE(audio_interface_->StartPlayback(audio));
258 // Wait for the audio callback to be called.
259 audio_callback_event_.Wait();
261 core_interface_->ReleaseResource(audio);
263 test_done_ = true;
265 // If any more audio callbacks are generated, we should crash (which is good).
266 audio_callback_method_ = NULL;
268 PASS();
271 // This is the same as |TestAudioCallback1()|, except that it attempts a second
272 // round of |StartPlayback| and |StopPlayback| to make sure the callback
273 // function still responds when using the same audio resource.
274 std::string TestAudio::TestAudioCallback3() {
275 const PP_AudioSampleRate kSampleRate = PP_AUDIOSAMPLERATE_44100;
276 const uint32_t kRequestFrameCount = 1024;
278 uint32_t frame_count = audio_config_interface_->RecommendSampleFrameCount(
279 instance_->pp_instance(), kSampleRate, kRequestFrameCount);
280 PP_Resource ac = audio_config_interface_->CreateStereo16Bit(
281 instance_->pp_instance(), kSampleRate, frame_count);
282 ASSERT_TRUE(ac);
283 audio_callback_method_ = NULL;
284 PP_Resource audio = audio_interface_->Create(
285 instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
286 core_interface_->ReleaseResource(ac);
287 ac = 0;
289 audio_callback_event_.Reset();
290 test_done_ = false;
291 callback_fired_ = false;
293 audio_callback_method_ = &TestAudio::AudioCallbackTest;
294 ASSERT_TRUE(audio_interface_->StartPlayback(audio));
296 // Wait for the audio callback to be called.
297 audio_callback_event_.Wait();
299 ASSERT_TRUE(audio_interface_->StopPlayback(audio));
301 // Repeat one more |StartPlayback| & |StopPlayback| cycle, and verify again
302 // that the callback function was invoked.
303 audio_callback_event_.Reset();
304 ASSERT_TRUE(audio_interface_->StartPlayback(audio));
306 // Wait for the audio callback to be called.
307 audio_callback_event_.Wait();
308 ASSERT_TRUE(audio_interface_->StopPlayback(audio));
309 test_done_ = true;
311 // If any more audio callbacks are generated, we should crash (which is good).
312 audio_callback_method_ = NULL;
314 core_interface_->ReleaseResource(audio);
316 PASS();
320 // TODO(raymes): Test that actually playback happens correctly, etc.
322 static void Crash() {
323 *static_cast<volatile unsigned*>(NULL) = 0xdeadbeef;
326 // static
327 void TestAudio::AudioCallbackTrampoline(void* sample_buffer,
328 uint32_t buffer_size_in_bytes,
329 void* user_data) {
330 TestAudio* thiz = static_cast<TestAudio*>(user_data);
332 // Crash if on the main thread.
333 if (thiz->core_interface_->IsMainThread())
334 Crash();
336 AudioCallbackMethod method = thiz->audio_callback_method_;
337 (thiz->*method)(sample_buffer, buffer_size_in_bytes);
340 void TestAudio::AudioCallbackTrivial(void* sample_buffer,
341 uint32_t buffer_size_in_bytes) {
342 memset(sample_buffer, 0, buffer_size_in_bytes);
345 void TestAudio::AudioCallbackTest(void* sample_buffer,
346 uint32_t buffer_size_in_bytes) {
347 if (test_done_)
348 Crash();
350 memset(sample_buffer, 0, buffer_size_in_bytes);
351 audio_callback_event_.Signal();