1 // Copyright 2017 The Chromium OS 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 <gtest/gtest.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <syslog.h>
9 #include <time.h>
10
11 #include <memory>
12
13 extern "C" {
14 #include "cras_iodev.h" // stubbed
15 #include "cras_rstream.h" // stubbed
16 #include "cras_shm.h"
17 #include "cras_types.h"
18 #include "dev_io.h" // tested
19 #include "dev_stream.h" // tested
20 #include "utlist.h"
21
22 struct audio_thread_event_log* atlog;
23 }
24
25 #include "dev_io_stubs.h"
26 #include "iodev_stub.h"
27 #include "metrics_stub.h"
28 #include "rstream_stub.h"
29
30 #define FAKE_POLL_FD 33
31
32 namespace {
33
34 class TimingSuite : public testing::Test {
35 protected:
SetUp()36 virtual void SetUp() {
37 atlog = static_cast<audio_thread_event_log*>(calloc(1, sizeof(*atlog)));
38 iodev_stub_reset();
39 rstream_stub_reset();
40 }
41
TearDown()42 virtual void TearDown() { free(atlog); }
43
SingleInputDevNextWake(size_t dev_cb_threshold,size_t dev_level,const timespec * level_timestamp,cras_audio_format * dev_format,const std::vector<StreamPtr> & streams,CRAS_NODE_TYPE active_node_type=CRAS_NODE_TYPE_MIC)44 timespec SingleInputDevNextWake(
45 size_t dev_cb_threshold,
46 size_t dev_level,
47 const timespec* level_timestamp,
48 cras_audio_format* dev_format,
49 const std::vector<StreamPtr>& streams,
50 CRAS_NODE_TYPE active_node_type = CRAS_NODE_TYPE_MIC) {
51 struct open_dev* dev_list_ = NULL;
52
53 DevicePtr dev = create_device(CRAS_STREAM_INPUT, dev_cb_threshold,
54 dev_format, active_node_type);
55 dev->dev->input_streaming = true;
56 DL_APPEND(dev_list_, dev->odev.get());
57
58 for (auto const& stream : streams) {
59 add_stream_to_dev(dev->dev, stream);
60 }
61
62 // Set response for frames_queued.
63 iodev_stub_frames_queued(dev->dev.get(), dev_level, *level_timestamp);
64
65 dev_io_send_captured_samples(dev_list_);
66
67 struct timespec dev_time;
68 dev_time.tv_sec = level_timestamp->tv_sec + 500; // Far in the future.
69 dev_io_next_input_wake(&dev_list_, &dev_time);
70 return dev_time;
71 }
72
SingleOutputDevNextWake(size_t dev_cb_threshold,size_t dev_level,const timespec * level_timestamp,cras_audio_format * dev_format,const std::vector<StreamPtr> & streams,const timespec * dev_wake_ts,CRAS_NODE_TYPE active_node_type=CRAS_NODE_TYPE_HEADPHONE)73 timespec SingleOutputDevNextWake(
74 size_t dev_cb_threshold,
75 size_t dev_level,
76 const timespec* level_timestamp,
77 cras_audio_format* dev_format,
78 const std::vector<StreamPtr>& streams,
79 const timespec* dev_wake_ts,
80 CRAS_NODE_TYPE active_node_type = CRAS_NODE_TYPE_HEADPHONE) {
81 struct open_dev* dev_list_ = NULL;
82
83 DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, dev_cb_threshold,
84 dev_format, active_node_type);
85 DL_APPEND(dev_list_, dev->odev.get());
86
87 for (auto const& stream : streams) {
88 add_stream_to_dev(dev->dev, stream);
89 }
90
91 dev->odev->wake_ts = *dev_wake_ts;
92
93 // Set response for frames_queued.
94 iodev_stub_frames_queued(dev->dev.get(), dev_level, *level_timestamp);
95
96 struct timespec dev_time, now;
97 dev_time.tv_sec = level_timestamp->tv_sec + 500; // Far in the future.
98 clock_gettime(CLOCK_MONOTONIC_RAW, &now);
99 dev_io_next_output_wake(&dev_list_, &dev_time, &now);
100 return dev_time;
101 }
102 };
103
104 extern "C" {
105 // From librt. Fix now at this time.
clock_gettime(clockid_t clk_id,struct timespec * tp)106 int clock_gettime(clockid_t clk_id, struct timespec* tp) {
107 tp->tv_sec = 12345;
108 tp->tv_nsec = 987654321;
109 return 0;
110 }
111 };
112
113 // Add a new input stream, make sure the initial next_cb_ts is 0.
TEST_F(TimingSuite,NewInputStreamInit)114 TEST_F(TimingSuite, NewInputStreamInit) {
115 struct open_dev* dev_list_ = NULL;
116
117 cras_audio_format format;
118 fill_audio_format(&format, 48000);
119 DevicePtr dev =
120 create_device(CRAS_STREAM_INPUT, 1024, &format, CRAS_NODE_TYPE_MIC);
121 DL_APPEND(dev_list_, dev->odev.get());
122 struct cras_iodev* iodev = dev->odev->dev;
123
124 ShmPtr shm = create_shm(480);
125 RstreamPtr rstream =
126 create_rstream(1, CRAS_STREAM_INPUT, 480, &format, shm.get());
127
128 dev_io_append_stream(&dev_list_, rstream.get(), &iodev, 1);
129
130 EXPECT_EQ(0, rstream->next_cb_ts.tv_sec);
131 EXPECT_EQ(0, rstream->next_cb_ts.tv_nsec);
132
133 dev_stream_destroy(iodev->streams);
134 }
135
136 // There is the pseudo code about wake up time for an input device.
137 //
138 // function set_input_dev_wake_ts(dev):
139 // wake_ts = now + 20s #rule_1
140 //
141 // cap_limit = MIN(dev_stream_capture_avail(stream)) for stream on dev
142 //
143 // for stream in dev:
144 // wake_ts = MIN(get_input_wake_time(stream, cap_limit), wake_ts)
145 // for stream on dev #rule_2
146 // if cap_limit:
147 // wake_ts = MIN(get_input_dev_max_wake_ts(dev), wake_ts) #rule_3
148 //
149 // device.wake_ts = wake_ts
150 //
151 // function get_input_wake_time(stream, cap_limit):
152 // needed_frames_from_device = dev_stream_capture_avail(stream)
153 //
154 // if needed_frames_from_device > cap_limit: #rule_4
155 // return None
156 //
157 // if stream is USE_DEV_TIMING and stream is pending reply: #rule_5
158 // return None
159 //
160 // time_for_sample = The time when device gets enough samples #rule_6
161 //
162 // wake_time_out = MAX(stream.next_cb_ts, time_for_sample) #rule_7
163 //
164 // if stream is USE_DEV_TIMING:
165 // wake_time_out = time_for_sample #rule_8
166 //
167 // return wake_time_out
168 //
169 // function get_input_dev_max_wake_ts(dev):
170 // return MAX(5ms, The time when hw_level = buffer_size / 2) #rule_9
171 //
172 //
173 // dev_stream_capture_avail: The number of frames free to be written to in a
174 // capture stream.
175 //
176 // The following unittests will check these logics.
177
178 // Test rule_1.
179 // The device wake up time should be 20s from now.
TEST_F(TimingSuite,InputWakeTimeNoStreamWithBigBufferDevice)180 TEST_F(TimingSuite, InputWakeTimeNoStreamWithBigBufferDevice) {
181 cras_audio_format format;
182 fill_audio_format(&format, 48000);
183
184 struct timespec start;
185 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
186
187 std::vector<StreamPtr> streams;
188 timespec dev_time =
189 SingleInputDevNextWake(4800000, 0, &start, &format, streams);
190
191 const timespec add_millis = {20, 0};
192 add_timespecs(&start, &add_millis);
193 EXPECT_EQ(start.tv_sec, dev_time.tv_sec);
194 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
195 }
196
197 // Test rule_2, rule_4(Stream 1), rule_7(Stream 2)
198 // Stream 1: next_cb_ts = now, cb_threshold = 480, dev_offset = 0
199 // Stream 2: next_cb_ts = now + 5s, cb_threshold = 480, dev_offset = 200
200 // Stream 1 need 480 frames and Stream 2 need 240 frames. So 240 will be the
201 // cap_limit and Stream 1 will be ignored. The next wake up time should be
202 // the next_cb_ts of stream2.
TEST_F(TimingSuite,InputWakeTimeTwoStreamsWithFramesInside)203 TEST_F(TimingSuite, InputWakeTimeTwoStreamsWithFramesInside) {
204 cras_audio_format format;
205 fill_audio_format(&format, 48000);
206 struct timespec start;
207 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
208
209 StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
210 stream1->rstream->next_cb_ts = start;
211
212 StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_INPUT, 480, &format);
213 stream2->rstream->next_cb_ts = start;
214 stream2->rstream->next_cb_ts.tv_sec += 5;
215 rstream_stub_dev_offset(stream2->rstream.get(), 1, 200);
216
217 std::vector<StreamPtr> streams;
218 streams.emplace_back(std::move(stream1));
219 streams.emplace_back(std::move(stream2));
220 timespec dev_time =
221 SingleInputDevNextWake(480000, 0, &start, &format, streams);
222
223 EXPECT_EQ(start.tv_sec + 5, dev_time.tv_sec);
224 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
225 }
226
227 // Test rule_2, rule_7
228 // Stream 1: next_cb_ts = now + 2s, cb_threshold = 480, dev_offset = 0
229 // Stream 2: next_cb_ts = now + 5s, cb_threshold = 480, dev_offset = 0
230 // The audio thread will choose the earliest next_cb_ts because the they have
231 // the same value of needed_frames_from_device. The next wake up time should
232 // be the next_cb_ts of stream1.
TEST_F(TimingSuite,InputWakeTimeTwoEmptyStreams)233 TEST_F(TimingSuite, InputWakeTimeTwoEmptyStreams) {
234 cras_audio_format format;
235 fill_audio_format(&format, 48000);
236 struct timespec start;
237 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
238
239 StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
240 stream1->rstream->next_cb_ts = start;
241 stream1->rstream->next_cb_ts.tv_sec += 2;
242
243 StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_INPUT, 480, &format);
244 stream2->rstream->next_cb_ts = start;
245 stream2->rstream->next_cb_ts.tv_sec += 5;
246
247 std::vector<StreamPtr> streams;
248 streams.emplace_back(std::move(stream1));
249 streams.emplace_back(std::move(stream2));
250 timespec dev_time =
251 SingleInputDevNextWake(480000, 0, &start, &format, streams);
252
253 EXPECT_EQ(start.tv_sec + 2, dev_time.tv_sec);
254 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
255 }
256
257 // Test rule_3.
258 // If cap_limit is zero from stream, input_dev_max_wake_ts should not
259 // be taken into account.
TEST_F(TimingSuite,InputWakeTimeOneFullStreamWithDeviceWakeUp)260 TEST_F(TimingSuite, InputWakeTimeOneFullStreamWithDeviceWakeUp) {
261 cras_audio_format format;
262 fill_audio_format(&format, 48000);
263
264 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
265
266 struct timespec start, stream_wake;
267 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
268
269 // Set the next stream wake to be 10ms from now.
270 const timespec ten_millis = {0, 10 * 1000 * 1000};
271 stream_wake = start;
272 add_timespecs(&stream_wake, &ten_millis);
273 stream->rstream->next_cb_ts = stream_wake;
274
275 // Add fake data so the stream has no room for more data.
276 AddFakeDataToStream(stream.get(), 480);
277
278 std::vector<StreamPtr> streams;
279 streams.emplace_back(std::move(stream));
280 timespec wake_time = SingleInputDevNextWake(240, 0, &start, &format, streams);
281
282 // Input device would wake at 5ms from now, but since stream cap_limit == 0
283 // the final wake_time is determined by stream.
284 EXPECT_EQ(stream_wake.tv_sec, wake_time.tv_sec);
285 EXPECT_EQ(stream_wake.tv_nsec, wake_time.tv_nsec);
286 }
287
288 // Test rule_3 and rule_9.
289 // One empty stream with small device buffer. It should wake up when there are
290 // buffer_size / 2 frames in device buffer.
TEST_F(TimingSuite,InputWakeTimeOneStreamWithDeviceWakeUp)291 TEST_F(TimingSuite, InputWakeTimeOneStreamWithDeviceWakeUp) {
292 cras_audio_format format;
293 fill_audio_format(&format, 48000);
294
295 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
296
297 struct timespec start;
298 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
299
300 // The next callback of the new stream is 0.
301 stream->rstream->next_cb_ts.tv_sec = 0;
302 stream->rstream->next_cb_ts.tv_nsec = 0;
303
304 std::vector<StreamPtr> streams;
305 streams.emplace_back(std::move(stream));
306 timespec dev_time = SingleInputDevNextWake(240, 0, &start, &format, streams);
307 // The device wake up time should be 5ms from now. At that time there are
308 // 240 frames in the device.
309 const timespec add_millis = {0, 5 * 1000 * 1000};
310 add_timespecs(&start, &add_millis);
311 EXPECT_EQ(start.tv_sec, dev_time.tv_sec);
312 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
313 }
314
315 // Test rule_5.
316 // The stream with USE_DEV_TIMING flag will be ignore if it is pending reply.
TEST_F(TimingSuite,InputWakeTimeOneStreamUsingDevTimingWithPendingReply)317 TEST_F(TimingSuite, InputWakeTimeOneStreamUsingDevTimingWithPendingReply) {
318 cras_audio_format format;
319 fill_audio_format(&format, 48000);
320
321 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
322
323 struct timespec start;
324 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
325
326 // The next callback should be ignored.
327 stream->rstream->next_cb_ts = start;
328 stream->rstream->next_cb_ts.tv_sec += 10;
329 stream->rstream->flags = USE_DEV_TIMING;
330 rstream_stub_pending_reply(stream->rstream.get(), 1);
331
332 std::vector<StreamPtr> streams;
333 streams.emplace_back(std::move(stream));
334 timespec dev_time = SingleInputDevNextWake(4800, 0, &start, &format, streams);
335
336 // The device wake up time should be 100ms from now. At that time the hw_level
337 // is buffer_size / 2.
338 const timespec add_millis = {0, 100 * 1000 * 1000};
339 add_timespecs(&start, &add_millis);
340 EXPECT_EQ(start.tv_sec, dev_time.tv_sec);
341 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
342 }
343
344 // Test rule_6.
345 // Add a new stream, the wake up time is the time when it has enough data to
346 // post.
TEST_F(TimingSuite,InputWakeTimeOneStreamWithEmptyDevice)347 TEST_F(TimingSuite, InputWakeTimeOneStreamWithEmptyDevice) {
348 cras_audio_format format;
349 fill_audio_format(&format, 48000);
350
351 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
352
353 struct timespec start;
354 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
355
356 // The next callback of the new stream is 0.
357 stream->rstream->next_cb_ts.tv_sec = 0;
358 stream->rstream->next_cb_ts.tv_nsec = 0;
359
360 std::vector<StreamPtr> streams;
361 streams.emplace_back(std::move(stream));
362 timespec dev_time = SingleInputDevNextWake(600, 0, &start, &format, streams);
363
364 // The device wake up time should be 10ms from now. At that time the
365 // stream will have 480 samples to post.
366 const timespec ten_millis = {0, 10 * 1000 * 1000};
367 add_timespecs(&start, &ten_millis);
368 EXPECT_EQ(0, streams[0]->rstream->next_cb_ts.tv_sec);
369 EXPECT_EQ(0, streams[0]->rstream->next_cb_ts.tv_nsec);
370 EXPECT_EQ(start.tv_sec, dev_time.tv_sec);
371 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
372 }
373
374 // Test rule_6.
375 // Add a new stream with enough frames in device, check the wake up time is
376 // right now.
TEST_F(TimingSuite,InputWakeTimeOneStreamWithFullDevice)377 TEST_F(TimingSuite, InputWakeTimeOneStreamWithFullDevice) {
378 cras_audio_format format;
379 fill_audio_format(&format, 48000);
380
381 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
382
383 struct timespec start;
384 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
385
386 // The next callback of the new stream is 0.
387 stream->rstream->next_cb_ts.tv_sec = 0;
388 stream->rstream->next_cb_ts.tv_nsec = 0;
389
390 // If there are enough frames in the device, we should wake up immediately.
391 std::vector<StreamPtr> streams;
392 streams.emplace_back(std::move(stream));
393 timespec dev_time =
394 SingleInputDevNextWake(480, 480, &start, &format, streams);
395 EXPECT_EQ(0, streams[0]->rstream->next_cb_ts.tv_sec);
396 EXPECT_EQ(0, streams[0]->rstream->next_cb_ts.tv_nsec);
397 EXPECT_EQ(start.tv_sec, dev_time.tv_sec);
398 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
399 }
400
401 // Test rule_8.
402 // The stream with USE_DEV_TIMING flag should wake up when it has enough frames
403 // to post.
TEST_F(TimingSuite,InputWakeTimeOneStreamUsingDevTiming)404 TEST_F(TimingSuite, InputWakeTimeOneStreamUsingDevTiming) {
405 cras_audio_format format;
406 fill_audio_format(&format, 48000);
407
408 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
409
410 struct timespec start;
411 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
412
413 // The next callback should be ignored.
414 stream->rstream->next_cb_ts = start;
415 stream->rstream->next_cb_ts.tv_sec += 10;
416 stream->rstream->flags = USE_DEV_TIMING;
417
418 std::vector<StreamPtr> streams;
419 streams.emplace_back(std::move(stream));
420 timespec dev_time = SingleInputDevNextWake(600, 0, &start, &format, streams);
421
422 // The device wake up time should be 10ms from now. At that time the
423 // stream will have 480 samples to post.
424 const timespec add_millis = {0, 10 * 1000 * 1000};
425 add_timespecs(&start, &add_millis);
426 EXPECT_EQ(start.tv_sec, dev_time.tv_sec);
427 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
428 }
429
430 // Test rule_9.
431 // The device wake up time should be 10ms from now. At that time the hw_level
432 // is buffer_size / 2.
TEST_F(TimingSuite,InputWakeTimeNoStreamSmallBufferDevice)433 TEST_F(TimingSuite, InputWakeTimeNoStreamSmallBufferDevice) {
434 cras_audio_format format;
435 fill_audio_format(&format, 48000);
436
437 struct timespec start;
438 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
439
440 std::vector<StreamPtr> streams;
441 timespec dev_time = SingleInputDevNextWake(480, 0, &start, &format, streams);
442
443 const timespec add_millis = {0, 10 * 1000 * 1000};
444 add_timespecs(&start, &add_millis);
445 EXPECT_EQ(start.tv_sec, dev_time.tv_sec);
446 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
447 }
448
449 // Test rule_9.
450 // There are more than buffer_size / 2 frames in the device. The device needs
451 // to sleep at least 5ms.
TEST_F(TimingSuite,InputWakeTimeOneStreamWithEnoughFramesInDevice)452 TEST_F(TimingSuite, InputWakeTimeOneStreamWithEnoughFramesInDevice) {
453 cras_audio_format format;
454 fill_audio_format(&format, 48000);
455
456 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
457
458 struct timespec start;
459 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
460
461 // Make next_cb_ts far from now.
462 stream->rstream->next_cb_ts = start;
463 stream->rstream->next_cb_ts.tv_sec += 10;
464
465 std::vector<StreamPtr> streams;
466 streams.emplace_back(std::move(stream));
467 timespec dev_time =
468 SingleInputDevNextWake(480, 480, &start, &format, streams);
469
470 const timespec add_millis = {0, 5 * 1000 * 1000};
471 add_timespecs(&start, &add_millis);
472 EXPECT_EQ(start.tv_sec, dev_time.tv_sec);
473 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
474 }
475
476 // One device, one stream, write a callback of data and check the sleep time is
477 // one more wakeup interval.
TEST_F(TimingSuite,WaitAfterFill)478 TEST_F(TimingSuite, WaitAfterFill) {
479 const size_t cb_threshold = 480;
480
481 cras_audio_format format;
482 fill_audio_format(&format, 48000);
483
484 StreamPtr stream =
485 create_stream(1, 1, CRAS_STREAM_INPUT, cb_threshold, &format);
486 // rstream's next callback is now and there is enough data to fill.
487 struct timespec start;
488 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
489 stream->rstream->next_cb_ts = start;
490 AddFakeDataToStream(stream.get(), 480);
491
492 std::vector<StreamPtr> streams;
493 streams.emplace_back(std::move(stream));
494 timespec dev_time =
495 SingleInputDevNextWake(cb_threshold, 0, &start, &format, streams);
496
497 // The next callback should be scheduled 10ms in the future.
498 // And the next wake up should reflect the only attached stream.
499 const timespec ten_millis = {0, 10 * 1000 * 1000};
500 add_timespecs(&start, &ten_millis);
501 EXPECT_EQ(start.tv_sec, streams[0]->rstream->next_cb_ts.tv_sec);
502 EXPECT_EQ(start.tv_nsec, streams[0]->rstream->next_cb_ts.tv_nsec);
503 EXPECT_EQ(dev_time.tv_sec, streams[0]->rstream->next_cb_ts.tv_sec);
504 EXPECT_EQ(dev_time.tv_nsec, streams[0]->rstream->next_cb_ts.tv_nsec);
505 }
506
507 // One device with one stream which has block_size larger than the device buffer
508 // level. If the device buffer level = 0, the input device wake time should be
509 // set to (buffer_size / 2) / device_rate secs.
TEST_F(TimingSuite,LargeCallbackStreamWithEmptyBuffer)510 TEST_F(TimingSuite, LargeCallbackStreamWithEmptyBuffer) {
511 const size_t cb_threshold = 3000;
512 const size_t dev_cb_threshold = 1200;
513 const size_t dev_level = 0;
514
515 cras_audio_format format;
516 fill_audio_format(&format, 48000);
517
518 StreamPtr stream =
519 create_stream(1, 1, CRAS_STREAM_INPUT, cb_threshold, &format);
520 struct timespec start;
521 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
522 stream->rstream->next_cb_ts = start;
523
524 std::vector<StreamPtr> streams;
525 streams.emplace_back(std::move(stream));
526 timespec dev_time = SingleInputDevNextWake(dev_cb_threshold, dev_level,
527 &start, &format, streams);
528
529 struct timespec delta;
530 subtract_timespecs(&dev_time, &start, &delta);
531 // The next dev wake ts should be 25ms since the buffer level is empty and
532 // 1200 / 48000 = 0.025.
533 EXPECT_EQ(delta.tv_sec, 0);
534 EXPECT_LT(delta.tv_nsec, 25000000 + 5000 * 1000);
535 EXPECT_GT(delta.tv_nsec, 25000000 - 5000 * 1000);
536 }
537
538 // One device with one stream which has block_size larger than the device buffer
539 // level. If the device buffer level = buffer_size / 2, the input device wake
540 // time should be set to max(0, 5ms) = 5ms to prevent busy loop occurs.
TEST_F(TimingSuite,LargeCallbackStreamWithHalfFullBuffer)541 TEST_F(TimingSuite, LargeCallbackStreamWithHalfFullBuffer) {
542 const size_t cb_threshold = 3000;
543 const size_t dev_cb_threshold = 1200;
544 const size_t dev_level = 1200;
545
546 cras_audio_format format;
547 fill_audio_format(&format, 48000);
548
549 StreamPtr stream =
550 create_stream(1, 1, CRAS_STREAM_INPUT, cb_threshold, &format);
551 struct timespec start;
552 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
553 stream->rstream->next_cb_ts = start;
554
555 std::vector<StreamPtr> streams;
556 streams.emplace_back(std::move(stream));
557 timespec dev_time = SingleInputDevNextWake(dev_cb_threshold, dev_level,
558 &start, &format, streams);
559
560 struct timespec delta;
561 subtract_timespecs(&dev_time, &start, &delta);
562 // The next dev wake ts should be 5ms since the buffer level is half full.
563 EXPECT_EQ(delta.tv_sec, 0);
564 EXPECT_LT(delta.tv_nsec, 5000000 + 5000 * 1000);
565 EXPECT_GT(delta.tv_nsec, 5000000 - 5000 * 1000);
566 }
567
568 // One device(48k), one stream(44.1k), write a callback of data and check that
569 // the sleep time is correct when doing SRC.
TEST_F(TimingSuite,WaitAfterFillSRC)570 TEST_F(TimingSuite, WaitAfterFillSRC) {
571 cras_audio_format dev_format;
572 fill_audio_format(&dev_format, 48000);
573 cras_audio_format stream_format;
574 fill_audio_format(&stream_format, 44100);
575
576 StreamPtr stream =
577 create_stream(1, 1, CRAS_STREAM_INPUT, 441, &stream_format);
578 // rstream's next callback is now and there is enough data to fill.
579 struct timespec start;
580 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
581 stream->rstream->next_cb_ts = start;
582 AddFakeDataToStream(stream.get(), 441);
583
584 std::vector<StreamPtr> streams;
585 streams.emplace_back(std::move(stream));
586 timespec dev_time =
587 SingleInputDevNextWake(480, 0, &start, &dev_format, streams);
588
589 // The next callback should be scheduled 10ms in the future.
590 struct timespec delta;
591 subtract_timespecs(&dev_time, &start, &delta);
592 EXPECT_LT(9900 * 1000, delta.tv_nsec);
593 EXPECT_GT(10100 * 1000, delta.tv_nsec);
594 }
595
596 // One device, two streams. One stream is ready the other still needs data.
597 // Checks that the sleep interval is based on the time the device will take to
598 // supply the needed samples for stream2.
TEST_F(TimingSuite,WaitTwoStreamsSameFormat)599 TEST_F(TimingSuite, WaitTwoStreamsSameFormat) {
600 const size_t cb_threshold = 480;
601
602 cras_audio_format format;
603 fill_audio_format(&format, 48000);
604
605 // stream1's next callback is now and there is enough data to fill.
606 StreamPtr stream1 =
607 create_stream(1, 1, CRAS_STREAM_INPUT, cb_threshold, &format);
608 struct timespec start;
609 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
610 stream1->rstream->next_cb_ts = start;
611 AddFakeDataToStream(stream1.get(), cb_threshold);
612
613 // stream2 is only half full.
614 StreamPtr stream2 =
615 create_stream(1, 1, CRAS_STREAM_INPUT, cb_threshold, &format);
616 stream2->rstream->next_cb_ts = start;
617 AddFakeDataToStream(stream2.get(), 240);
618
619 std::vector<StreamPtr> streams;
620 streams.emplace_back(std::move(stream1));
621 streams.emplace_back(std::move(stream2));
622 timespec dev_time =
623 SingleInputDevNextWake(cb_threshold, 0, &start, &format, streams);
624
625 // Should wait for approximately 5 milliseconds for 240 samples at 48k.
626 struct timespec delta2;
627 subtract_timespecs(&dev_time, &start, &delta2);
628 EXPECT_LT(4900 * 1000, delta2.tv_nsec);
629 EXPECT_GT(5100 * 1000, delta2.tv_nsec);
630 }
631
632 // One device(44.1), two streams(44.1, 48). One stream is ready the other still
633 // needs data. Checks that the sleep interval is based on the time the device
634 // will take to supply the needed samples for stream2, stream2 is sample rate
635 // converted from the 44.1k device to the 48k stream.
TEST_F(TimingSuite,WaitTwoStreamsDifferentRates)636 TEST_F(TimingSuite, WaitTwoStreamsDifferentRates) {
637 cras_audio_format s1_format, s2_format;
638 fill_audio_format(&s1_format, 44100);
639 fill_audio_format(&s2_format, 48000);
640
641 // stream1's next callback is now and there is enough data to fill.
642 StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_INPUT, 441, &s1_format);
643 struct timespec start;
644 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
645 stream1->rstream->next_cb_ts = start;
646 AddFakeDataToStream(stream1.get(), 441);
647 // stream2's next callback is now but there is only half a callback of data.
648 StreamPtr stream2 = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &s2_format);
649 stream2->rstream->next_cb_ts = start;
650 AddFakeDataToStream(stream2.get(), 240);
651
652 std::vector<StreamPtr> streams;
653 streams.emplace_back(std::move(stream1));
654 streams.emplace_back(std::move(stream2));
655 timespec dev_time =
656 SingleInputDevNextWake(441, 0, &start, &s1_format, streams);
657
658 // Should wait for approximately 5 milliseconds for 240 48k samples from the
659 // 44.1k device.
660 struct timespec delta2;
661 subtract_timespecs(&dev_time, &start, &delta2);
662 EXPECT_LT(4900 * 1000, delta2.tv_nsec);
663 EXPECT_GT(5100 * 1000, delta2.tv_nsec);
664 }
665
666 // One device, two streams. Both streams get a full callback of data and the
667 // device has enough samples for the next callback already. Checks that the
668 // shorter of the two streams times is used for the next sleep interval.
TEST_F(TimingSuite,WaitTwoStreamsDifferentWakeupTimes)669 TEST_F(TimingSuite, WaitTwoStreamsDifferentWakeupTimes) {
670 cras_audio_format s1_format, s2_format;
671 fill_audio_format(&s1_format, 44100);
672 fill_audio_format(&s2_format, 48000);
673
674 struct timespec start;
675 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
676
677 // stream1's next callback is in 3ms.
678 StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_INPUT, 441, &s1_format);
679 stream1->rstream->next_cb_ts = start;
680 const timespec three_millis = {0, 3 * 1000 * 1000};
681 add_timespecs(&stream1->rstream->next_cb_ts, &three_millis);
682 AddFakeDataToStream(stream1.get(), 441);
683 // stream2 is also ready next cb in 5ms..
684 StreamPtr stream2 = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &s2_format);
685 stream2->rstream->next_cb_ts = start;
686 const timespec five_millis = {0, 5 * 1000 * 1000};
687 add_timespecs(&stream2->rstream->next_cb_ts, &five_millis);
688 AddFakeDataToStream(stream1.get(), 480);
689
690 std::vector<StreamPtr> streams;
691 streams.emplace_back(std::move(stream1));
692 streams.emplace_back(std::move(stream2));
693 timespec dev_time =
694 SingleInputDevNextWake(441, 441, &start, &s1_format, streams);
695
696 // Should wait for approximately 3 milliseconds for stream 1 first.
697 struct timespec delta2;
698 subtract_timespecs(&dev_time, &start, &delta2);
699 EXPECT_LT(2900 * 1000, delta2.tv_nsec);
700 EXPECT_GT(3100 * 1000, delta2.tv_nsec);
701 }
702
703 // One hotword stream attaches to hotword device. Input data has copied from
704 // device to stream but total number is less than cb_threshold. Hotword stream
705 // should be scheduled wake base on the samples needed to fill full shm.
TEST_F(TimingSuite,HotwordStreamUseDevTiming)706 TEST_F(TimingSuite, HotwordStreamUseDevTiming) {
707 cras_audio_format fmt;
708 fill_audio_format(&fmt, 48000);
709
710 struct timespec start, delay;
711 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
712
713 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 240, &fmt);
714 stream->rstream->flags = HOTWORD_STREAM;
715 stream->rstream->next_cb_ts = start;
716 delay.tv_sec = 0;
717 delay.tv_nsec = 3 * 1000 * 1000;
718 add_timespecs(&stream->rstream->next_cb_ts, &delay);
719
720 // Add fake data to stream and device so its slightly less than cb_threshold.
721 // Expect to wait for samples to fill the full buffer (480 - 192) frames
722 // instead of using the next_cb_ts.
723 AddFakeDataToStream(stream.get(), 192);
724 std::vector<StreamPtr> streams;
725 streams.emplace_back(std::move(stream));
726 timespec dev_time = SingleInputDevNextWake(4096, 0, &start, &fmt, streams);
727 struct timespec delta;
728 subtract_timespecs(&dev_time, &start, &delta);
729 // 288 frames worth of time = 6 ms.
730 EXPECT_EQ(6 * 1000 * 1000, delta.tv_nsec);
731 }
732
733 // One hotword stream attaches to hotword device. Input data burst to a number
734 // larger than cb_threshold. Also, stream is pending client reply.
735 // In this case stream fd is used to poll for next wake.
736 // And the dev wake time is unchanged from the default 20 seconds limit.
TEST_F(TimingSuite,HotwordStreamBulkDataIsPending)737 TEST_F(TimingSuite, HotwordStreamBulkDataIsPending) {
738 int poll_fd = 0;
739 cras_audio_format fmt;
740 fill_audio_format(&fmt, 48000);
741
742 struct timespec start;
743 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
744
745 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 240, &fmt);
746 stream->rstream->flags = HOTWORD_STREAM;
747 stream->rstream->next_cb_ts = start;
748
749 AddFakeDataToStream(stream.get(), 480);
750 std::vector<StreamPtr> streams;
751 streams.emplace_back(std::move(stream));
752 // Stream is pending the reply from client.
753 rstream_stub_pending_reply(streams[0]->rstream.get(), 1);
754
755 // There is more than 1 cb_threshold of data in device.
756 timespec dev_time = SingleInputDevNextWake(4096, 7000, &start, &fmt, streams,
757 CRAS_NODE_TYPE_HOTWORD);
758
759 // Need to wait for stream fd in the next ppoll.
760 poll_fd = dev_stream_poll_stream_fd(streams[0]->dstream.get());
761 EXPECT_EQ(FAKE_POLL_FD, poll_fd);
762
763 struct timespec delta;
764 subtract_timespecs(&dev_time, &start, &delta);
765 // Wake up time should be default 20 seconds because audio thread
766 // depends on reply from client to wake it up.
767 EXPECT_LT(19, delta.tv_sec);
768 EXPECT_GT(21, delta.tv_sec);
769 }
770
771 // One hotword stream attaches to hotword device. Input data burst to a number
772 // larger than cb_threshold. However, stream is not pending client reply.
773 // This happens if there was no data during capture_to_stream.
774 // In this case stream fd is NOT used to poll for next wake.
775 // And the dev wake time is changed to a 0 instead of default 20 seconds.
TEST_F(TimingSuite,HotwordStreamBulkDataIsNotPending)776 TEST_F(TimingSuite, HotwordStreamBulkDataIsNotPending) {
777 int poll_fd = 0;
778 cras_audio_format fmt;
779 fill_audio_format(&fmt, 48000);
780
781 struct timespec start;
782 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
783
784 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_INPUT, 240, &fmt);
785 stream->rstream->flags = HOTWORD_STREAM;
786 stream->rstream->next_cb_ts = start;
787
788 AddFakeDataToStream(stream.get(), 480);
789 std::vector<StreamPtr> streams;
790 streams.emplace_back(std::move(stream));
791 // Stream is not pending the reply from client.
792 rstream_stub_pending_reply(streams[0]->rstream.get(), 0);
793
794 // There is more than 1 cb_threshold of data in device.
795 timespec dev_time = SingleInputDevNextWake(4096, 7000, &start, &fmt, streams);
796
797 // Does not need to wait for stream fd in the next ppoll.
798 poll_fd = dev_stream_poll_stream_fd(streams[0]->dstream.get());
799 EXPECT_EQ(-1, poll_fd);
800
801 struct timespec delta;
802 subtract_timespecs(&dev_time, &start, &delta);
803 // Wake up time should be very small because there is enough
804 // data to be send to client.
805 EXPECT_LT(delta.tv_sec, 0.1);
806 }
807
808 // When a new output stream is added, there are two rules to determine the
809 // initial next_cb_ts.
810 // 1. If the device already has streams, the next_cb_ts will be the earliest
811 // next callback time from these streams.
812 // 2. If there are no other streams, the next_cb_ts will be set to the time
813 // when the valid frames in device is lower than cb_threshold. (If it is
814 // already lower than cb_threshold, set next_cb_ts to now.)
815
816 // Test rule 1.
817 // The device already has streams, the next_cb_ts will be the earliest
818 // next_cb_ts from these streams.
TEST_F(TimingSuite,NewOutputStreamInitStreamInDevice)819 TEST_F(TimingSuite, NewOutputStreamInitStreamInDevice) {
820 struct open_dev* dev_list_ = NULL;
821
822 cras_audio_format format;
823 fill_audio_format(&format, 48000);
824 DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
825 CRAS_NODE_TYPE_HEADPHONE);
826 DL_APPEND(dev_list_, dev->odev.get());
827 struct cras_iodev* iodev = dev->odev->dev;
828
829 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
830 add_stream_to_dev(dev->dev, stream);
831 stream->rstream->next_cb_ts.tv_sec = 54321;
832 stream->rstream->next_cb_ts.tv_nsec = 12345;
833
834 ShmPtr shm = create_shm(480);
835 RstreamPtr rstream =
836 create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
837
838 dev_io_append_stream(&dev_list_, rstream.get(), &iodev, 1);
839
840 EXPECT_EQ(stream->rstream->next_cb_ts.tv_sec, rstream->next_cb_ts.tv_sec);
841 EXPECT_EQ(stream->rstream->next_cb_ts.tv_nsec, rstream->next_cb_ts.tv_nsec);
842
843 dev_stream_destroy(iodev->streams->next);
844 }
845
846 // Test rule 2.
847 // The there are no streams and no frames in device buffer. The next_cb_ts
848 // will be set to now.
TEST_F(TimingSuite,NewOutputStreamInitNoStreamNoFramesInDevice)849 TEST_F(TimingSuite, NewOutputStreamInitNoStreamNoFramesInDevice) {
850 struct open_dev* dev_list_ = NULL;
851
852 cras_audio_format format;
853 fill_audio_format(&format, 48000);
854 DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
855 CRAS_NODE_TYPE_HEADPHONE);
856 DL_APPEND(dev_list_, dev->odev.get());
857 struct cras_iodev* iodev = dev->odev->dev;
858
859 struct timespec start;
860 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
861
862 ShmPtr shm = create_shm(480);
863 RstreamPtr rstream =
864 create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
865
866 dev_io_append_stream(&dev_list_, rstream.get(), &iodev, 1);
867
868 EXPECT_EQ(start.tv_sec, rstream->next_cb_ts.tv_sec);
869 EXPECT_EQ(start.tv_nsec, rstream->next_cb_ts.tv_nsec);
870
871 dev_stream_destroy(iodev->streams);
872 }
873
874 // Test rule 2.
875 // The there are no streams and some valid frames in device buffer. The
876 // next_cb_ts will be set to the time that valid frames in device is lower
877 // than cb_threshold.
TEST_F(TimingSuite,NewOutputStreamInitNoStreamSomeFramesInDevice)878 TEST_F(TimingSuite, NewOutputStreamInitNoStreamSomeFramesInDevice) {
879 struct open_dev* dev_list_ = NULL;
880
881 cras_audio_format format;
882 fill_audio_format(&format, 48000);
883 DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
884 CRAS_NODE_TYPE_HEADPHONE);
885 DL_APPEND(dev_list_, dev->odev.get());
886 struct cras_iodev* iodev = dev->odev->dev;
887
888 struct timespec start;
889 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
890
891 iodev_stub_valid_frames(iodev, 960, start);
892
893 ShmPtr shm = create_shm(480);
894 RstreamPtr rstream =
895 create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
896
897 dev_io_append_stream(&dev_list_, rstream.get(), &iodev, 1);
898
899 // The next_cb_ts should be 10ms from now. At that time there are
900 // only 480 valid frames in the device.
901 const timespec add_millis = {0, 10 * 1000 * 1000};
902 add_timespecs(&start, &add_millis);
903 EXPECT_EQ(start.tv_sec, rstream->next_cb_ts.tv_sec);
904 EXPECT_EQ(start.tv_nsec, rstream->next_cb_ts.tv_nsec);
905
906 dev_stream_destroy(iodev->streams);
907 }
908
909 // There is the pseudo code about wake up time for a output device.
910 //
911 // function dev_io_next_output_wake(dev):
912 // wake_ts = get_next_stream_wake_from_list(dev.streams)
913 // if cras_iodev_odev_should_wake(dev):
914 // wake_ts = MIN(wake_ts, dev.wake_ts) # rule_1
915 //
916 // function get_next_stream_wake_from_list(streams):
917 // for stream in streams:
918 // if stream is draining: # rule_2
919 // continue
920 // if stream is pending reply: # rule_3
921 // continue
922 // if stream is USE_DEV_TIMING: # rule_4
923 // continue
924 // min_ts = MIN(min_ts, stream.next_cb_ts) # rule_5
925 // return min_ts
926 //
927 // # This function is in iodev so we don't test its logic here.
928 // function cras_iodev_odev_should_wake(dev):
929 // if dev.is_free_running:
930 // return False
931 // if dev.state == NORMAL_RUN or dev.state == NO_STREAM_RUN:
932 // return True
933 // return False
934
935 // Test rule_1.
936 // The wake up time should be the earlier time amoung streams and devices.
TEST_F(TimingSuite,OutputWakeTimeOneStreamWithEarlierStreamWakeTime)937 TEST_F(TimingSuite, OutputWakeTimeOneStreamWithEarlierStreamWakeTime) {
938 cras_audio_format format;
939 fill_audio_format(&format, 48000);
940 struct timespec start;
941 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
942
943 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
944 stream->rstream->next_cb_ts = start;
945 stream->rstream->next_cb_ts.tv_sec += 1;
946
947 std::vector<StreamPtr> streams;
948 streams.emplace_back(std::move(stream));
949
950 struct timespec dev_wake_ts = start;
951 dev_wake_ts.tv_sec += 2;
952
953 timespec dev_time =
954 SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
955
956 EXPECT_EQ(start.tv_sec + 1, dev_time.tv_sec);
957 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
958 }
959
960 // Test rule_1.
961 // The wake up time should be the earlier time amoung streams and devices.
TEST_F(TimingSuite,OutputWakeTimeOneStreamWithEarlierDeviceWakeTime)962 TEST_F(TimingSuite, OutputWakeTimeOneStreamWithEarlierDeviceWakeTime) {
963 cras_audio_format format;
964 fill_audio_format(&format, 48000);
965 struct timespec start;
966 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
967
968 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
969 stream->rstream->next_cb_ts = start;
970 stream->rstream->next_cb_ts.tv_sec += 2;
971
972 std::vector<StreamPtr> streams;
973 streams.emplace_back(std::move(stream));
974
975 struct timespec dev_wake_ts = start;
976 dev_wake_ts.tv_sec += 1;
977
978 timespec dev_time =
979 SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
980
981 EXPECT_EQ(start.tv_sec + 1, dev_time.tv_sec);
982 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
983 }
984
985 // Test rule_2.
986 // The stream 1 is draining so it will be ignored. The wake up time should be
987 // the next_cb_ts of stream 2.
TEST_F(TimingSuite,OutputWakeTimeTwoStreamsWithOneIsDraining)988 TEST_F(TimingSuite, OutputWakeTimeTwoStreamsWithOneIsDraining) {
989 cras_audio_format format;
990 fill_audio_format(&format, 48000);
991 struct timespec start;
992 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
993
994 StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
995 stream1->rstream->next_cb_ts = start;
996 stream1->rstream->next_cb_ts.tv_sec += 2;
997 stream1->rstream->is_draining = 1;
998 stream1->rstream->queued_frames = 480;
999
1000 StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_OUTPUT, 480, &format);
1001 stream2->rstream->next_cb_ts = start;
1002 stream2->rstream->next_cb_ts.tv_sec += 5;
1003
1004 std::vector<StreamPtr> streams;
1005 streams.emplace_back(std::move(stream1));
1006 streams.emplace_back(std::move(stream2));
1007
1008 struct timespec dev_wake_ts = start;
1009 dev_wake_ts.tv_sec += 10;
1010
1011 timespec dev_time =
1012 SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1013
1014 EXPECT_EQ(start.tv_sec + 5, dev_time.tv_sec);
1015 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1016 }
1017
1018 // Test rule_3.
1019 // The stream 1 is pending reply so it will be ignored. The wake up time should
1020 // be the next_cb_ts of stream 2.
TEST_F(TimingSuite,OutputWakeTimeTwoStreamsWithOneIsPendingReply)1021 TEST_F(TimingSuite, OutputWakeTimeTwoStreamsWithOneIsPendingReply) {
1022 cras_audio_format format;
1023 fill_audio_format(&format, 48000);
1024 struct timespec start;
1025 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1026
1027 StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1028 stream1->rstream->next_cb_ts = start;
1029 stream1->rstream->next_cb_ts.tv_sec += 2;
1030 rstream_stub_pending_reply(stream1->rstream.get(), 1);
1031
1032 StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_OUTPUT, 480, &format);
1033 stream2->rstream->next_cb_ts = start;
1034 stream2->rstream->next_cb_ts.tv_sec += 5;
1035
1036 std::vector<StreamPtr> streams;
1037 streams.emplace_back(std::move(stream1));
1038 streams.emplace_back(std::move(stream2));
1039
1040 struct timespec dev_wake_ts = start;
1041 dev_wake_ts.tv_sec += 10;
1042
1043 timespec dev_time =
1044 SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1045
1046 EXPECT_EQ(start.tv_sec + 5, dev_time.tv_sec);
1047 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1048 }
1049
1050 // Test rule_4.
1051 // The stream 1 is uning device timing so it will be ignored. The wake up time
1052 // should be the next_cb_ts of stream 2.
TEST_F(TimingSuite,OutputWakeTimeTwoStreamsWithOneIsUsingDevTiming)1053 TEST_F(TimingSuite, OutputWakeTimeTwoStreamsWithOneIsUsingDevTiming) {
1054 cras_audio_format format;
1055 fill_audio_format(&format, 48000);
1056 struct timespec start;
1057 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1058
1059 StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1060 stream1->rstream->next_cb_ts = start;
1061 stream1->rstream->next_cb_ts.tv_sec += 2;
1062 stream1->rstream->flags = USE_DEV_TIMING;
1063
1064 StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_OUTPUT, 480, &format);
1065 stream2->rstream->next_cb_ts = start;
1066 stream2->rstream->next_cb_ts.tv_sec += 5;
1067
1068 std::vector<StreamPtr> streams;
1069 streams.emplace_back(std::move(stream1));
1070 streams.emplace_back(std::move(stream2));
1071
1072 struct timespec dev_wake_ts = start;
1073 dev_wake_ts.tv_sec += 10;
1074
1075 timespec dev_time =
1076 SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1077
1078 EXPECT_EQ(start.tv_sec + 5, dev_time.tv_sec);
1079 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1080 }
1081
1082 // Test rule_5.
1083 // The wake up time should be the next_cb_ts of streams.
TEST_F(TimingSuite,OutputWakeTimeTwoStreams)1084 TEST_F(TimingSuite, OutputWakeTimeTwoStreams) {
1085 cras_audio_format format;
1086 fill_audio_format(&format, 48000);
1087 struct timespec start;
1088 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1089
1090 StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1091 stream1->rstream->next_cb_ts = start;
1092 stream1->rstream->next_cb_ts.tv_sec += 2;
1093
1094 StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_OUTPUT, 480, &format);
1095 stream2->rstream->next_cb_ts = start;
1096 stream2->rstream->next_cb_ts.tv_sec += 5;
1097
1098 std::vector<StreamPtr> streams;
1099 streams.emplace_back(std::move(stream1));
1100 streams.emplace_back(std::move(stream2));
1101
1102 struct timespec dev_wake_ts = start;
1103 dev_wake_ts.tv_sec += 10;
1104
1105 timespec dev_time =
1106 SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1107
1108 EXPECT_EQ(start.tv_sec + 2, dev_time.tv_sec);
1109 EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1110 }
1111
1112 // One device, one stream, fetch stream and check the sleep time is one more
1113 // wakeup interval.
TEST_F(TimingSuite,OutputStreamsUpdateAfterFetching)1114 TEST_F(TimingSuite, OutputStreamsUpdateAfterFetching) {
1115 cras_audio_format format;
1116 fill_audio_format(&format, 48000);
1117
1118 StreamPtr stream = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1119
1120 // rstream's next callback is now.
1121 struct timespec start;
1122 clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1123 stream->rstream->next_cb_ts = start;
1124
1125 struct open_dev* dev_list_ = NULL;
1126
1127 DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
1128 CRAS_NODE_TYPE_HEADPHONE);
1129 DL_APPEND(dev_list_, dev->odev.get());
1130
1131 add_stream_to_dev(dev->dev, stream);
1132
1133 dev_io_playback_fetch(dev_list_);
1134
1135 // The next callback should be scheduled 10ms in the future.
1136 const timespec ten_millis = {0, 10 * 1000 * 1000};
1137 add_timespecs(&start, &ten_millis);
1138 EXPECT_EQ(start.tv_sec, stream->rstream->next_cb_ts.tv_sec);
1139 EXPECT_EQ(start.tv_nsec, stream->rstream->next_cb_ts.tv_nsec);
1140 }
1141
1142 // TODO(yuhsuan): There are some time scheduling rules in cras_iodev. Maybe we
1143 // can move them into dev_io so that all timing related codes are in the same
1144 // file or leave them in iodev_unittest like now.
1145 // 1. Device's wake_ts update: cras_iodev_frames_to_play_in_sleep.
1146 // 2. wake_ts update when removing stream: cras_iodev_rm_stream.
1147
1148 /* Stubs */
1149 extern "C" {
1150
input_data_get_for_stream(struct input_data * data,struct cras_rstream * stream,struct buffer_share * offsets,struct cras_audio_area ** area,unsigned int * offset)1151 int input_data_get_for_stream(struct input_data* data,
1152 struct cras_rstream* stream,
1153 struct buffer_share* offsets,
1154 struct cras_audio_area** area,
1155 unsigned int* offset) {
1156 return 0;
1157 }
1158
input_data_put_for_stream(struct input_data * data,struct cras_rstream * stream,struct buffer_share * offsets,unsigned int frames)1159 int input_data_put_for_stream(struct input_data* data,
1160 struct cras_rstream* stream,
1161 struct buffer_share* offsets,
1162 unsigned int frames) {
1163 return 0;
1164 }
1165
cras_rstream_post_processing_format(const struct cras_rstream * stream,void * dev_ptr)1166 struct cras_audio_format* cras_rstream_post_processing_format(
1167 const struct cras_rstream* stream,
1168 void* dev_ptr) {
1169 return NULL;
1170 }
1171
cras_audio_thread_event_drop_samples()1172 int cras_audio_thread_event_drop_samples() {
1173 return 0;
1174 }
1175
1176 } // extern "C"
1177
1178 } // namespace
1179
main(int argc,char ** argv)1180 int main(int argc, char** argv) {
1181 ::testing::InitGoogleTest(&argc, argv);
1182 openlog(NULL, LOG_PERROR, LOG_USER);
1183 return RUN_ALL_TESTS();
1184 }
1185