• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
97     dev_time.tv_sec = level_timestamp->tv_sec + 500;  // Far in the future.
98     dev_io_next_output_wake(&dev_list_, &dev_time);
99     return dev_time;
100   }
101 };
102 
103 extern "C" {
104 //  From librt. Fix now at this time.
clock_gettime(clockid_t clk_id,struct timespec * tp)105 int clock_gettime(clockid_t clk_id, struct timespec* tp) {
106   tp->tv_sec = 12345;
107   tp->tv_nsec = 987654321;
108   return 0;
109 }
110 };
111 
112 // Add a new input stream, make sure the initial next_cb_ts is 0.
TEST_F(TimingSuite,NewInputStreamInit)113 TEST_F(TimingSuite, NewInputStreamInit) {
114   struct open_dev* odev_list_ = NULL;
115   struct open_dev* idev_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(idev_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(&odev_list_, &idev_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 there is a matched input stream, use the next_cb_ts and
811 //    sleep_interval_ts from that input stream as the initial values.
812 // 2. If the device already has streams, the next_cb_ts will be the earliest
813 // next callback time from these streams.
814 // 3. If there are no other streams, the next_cb_ts will be set to the time
815 // when the valid frames in device is lower than cb_threshold. (If it is
816 // already lower than cb_threshold, set next_cb_ts to now.)
817 
818 // Test rule 1.
819 // There is a matched input stream. The next_cb_ts of the newly added output
820 // stream will use the next_cb_ts from the input stream.
TEST_F(TimingSuite,NewOutputStreamInitExistMatchedStream)821 TEST_F(TimingSuite, NewOutputStreamInitExistMatchedStream) {
822   struct open_dev* odev_list_ = NULL;
823   struct open_dev* idev_list_ = NULL;
824 
825   cras_audio_format format;
826   fill_audio_format(&format, 48000);
827   DevicePtr out_dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
828                                     CRAS_NODE_TYPE_HEADPHONE);
829   DL_APPEND(odev_list_, out_dev->odev.get());
830   struct cras_iodev* out_iodev = out_dev->odev->dev;
831 
832   DevicePtr in_dev =
833       create_device(CRAS_STREAM_INPUT, 1024, &format, CRAS_NODE_TYPE_MIC);
834   DL_APPEND(idev_list_, in_dev->odev.get());
835 
836   StreamPtr in_stream = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
837   add_stream_to_dev(in_dev->dev, in_stream);
838   in_stream->rstream->next_cb_ts.tv_sec = 54321;
839   in_stream->rstream->next_cb_ts.tv_nsec = 12345;
840   in_stream->rstream->sleep_interval_ts.tv_sec = 321;
841   in_stream->rstream->sleep_interval_ts.tv_nsec = 123;
842 
843   ShmPtr shm = create_shm(480);
844   RstreamPtr rstream =
845       create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
846 
847   dev_io_append_stream(&odev_list_, &idev_list_, rstream.get(), &out_iodev, 1);
848 
849   EXPECT_EQ(in_stream->rstream->next_cb_ts.tv_sec, rstream->next_cb_ts.tv_sec);
850   EXPECT_EQ(in_stream->rstream->next_cb_ts.tv_nsec,
851             rstream->next_cb_ts.tv_nsec);
852   EXPECT_EQ(in_stream->rstream->sleep_interval_ts.tv_sec,
853             rstream->sleep_interval_ts.tv_sec);
854   EXPECT_EQ(in_stream->rstream->sleep_interval_ts.tv_nsec,
855             rstream->sleep_interval_ts.tv_nsec);
856 
857   dev_stream_destroy(out_iodev->streams);
858 }
859 
860 // Test rule 2.
861 // The device already has streams, the next_cb_ts will be the earliest
862 // next_cb_ts from these streams.
TEST_F(TimingSuite,NewOutputStreamInitStreamInDevice)863 TEST_F(TimingSuite, NewOutputStreamInitStreamInDevice) {
864   struct open_dev* odev_list_ = NULL;
865   struct open_dev* idev_list_ = NULL;
866 
867   cras_audio_format format;
868   fill_audio_format(&format, 48000);
869   DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
870                                 CRAS_NODE_TYPE_HEADPHONE);
871   DL_APPEND(odev_list_, dev->odev.get());
872   struct cras_iodev* iodev = dev->odev->dev;
873 
874   StreamPtr stream = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
875   add_stream_to_dev(dev->dev, stream);
876   stream->rstream->next_cb_ts.tv_sec = 54321;
877   stream->rstream->next_cb_ts.tv_nsec = 12345;
878 
879   ShmPtr shm = create_shm(480);
880   RstreamPtr rstream =
881       create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
882 
883   dev_io_append_stream(&odev_list_, &idev_list_, rstream.get(), &iodev, 1);
884 
885   EXPECT_EQ(stream->rstream->next_cb_ts.tv_sec, rstream->next_cb_ts.tv_sec);
886   EXPECT_EQ(stream->rstream->next_cb_ts.tv_nsec, rstream->next_cb_ts.tv_nsec);
887 
888   dev_stream_destroy(iodev->streams->next);
889 }
890 
891 // Test rule 3.
892 // The there are no streams and no frames in device buffer. The next_cb_ts
893 // will be set to now.
TEST_F(TimingSuite,NewOutputStreamInitNoStreamNoFramesInDevice)894 TEST_F(TimingSuite, NewOutputStreamInitNoStreamNoFramesInDevice) {
895   struct open_dev* odev_list_ = NULL;
896   struct open_dev* idev_list_ = NULL;
897 
898   cras_audio_format format;
899   fill_audio_format(&format, 48000);
900   DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
901                                 CRAS_NODE_TYPE_HEADPHONE);
902   DL_APPEND(odev_list_, dev->odev.get());
903   struct cras_iodev* iodev = dev->odev->dev;
904 
905   struct timespec start;
906   clock_gettime(CLOCK_MONOTONIC_RAW, &start);
907 
908   ShmPtr shm = create_shm(480);
909   RstreamPtr rstream =
910       create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
911 
912   dev_io_append_stream(&odev_list_, &idev_list_, rstream.get(), &iodev, 1);
913 
914   EXPECT_EQ(start.tv_sec, rstream->next_cb_ts.tv_sec);
915   EXPECT_EQ(start.tv_nsec, rstream->next_cb_ts.tv_nsec);
916 
917   dev_stream_destroy(iodev->streams);
918 }
919 
920 // Test rule 2.
921 // The there are no streams and some valid frames in device buffer. The
922 // next_cb_ts will be set to the time that valid frames in device is lower
923 // than cb_threshold.
TEST_F(TimingSuite,NewOutputStreamInitNoStreamSomeFramesInDevice)924 TEST_F(TimingSuite, NewOutputStreamInitNoStreamSomeFramesInDevice) {
925   struct open_dev* odev_list_ = NULL;
926   struct open_dev* idev_list_ = NULL;
927 
928   cras_audio_format format;
929   fill_audio_format(&format, 48000);
930   DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
931                                 CRAS_NODE_TYPE_HEADPHONE);
932   DL_APPEND(odev_list_, dev->odev.get());
933   struct cras_iodev* iodev = dev->odev->dev;
934 
935   struct timespec start;
936   clock_gettime(CLOCK_MONOTONIC_RAW, &start);
937 
938   iodev_stub_valid_frames(iodev, 960, start);
939 
940   ShmPtr shm = create_shm(480);
941   RstreamPtr rstream =
942       create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
943 
944   dev_io_append_stream(&odev_list_, &idev_list_, rstream.get(), &iodev, 1);
945 
946   // The next_cb_ts should be 10ms from now. At that time there are
947   // only 480 valid frames in the device.
948   const timespec add_millis = {0, 10 * 1000 * 1000};
949   add_timespecs(&start, &add_millis);
950   EXPECT_EQ(start.tv_sec, rstream->next_cb_ts.tv_sec);
951   EXPECT_EQ(start.tv_nsec, rstream->next_cb_ts.tv_nsec);
952 
953   dev_stream_destroy(iodev->streams);
954 }
955 
956 // There is the pseudo code about wake up time for a output device.
957 //
958 // function dev_io_next_output_wake(dev):
959 //   wake_ts = get_next_stream_wake_from_list(dev.streams)
960 //   if cras_iodev_odev_should_wake(dev):
961 //     wake_ts = MIN(wake_ts, dev.wake_ts) # rule_1
962 //
963 // function get_next_stream_wake_from_list(streams):
964 //   for stream in streams:
965 //     if stream is draining: # rule_2
966 //     	 continue
967 //     if stream is pending reply: # rule_3
968 //       continue
969 //     if stream is USE_DEV_TIMING: # rule_4
970 //       continue
971 //     min_ts = MIN(min_ts, stream.next_cb_ts) # rule_5
972 //   return min_ts
973 //
974 // # This function is in iodev so we don't test its logic here.
975 // function cras_iodev_odev_should_wake(dev):
976 //   if dev.is_free_running:
977 //     return False
978 //   if dev.state == NORMAL_RUN or dev.state == NO_STREAM_RUN:
979 //     return True
980 //   return False
981 
982 // Test rule_1.
983 // The wake up time should be the earlier time amoung streams and devices.
TEST_F(TimingSuite,OutputWakeTimeOneStreamWithEarlierStreamWakeTime)984 TEST_F(TimingSuite, OutputWakeTimeOneStreamWithEarlierStreamWakeTime) {
985   cras_audio_format format;
986   fill_audio_format(&format, 48000);
987   struct timespec start;
988   clock_gettime(CLOCK_MONOTONIC_RAW, &start);
989 
990   StreamPtr stream = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
991   stream->rstream->next_cb_ts = start;
992   stream->rstream->next_cb_ts.tv_sec += 1;
993 
994   std::vector<StreamPtr> streams;
995   streams.emplace_back(std::move(stream));
996 
997   struct timespec dev_wake_ts = start;
998   dev_wake_ts.tv_sec += 2;
999 
1000   timespec dev_time =
1001       SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1002 
1003   EXPECT_EQ(start.tv_sec + 1, dev_time.tv_sec);
1004   EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1005 }
1006 
1007 // Test rule_1.
1008 // The wake up time should be the earlier time amoung streams and devices.
TEST_F(TimingSuite,OutputWakeTimeOneStreamWithEarlierDeviceWakeTime)1009 TEST_F(TimingSuite, OutputWakeTimeOneStreamWithEarlierDeviceWakeTime) {
1010   cras_audio_format format;
1011   fill_audio_format(&format, 48000);
1012   struct timespec start;
1013   clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1014 
1015   StreamPtr stream = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1016   stream->rstream->next_cb_ts = start;
1017   stream->rstream->next_cb_ts.tv_sec += 2;
1018 
1019   std::vector<StreamPtr> streams;
1020   streams.emplace_back(std::move(stream));
1021 
1022   struct timespec dev_wake_ts = start;
1023   dev_wake_ts.tv_sec += 1;
1024 
1025   timespec dev_time =
1026       SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1027 
1028   EXPECT_EQ(start.tv_sec + 1, dev_time.tv_sec);
1029   EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1030 }
1031 
1032 // Test rule_2.
1033 // The stream 1 is draining so it will be ignored. The wake up time should be
1034 // the next_cb_ts of stream 2.
TEST_F(TimingSuite,OutputWakeTimeTwoStreamsWithOneIsDraining)1035 TEST_F(TimingSuite, OutputWakeTimeTwoStreamsWithOneIsDraining) {
1036   cras_audio_format format;
1037   fill_audio_format(&format, 48000);
1038   struct timespec start;
1039   clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1040 
1041   StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1042   stream1->rstream->next_cb_ts = start;
1043   stream1->rstream->next_cb_ts.tv_sec += 2;
1044   stream1->rstream->is_draining = 1;
1045   stream1->rstream->queued_frames = 480;
1046 
1047   StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_OUTPUT, 480, &format);
1048   stream2->rstream->next_cb_ts = start;
1049   stream2->rstream->next_cb_ts.tv_sec += 5;
1050 
1051   std::vector<StreamPtr> streams;
1052   streams.emplace_back(std::move(stream1));
1053   streams.emplace_back(std::move(stream2));
1054 
1055   struct timespec dev_wake_ts = start;
1056   dev_wake_ts.tv_sec += 10;
1057 
1058   timespec dev_time =
1059       SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1060 
1061   EXPECT_EQ(start.tv_sec + 5, dev_time.tv_sec);
1062   EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1063 }
1064 
1065 // Test rule_3.
1066 // The stream 1 is pending reply so it will be ignored. The wake up time should
1067 // be the next_cb_ts of stream 2.
TEST_F(TimingSuite,OutputWakeTimeTwoStreamsWithOneIsPendingReply)1068 TEST_F(TimingSuite, OutputWakeTimeTwoStreamsWithOneIsPendingReply) {
1069   cras_audio_format format;
1070   fill_audio_format(&format, 48000);
1071   struct timespec start;
1072   clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1073 
1074   StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1075   stream1->rstream->next_cb_ts = start;
1076   stream1->rstream->next_cb_ts.tv_sec += 2;
1077   rstream_stub_pending_reply(stream1->rstream.get(), 1);
1078 
1079   StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_OUTPUT, 480, &format);
1080   stream2->rstream->next_cb_ts = start;
1081   stream2->rstream->next_cb_ts.tv_sec += 5;
1082 
1083   std::vector<StreamPtr> streams;
1084   streams.emplace_back(std::move(stream1));
1085   streams.emplace_back(std::move(stream2));
1086 
1087   struct timespec dev_wake_ts = start;
1088   dev_wake_ts.tv_sec += 10;
1089 
1090   timespec dev_time =
1091       SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1092 
1093   EXPECT_EQ(start.tv_sec + 5, dev_time.tv_sec);
1094   EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1095 }
1096 
1097 // Test rule_4.
1098 // The stream 1 is uning device timing so it will be ignored. The wake up time
1099 // should be the next_cb_ts of stream 2.
TEST_F(TimingSuite,OutputWakeTimeTwoStreamsWithOneIsUsingDevTiming)1100 TEST_F(TimingSuite, OutputWakeTimeTwoStreamsWithOneIsUsingDevTiming) {
1101   cras_audio_format format;
1102   fill_audio_format(&format, 48000);
1103   struct timespec start;
1104   clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1105 
1106   StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1107   stream1->rstream->next_cb_ts = start;
1108   stream1->rstream->next_cb_ts.tv_sec += 2;
1109   stream1->rstream->flags = USE_DEV_TIMING;
1110 
1111   StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_OUTPUT, 480, &format);
1112   stream2->rstream->next_cb_ts = start;
1113   stream2->rstream->next_cb_ts.tv_sec += 5;
1114 
1115   std::vector<StreamPtr> streams;
1116   streams.emplace_back(std::move(stream1));
1117   streams.emplace_back(std::move(stream2));
1118 
1119   struct timespec dev_wake_ts = start;
1120   dev_wake_ts.tv_sec += 10;
1121 
1122   timespec dev_time =
1123       SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1124 
1125   EXPECT_EQ(start.tv_sec + 5, dev_time.tv_sec);
1126   EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1127 }
1128 
1129 // Test rule_5.
1130 // The wake up time should be the next_cb_ts of streams.
TEST_F(TimingSuite,OutputWakeTimeTwoStreams)1131 TEST_F(TimingSuite, OutputWakeTimeTwoStreams) {
1132   cras_audio_format format;
1133   fill_audio_format(&format, 48000);
1134   struct timespec start;
1135   clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1136 
1137   StreamPtr stream1 = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1138   stream1->rstream->next_cb_ts = start;
1139   stream1->rstream->next_cb_ts.tv_sec += 2;
1140 
1141   StreamPtr stream2 = create_stream(1, 2, CRAS_STREAM_OUTPUT, 480, &format);
1142   stream2->rstream->next_cb_ts = start;
1143   stream2->rstream->next_cb_ts.tv_sec += 5;
1144 
1145   std::vector<StreamPtr> streams;
1146   streams.emplace_back(std::move(stream1));
1147   streams.emplace_back(std::move(stream2));
1148 
1149   struct timespec dev_wake_ts = start;
1150   dev_wake_ts.tv_sec += 10;
1151 
1152   timespec dev_time =
1153       SingleOutputDevNextWake(48000, 0, &start, &format, streams, &dev_wake_ts);
1154 
1155   EXPECT_EQ(start.tv_sec + 2, dev_time.tv_sec);
1156   EXPECT_EQ(start.tv_nsec, dev_time.tv_nsec);
1157 }
1158 
1159 // One device, one stream, fetch stream and check the sleep time is one more
1160 // wakeup interval.
TEST_F(TimingSuite,OutputStreamsUpdateAfterFetching)1161 TEST_F(TimingSuite, OutputStreamsUpdateAfterFetching) {
1162   cras_audio_format format;
1163   fill_audio_format(&format, 48000);
1164 
1165   StreamPtr stream = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
1166 
1167   // rstream's next callback is now.
1168   struct timespec start;
1169   clock_gettime(CLOCK_MONOTONIC_RAW, &start);
1170   stream->rstream->next_cb_ts = start;
1171 
1172   struct open_dev* dev_list_ = NULL;
1173 
1174   DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
1175                                 CRAS_NODE_TYPE_HEADPHONE);
1176   DL_APPEND(dev_list_, dev->odev.get());
1177 
1178   add_stream_to_dev(dev->dev, stream);
1179 
1180   dev_io_playback_fetch(dev_list_);
1181 
1182   // The next callback should be scheduled 10ms in the future.
1183   const timespec ten_millis = {0, 10 * 1000 * 1000};
1184   add_timespecs(&start, &ten_millis);
1185   EXPECT_EQ(start.tv_sec, stream->rstream->next_cb_ts.tv_sec);
1186   EXPECT_EQ(start.tv_nsec, stream->rstream->next_cb_ts.tv_nsec);
1187 }
1188 
1189 // TODO(yuhsuan): There are some time scheduling rules in cras_iodev. Maybe we
1190 // can move them into dev_io so that all timing related codes are in the same
1191 // file or leave them in iodev_unittest like now.
1192 // 1. Device's wake_ts update: cras_iodev_frames_to_play_in_sleep.
1193 // 2. wake_ts update when removing stream: cras_iodev_rm_stream.
1194 
1195 /* Stubs */
1196 extern "C" {
1197 
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)1198 int input_data_get_for_stream(struct input_data* data,
1199                               struct cras_rstream* stream,
1200                               struct buffer_share* offsets,
1201                               struct cras_audio_area** area,
1202                               unsigned int* offset) {
1203   return 0;
1204 }
1205 
input_data_put_for_stream(struct input_data * data,struct cras_rstream * stream,struct buffer_share * offsets,unsigned int frames)1206 int input_data_put_for_stream(struct input_data* data,
1207                               struct cras_rstream* stream,
1208                               struct buffer_share* offsets,
1209                               unsigned int frames) {
1210   return 0;
1211 }
1212 
input_data_get_software_gain_scaler(struct input_data * data,float idev_sw_gain_scaler,struct cras_rstream * stream)1213 float input_data_get_software_gain_scaler(struct input_data* data,
1214                                           float idev_sw_gain_scaler,
1215                                           struct cras_rstream* stream) {
1216   return 1.0;
1217 }
1218 
cras_rstream_post_processing_format(const struct cras_rstream * stream,void * dev_ptr)1219 struct cras_audio_format* cras_rstream_post_processing_format(
1220     const struct cras_rstream* stream,
1221     void* dev_ptr) {
1222   return NULL;
1223 }
1224 
cras_audio_thread_event_drop_samples()1225 int cras_audio_thread_event_drop_samples() {
1226   return 0;
1227 }
1228 
cras_audio_thread_event_severe_underrun()1229 int cras_audio_thread_event_severe_underrun() {
1230   return 0;
1231 }
1232 
buffer_share_get_data(const struct buffer_share * mix,unsigned int id)1233 void* buffer_share_get_data(const struct buffer_share* mix, unsigned int id) {
1234   return NULL;
1235 };
cras_apm_list_start_apm(struct cras_apm_list * list,void * dev_ptr)1236 void cras_apm_list_start_apm(struct cras_apm_list* list, void* dev_ptr){};
cras_apm_list_stop_apm(struct cras_apm_list * list,void * dev_ptr)1237 void cras_apm_list_stop_apm(struct cras_apm_list* list, void* dev_ptr){};
1238 }  // extern "C"
1239 
1240 }  //  namespace
1241 
main(int argc,char ** argv)1242 int main(int argc, char** argv) {
1243   ::testing::InitGoogleTest(&argc, argv);
1244   openlog(NULL, LOG_PERROR, LOG_USER);
1245   return RUN_ALL_TESTS();
1246 }
1247