1f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid// Use of this source code is governed by a BSD-style license that can be
3f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid// found in the LICENSE file.
4f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
5f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid#include <stdio.h>
6f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid#include <gtest/gtest.h>
7f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
8f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidextern "C" {
97180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid#include "audio_thread_log.h"
107180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid#include "byte_buffer.h"
117180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid#include "cras_audio_area.h"
12f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid#include "cras_rstream.h"
13f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid#include "cras_shm.h"
14f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid#include "cras_types.h"
15f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid#include "dev_stream.h"
16f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
17f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
18f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidnamespace {
19f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
207180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidextern "C" {
217180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidstruct audio_thread_event_log *atlog;
227180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid};
237180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
249111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reidstatic struct timespec clock_gettime_retspec;
253089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chaostatic struct timespec cb_ts;
269111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
27f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidstatic const int kBufferFrames = 1024;
28f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidstatic const struct cras_audio_format fmt_s16le_44_1 = {
29ebf43fb85cdb30c3620428873518d493a9cb575eDylan Reid  SND_PCM_FORMAT_S16_LE,
30ebf43fb85cdb30c3620428873518d493a9cb575eDylan Reid  44100,
31ebf43fb85cdb30c3620428873518d493a9cb575eDylan Reid  2,
32f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid};
33f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidstatic const struct cras_audio_format fmt_s16le_48 = {
34ebf43fb85cdb30c3620428873518d493a9cb575eDylan Reid  SND_PCM_FORMAT_S16_LE,
35ebf43fb85cdb30c3620428873518d493a9cb575eDylan Reid  48000,
36ebf43fb85cdb30c3620428873518d493a9cb575eDylan Reid  2,
37f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid};
38eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chaostatic const struct cras_audio_format fmt_s16le_48_mono = {
39eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  SND_PCM_FORMAT_S16_LE,
40eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  48000,
41eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  1,
42eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao};
43f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
447180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidstruct cras_audio_area_copy_call {
457180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  const struct cras_audio_area *dst;
467180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  unsigned int dst_offset;
477180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  unsigned int dst_format_bytes;
487180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  const struct cras_audio_area *src;
49bc0496defda90cdc6d4427d43bcbb04338400a0eDylan Reid  unsigned int src_offset;
50a7031f6452138ef6edd64f5ef75002299e2dd32aCheng-Yi Chiang  float software_gain_scaler;
517180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid};
527180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
537180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidstruct fmt_conv_call {
547180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  struct cras_fmt_conv *conv;
557180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  uint8_t *in_buf;
567180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  uint8_t *out_buf;
577180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  size_t in_frames;
587180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  size_t out_frames;
597180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid};
607180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
61f65110045e7be552c75b5642e7c47b599824082aDylan Reidstruct mix_add_call {
62f65110045e7be552c75b5642e7c47b599824082aDylan Reid  int16_t *dst;
63f65110045e7be552c75b5642e7c47b599824082aDylan Reid  int16_t *src;
64f65110045e7be552c75b5642e7c47b599824082aDylan Reid  unsigned int count;
65f65110045e7be552c75b5642e7c47b599824082aDylan Reid  unsigned int index;
66f65110045e7be552c75b5642e7c47b599824082aDylan Reid  int mute;
67f65110045e7be552c75b5642e7c47b599824082aDylan Reid  float mix_vol;
68f65110045e7be552c75b5642e7c47b599824082aDylan Reid};
69f65110045e7be552c75b5642e7c47b599824082aDylan Reid
70f65110045e7be552c75b5642e7c47b599824082aDylan Reidstruct rstream_get_readable_call {
71f65110045e7be552c75b5642e7c47b599824082aDylan Reid  struct cras_rstream *rstream;
72f65110045e7be552c75b5642e7c47b599824082aDylan Reid  unsigned int offset;
73f65110045e7be552c75b5642e7c47b599824082aDylan Reid  unsigned int num_called;
74f65110045e7be552c75b5642e7c47b599824082aDylan Reid};
75f65110045e7be552c75b5642e7c47b599824082aDylan Reid
76f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidstatic int config_format_converter_called;
77f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidstatic struct cras_fmt_conv *config_format_converter_conv;
787180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidstatic struct cras_audio_format in_fmt;
797180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidstatic struct cras_audio_format out_fmt;
807180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidstatic struct cras_audio_area_copy_call copy_area_call;
817180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidstatic struct fmt_conv_call conv_frames_call;
827180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidstatic size_t conv_frames_ret;
83eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chaostatic int cras_audio_area_create_num_channels_val;
84eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chaostatic int cras_fmt_conv_convert_frames_in_frames_val;
854da40ffba6ec3485b8e0a341c12dc2ee1d9cdeb6Hsin-Yu Chaostatic int cras_fmt_conversion_needed_val;
86fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chaostatic int cras_fmt_conv_set_linear_resample_rates_called;
87084401521b297857987b2b3ece787c16cacdbbccHsin-Yu Chaostatic float cras_fmt_conv_set_linear_resample_rates_from;
88084401521b297857987b2b3ece787c16cacdbbccHsin-Yu Chaostatic float cras_fmt_conv_set_linear_resample_rates_to;
89fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
90f65110045e7be552c75b5642e7c47b599824082aDylan Reidstatic unsigned int rstream_playable_frames_ret;
91f65110045e7be552c75b5642e7c47b599824082aDylan Reidstatic struct mix_add_call mix_add_call;
92f65110045e7be552c75b5642e7c47b599824082aDylan Reidstatic struct rstream_get_readable_call rstream_get_readable_call;
93f65110045e7be552c75b5642e7c47b599824082aDylan Reidstatic unsigned int rstream_get_readable_num;
94249e72919eb928e107d251b262c305a8fe531641Dylan Reidstatic uint8_t *rstream_get_readable_ptr;
95f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
96797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiangstatic int cras_rstream_audio_ready_called;
97797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiangstatic int cras_rstream_audio_ready_count;
98797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
997180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidclass CreateSuite : public testing::Test{
100f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  protected:
101f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid    virtual void SetUp() {
1027180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      in_fmt.format = SND_PCM_FORMAT_S16_LE;
1037180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      out_fmt.format = SND_PCM_FORMAT_S16_LE;
1047180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      in_fmt.num_channels = 2;
1057180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      out_fmt.num_channels = 2;
106f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
1074760724dc983b4bde612b274c3ecc5daead4c260Dylan Reid      SetupShm(&rstream_.shm);
108f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
109f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid      rstream_.stream_id = 0x10001;
110f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid      rstream_.buffer_frames = kBufferFrames;
111f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid      rstream_.cb_threshold = kBufferFrames / 2;
112f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid      rstream_.is_draining = 0;
113f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid      rstream_.stream_type = CRAS_STREAM_TYPE_DEFAULT;
114f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid      rstream_.direction = CRAS_STREAM_OUTPUT;
1157180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      rstream_.format.format = SND_PCM_FORMAT_S16_LE;
1163401f772f9dcce31dd2bdb55defcbe35a19e173eDylan Reid      rstream_.format.num_channels = 2;
1173b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao      rstream_.format = fmt_s16le_44_1;
1183401f772f9dcce31dd2bdb55defcbe35a19e173eDylan Reid      rstream_.flags = 0;
119f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
120f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid      config_format_converter_called = 0;
1214da40ffba6ec3485b8e0a341c12dc2ee1d9cdeb6Hsin-Yu Chao      cras_fmt_conversion_needed_val = 0;
122fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao      cras_fmt_conv_set_linear_resample_rates_called = 0;
1237180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
124797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang      cras_rstream_audio_ready_called = 0;
125797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang      cras_rstream_audio_ready_count = 0;
126797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
1277180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      memset(&copy_area_call, 0xff, sizeof(copy_area_call));
1287180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      memset(&conv_frames_call, 0xff, sizeof(conv_frames_call));
1297180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1307180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      atlog = audio_thread_event_log_init();
131f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid    }
132f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
133f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid    virtual void TearDown() {
1344760724dc983b4bde612b274c3ecc5daead4c260Dylan Reid      free(rstream_.shm.area);
1357180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      audio_thread_event_log_deinit(atlog);
1367180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid    }
1377180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1387180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid    void SetupShm(struct cras_audio_shm *shm) {
1397180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      int16_t *buf;
1407180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1417180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      shm->area = static_cast<struct cras_audio_shm_area *>(
1427180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid          calloc(1, kBufferFrames * 4 + sizeof(cras_audio_shm_area)));
1437180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      cras_shm_set_frame_bytes(shm, 4);
1447180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      cras_shm_set_used_size(shm,
1457180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                             kBufferFrames * cras_shm_frame_bytes(shm));
1467180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1477180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      buf = (int16_t *)shm->area->samples;
1487180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      for (size_t i = 0; i < kBufferFrames * 2; i++)
1497180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid        buf[i] = i;
1507180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      cras_shm_set_mute(shm, 0);
1517180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      cras_shm_set_volume_scaler(shm, 1.0);
152f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid    }
153f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
154f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  int16_t *compare_buffer_;
155f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  struct cras_rstream rstream_;
156f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid};
157f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
1587180fbd487d1ed4ad398fbb5523ba46e129663efDylan ReidTEST_F(CreateSuite, CaptureNoSRC) {
1597180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  struct dev_stream devstr;
1607180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  struct cras_audio_area *area;
1617180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  struct cras_audio_area *stream_area;
1627180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  int16_t cap_buf[kBufferFrames * 2];
163a7031f6452138ef6edd64f5ef75002299e2dd32aCheng-Yi Chiang  float software_gain_scaler = 10;
1647180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1657180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.stream = &rstream_;
1667180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv = NULL;
1677180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_buffer = NULL;
1687180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_buffer_size_frames = 0;
1697180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1707180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area = (struct cras_audio_area*)calloc(1, sizeof(*area) +
1717180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                               2 * sizeof(*area->channels));
1727180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->num_channels = 2;
1737180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  channel_area_set_channel(&area->channels[0], CRAS_CH_FL);
1747180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  channel_area_set_channel(&area->channels[1], CRAS_CH_FR);
1757180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->channels[0].step_bytes = 4;
1767180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->channels[0].buf = (uint8_t *)(cap_buf);
1777180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->channels[1].step_bytes = 4;
1787180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->channels[1].buf = (uint8_t *)(cap_buf + 1);
1797180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1807180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area = (struct cras_audio_area*)calloc(1, sizeof(*area) +
1817180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                                  2 * sizeof(*area->channels));
1827180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->num_channels = 2;
1834760724dc983b4bde612b274c3ecc5daead4c260Dylan Reid  rstream_.audio_area = stream_area;
1844760724dc983b4bde612b274c3ecc5daead4c260Dylan Reid  int16_t *shm_samples = (int16_t *)rstream_.shm.area->samples;
1857180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->channels[0].step_bytes = 4;
1867180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->channels[0].buf = (uint8_t *)(shm_samples);
1877180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->channels[1].step_bytes = 4;
1887180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->channels[1].buf = (uint8_t *)(shm_samples + 1);
1897180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
190a7031f6452138ef6edd64f5ef75002299e2dd32aCheng-Yi Chiang  dev_stream_capture(&devstr, area, 0, software_gain_scaler);
1917180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1927180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(stream_area, copy_area_call.dst);
1937180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(0, copy_area_call.dst_offset);
1947180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(4, copy_area_call.dst_format_bytes);
1957180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(area, copy_area_call.src);
196a7031f6452138ef6edd64f5ef75002299e2dd32aCheng-Yi Chiang  EXPECT_EQ(software_gain_scaler, copy_area_call.software_gain_scaler);
1977180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1987180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  free(area);
1997180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  free(stream_area);
2007180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
2017180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2027180fbd487d1ed4ad398fbb5523ba46e129663efDylan ReidTEST_F(CreateSuite, CaptureSRC) {
2037180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  struct dev_stream devstr;
2047180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  struct cras_audio_area *area;
2057180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  struct cras_audio_area *stream_area;
2067180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  int16_t cap_buf[kBufferFrames * 2];
207a7031f6452138ef6edd64f5ef75002299e2dd32aCheng-Yi Chiang  float software_gain_scaler = 10;
2087180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2097180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.stream = &rstream_;
2107180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv = (struct cras_fmt_conv *)0xdead;
2117180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_buffer =
2127180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      (struct byte_buffer *)byte_buffer_create(kBufferFrames * 2 * 4);
2137180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_buffer_size_frames = kBufferFrames * 2;
2147180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2157180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area = (struct cras_audio_area*)calloc(1, sizeof(*area) +
2167180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                               2 * sizeof(*area->channels));
2177180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->num_channels = 2;
2187180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  channel_area_set_channel(&area->channels[0], CRAS_CH_FL);
2197180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  channel_area_set_channel(&area->channels[1], CRAS_CH_FR);
2207180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->channels[0].step_bytes = 4;
2217180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->channels[0].buf = (uint8_t *)(cap_buf);
2227180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->channels[1].step_bytes = 4;
2237180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->channels[1].buf = (uint8_t *)(cap_buf + 1);
2247180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  area->frames = kBufferFrames;
2257180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2267180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area = (struct cras_audio_area*)calloc(1, sizeof(*area) +
2277180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                                  2 * sizeof(*area->channels));
2287180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->num_channels = 2;
2294760724dc983b4bde612b274c3ecc5daead4c260Dylan Reid  rstream_.audio_area = stream_area;
2304760724dc983b4bde612b274c3ecc5daead4c260Dylan Reid  int16_t *shm_samples = (int16_t *)rstream_.shm.area->samples;
2317180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->channels[0].step_bytes = 4;
2327180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->channels[0].buf = (uint8_t *)(shm_samples);
2337180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->channels[1].step_bytes = 4;
2347180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  stream_area->channels[1].buf = (uint8_t *)(shm_samples + 1);
2354760724dc983b4bde612b274c3ecc5daead4c260Dylan Reid  rstream_.audio_area = stream_area;
2367180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2377180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_area = (struct cras_audio_area*)calloc(1, sizeof(*area) +
2387180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                                  2 * sizeof(*area->channels));
2397180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_area->num_channels = 2;
2407180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_area->channels[0].step_bytes = 4;
2417180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_area->channels[0].buf = (uint8_t *)(devstr.conv_buffer->bytes);
2427180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_area->channels[1].step_bytes = 4;
2437180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  devstr.conv_area->channels[1].buf =
2447180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid      (uint8_t *)(devstr.conv_buffer->bytes + 1);
2457180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2467180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  conv_frames_ret = kBufferFrames / 2;
247eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  cras_fmt_conv_convert_frames_in_frames_val = kBufferFrames;
2484da40ffba6ec3485b8e0a341c12dc2ee1d9cdeb6Hsin-Yu Chao  cras_fmt_conversion_needed_val = 1;
249a7031f6452138ef6edd64f5ef75002299e2dd32aCheng-Yi Chiang  dev_stream_capture(&devstr, area, 0, software_gain_scaler);
2507180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2517180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ((struct cras_fmt_conv *)0xdead, conv_frames_call.conv);
2527180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ((uint8_t *)cap_buf, conv_frames_call.in_buf);
2537180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(devstr.conv_buffer->bytes, conv_frames_call.out_buf);
2547180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(kBufferFrames, conv_frames_call.in_frames);
2557180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(kBufferFrames * 2, conv_frames_call.out_frames);
2567180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2577180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(stream_area, copy_area_call.dst);
2587180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(0, copy_area_call.dst_offset);
2597180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(4, copy_area_call.dst_format_bytes);
2607180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(devstr.conv_area, copy_area_call.src);
2617180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(conv_frames_ret, devstr.conv_area->frames);
262a7031f6452138ef6edd64f5ef75002299e2dd32aCheng-Yi Chiang  EXPECT_EQ(software_gain_scaler, copy_area_call.software_gain_scaler);
2637180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2647180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  free(area);
2657180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  free(stream_area);
2667180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  free(devstr.conv_area);
2677180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
2687180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2697180fbd487d1ed4ad398fbb5523ba46e129663efDylan ReidTEST_F(CreateSuite, CreateSRC44to48) {
270f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  struct dev_stream *dev_stream;
271f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
272f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  rstream_.format = fmt_s16le_44_1;
2737180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  in_fmt.frame_rate = 44100;
2747180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  out_fmt.frame_rate = 48000;
275f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
2763089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao  dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void *)0x55,
2773089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao                                 &cb_ts);
278f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  EXPECT_EQ(1, config_format_converter_called);
2797180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
2807180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_LE(cras_frames_at_rate(in_fmt.frame_rate, kBufferFrames,
2817180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                out_fmt.frame_rate),
282f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid            dev_stream->conv_buffer_size_frames);
283f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  dev_stream_destroy(dev_stream);
284f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
285f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
2867180fbd487d1ed4ad398fbb5523ba46e129663efDylan ReidTEST_F(CreateSuite, CreateSRC44to48Input) {
2877180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  struct dev_stream *dev_stream;
2887180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
2897180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  rstream_.format = fmt_s16le_44_1;
2907180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  rstream_.direction = CRAS_STREAM_INPUT;
2917180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  in_fmt.frame_rate = 48000;
2927180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  out_fmt.frame_rate = 44100;
2937180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
2943089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao  dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void *)0x55,
2953089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao                                 &cb_ts);
2967180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(1, config_format_converter_called);
2977180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
2987180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_LE(cras_frames_at_rate(in_fmt.frame_rate, kBufferFrames,
2997180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                out_fmt.frame_rate),
3007180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid            dev_stream->conv_buffer_size_frames);
3017180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  dev_stream_destroy(dev_stream);
3027180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
3037180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
3047180fbd487d1ed4ad398fbb5523ba46e129663efDylan ReidTEST_F(CreateSuite, CreateSRC48to44) {
305f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  struct dev_stream *dev_stream;
306f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
307f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  rstream_.format = fmt_s16le_48;
3087180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  in_fmt.frame_rate = 48000;
3097180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  out_fmt.frame_rate = 44100;
310f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
3113089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao  dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void *)0x55,
3123089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao                                 &cb_ts);
313f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  EXPECT_EQ(1, config_format_converter_called);
3147180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
3157180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_LE(cras_frames_at_rate(in_fmt.frame_rate, kBufferFrames,
3167180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                out_fmt.frame_rate),
3177180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid            dev_stream->conv_buffer_size_frames);
3187180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  dev_stream_destroy(dev_stream);
3197180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
3207180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
3217180fbd487d1ed4ad398fbb5523ba46e129663efDylan ReidTEST_F(CreateSuite, CreateSRC48to44Input) {
3227180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  struct dev_stream *dev_stream;
3237180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
3247180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  rstream_.format = fmt_s16le_48;
3257180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  rstream_.direction = CRAS_STREAM_INPUT;
3267180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  in_fmt.frame_rate = 44100;
3277180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  out_fmt.frame_rate = 48000;
3287180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
3293089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao  dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void *)0x55,
3303089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao                                 &cb_ts);
3317180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_EQ(1, config_format_converter_called);
3327180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
3337180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  EXPECT_LE(cras_frames_at_rate(in_fmt.frame_rate, kBufferFrames,
3347180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                out_fmt.frame_rate),
335f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid            dev_stream->conv_buffer_size_frames);
336f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  dev_stream_destroy(dev_stream);
337f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
338f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
339eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu ChaoTEST_F(CreateSuite, CreateSRC48to44StereoToMono) {
340eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  struct dev_stream *dev_stream;
341eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao
342eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  rstream_.format = fmt_s16le_48_mono;
343eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  rstream_.direction = CRAS_STREAM_INPUT;
344eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  in_fmt.frame_rate = 44100;
345eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  out_fmt.frame_rate = 48000;
346eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
3473089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao  dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void *)0x55,
3483089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao                                 &cb_ts);
349eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_EQ(1, config_format_converter_called);
350eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
351eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_LE(cras_frames_at_rate(in_fmt.frame_rate, kBufferFrames,
352eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao                                out_fmt.frame_rate),
353eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao            dev_stream->conv_buffer_size_frames);
354eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_EQ(dev_stream->conv_buffer_size_frames * 4,
3555e418af95b42c432b198434abd663c4548425c8dHsin-Yu Chao            dev_stream->conv_buffer->max_size);
356eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_EQ(2, cras_audio_area_create_num_channels_val);
357eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  dev_stream_destroy(dev_stream);
358eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao}
359eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao
360eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu ChaoTEST_F(CreateSuite, CaptureAvailConvBufHasSamples) {
361eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  struct dev_stream *dev_stream;
362eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  unsigned int avail;
363eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao
364eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  rstream_.format = fmt_s16le_48;
365eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  rstream_.direction = CRAS_STREAM_INPUT;
366eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
3673089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao  dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void *)0x55,
3683089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao                                 &cb_ts);
369eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_EQ(1, config_format_converter_called);
370eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
371eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_LE(cras_frames_at_rate(in_fmt.frame_rate, kBufferFrames,
372eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao                                out_fmt.frame_rate),
373eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao            dev_stream->conv_buffer_size_frames);
374eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_EQ(dev_stream->conv_buffer_size_frames * 4,
3755e418af95b42c432b198434abd663c4548425c8dHsin-Yu Chao            dev_stream->conv_buffer->max_size);
376eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_EQ(2, cras_audio_area_create_num_channels_val);
377eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao
378eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  buf_increment_write(dev_stream->conv_buffer, 50 * 4);
379e7d7869999ba37fcfa64de304214dc6fab0271e5Hsin-Yu Chao  avail = dev_stream_capture_avail(dev_stream);
380eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao
381eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  EXPECT_EQ(cras_frames_at_rate(48000, 512 - 50, 44100), avail);
382eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao
383eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  dev_stream_destroy(dev_stream);
384eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao}
385eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao
386fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu ChaoTEST_F(CreateSuite, SetDevRateNotMasterDev) {
387fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  struct dev_stream *dev_stream;
388fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  unsigned int dev_id = 9;
389fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
390fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  rstream_.format = fmt_s16le_48;
391fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  rstream_.direction = CRAS_STREAM_INPUT;
392fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  rstream_.master_dev.dev_id = 4;
393fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  config_format_converter_conv =
394fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao      reinterpret_cast<struct cras_fmt_conv*>(0x33);
395fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
3963089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao                                 (void *)0x55, &cb_ts);
397fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
398fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  dev_stream_set_dev_rate(dev_stream, 44100, 1.01, 1.0, 0);
399fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(1, cras_fmt_conv_set_linear_resample_rates_called);
400fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(44100, cras_fmt_conv_set_linear_resample_rates_from);
401fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(44541, cras_fmt_conv_set_linear_resample_rates_to);
402fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
403fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  dev_stream_set_dev_rate(dev_stream, 44100, 1.01, 1.0, 1);
404fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(2, cras_fmt_conv_set_linear_resample_rates_called);
405fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(44100, cras_fmt_conv_set_linear_resample_rates_from);
406fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_LE(44541, cras_fmt_conv_set_linear_resample_rates_to);
407fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
408fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  dev_stream_set_dev_rate(dev_stream, 44100, 1.0, 1.01, -1);
409fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(3, cras_fmt_conv_set_linear_resample_rates_called);
410fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(44100, cras_fmt_conv_set_linear_resample_rates_from);
411fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_GE(43663, cras_fmt_conv_set_linear_resample_rates_to);
4123b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  dev_stream_destroy(dev_stream);
413fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao}
414fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
415fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu ChaoTEST_F(CreateSuite, SetDevRateMasterDev) {
416fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  struct dev_stream *dev_stream;
417fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  unsigned int dev_id = 9;
418fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  unsigned int expected_ts_nsec;
419fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
420fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  rstream_.format = fmt_s16le_48;
421fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  rstream_.direction = CRAS_STREAM_INPUT;
422fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  rstream_.master_dev.dev_id = dev_id;
423fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  config_format_converter_conv =
424fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao      reinterpret_cast<struct cras_fmt_conv*>(0x33);
425fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
4263089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao                                 (void *)0x55, &cb_ts);
427fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
428fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  dev_stream_set_dev_rate(dev_stream, 44100, 1.01, 1.0, 0);
429fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(1, cras_fmt_conv_set_linear_resample_rates_called);
430fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(44100, cras_fmt_conv_set_linear_resample_rates_from);
431fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(44100, cras_fmt_conv_set_linear_resample_rates_to);
432fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  expected_ts_nsec = 1000000000.0 * kBufferFrames / 2.0 / 48000.0 / 1.01;
433fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(0, rstream_.sleep_interval_ts.tv_sec);
434fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(expected_ts_nsec, rstream_.sleep_interval_ts.tv_nsec);
435fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
436fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  dev_stream_set_dev_rate(dev_stream, 44100, 1.01, 1.0, 1);
437fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(2, cras_fmt_conv_set_linear_resample_rates_called);
438fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(44100, cras_fmt_conv_set_linear_resample_rates_from);
439fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_LE(44100, cras_fmt_conv_set_linear_resample_rates_to);
440fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  expected_ts_nsec = 1000000000.0 * kBufferFrames / 2.0 / 48000.0 / 1.01;
441fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(0, rstream_.sleep_interval_ts.tv_sec);
442fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(expected_ts_nsec, rstream_.sleep_interval_ts.tv_nsec);
443fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
444fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  dev_stream_set_dev_rate(dev_stream, 44100, 1.0, 1.33, -1);
445fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(3, cras_fmt_conv_set_linear_resample_rates_called);
446fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(44100, cras_fmt_conv_set_linear_resample_rates_from);
447fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_GE(44100, cras_fmt_conv_set_linear_resample_rates_to);
448fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  expected_ts_nsec = 1000000000.0 * kBufferFrames / 2.0 / 48000.0;
449fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(0, rstream_.sleep_interval_ts.tv_sec);
450fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  EXPECT_EQ(expected_ts_nsec, rstream_.sleep_interval_ts.tv_nsec);
4513b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  dev_stream_destroy(dev_stream);
452fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao}
453fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
454f65110045e7be552c75b5642e7c47b599824082aDylan ReidTEST_F(CreateSuite, StreamMixNoFrames) {
455f65110045e7be552c75b5642e7c47b599824082aDylan Reid  struct dev_stream dev_stream;
456249e72919eb928e107d251b262c305a8fe531641Dylan Reid  struct cras_audio_format fmt;
457f65110045e7be552c75b5642e7c47b599824082aDylan Reid
458f65110045e7be552c75b5642e7c47b599824082aDylan Reid  dev_stream.conv = NULL;
459f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_playable_frames_ret = 0;
460249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.num_channels = 2;
461249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
462249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(0, dev_stream_mix(&dev_stream, &fmt, 0, 3));
463f65110045e7be552c75b5642e7c47b599824082aDylan Reid}
464f65110045e7be552c75b5642e7c47b599824082aDylan Reid
465f65110045e7be552c75b5642e7c47b599824082aDylan ReidTEST_F(CreateSuite, StreamMixNoConv) {
466f65110045e7be552c75b5642e7c47b599824082aDylan Reid  struct dev_stream dev_stream;
467f65110045e7be552c75b5642e7c47b599824082aDylan Reid  const unsigned int nfr = 100;
468249e72919eb928e107d251b262c305a8fe531641Dylan Reid  struct cras_audio_format fmt;
469f65110045e7be552c75b5642e7c47b599824082aDylan Reid
470f65110045e7be552c75b5642e7c47b599824082aDylan Reid  dev_stream.conv = NULL;
471f65110045e7be552c75b5642e7c47b599824082aDylan Reid  dev_stream.stream = reinterpret_cast<cras_rstream*>(0x5446);
472f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_playable_frames_ret = nfr;
473f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_get_readable_num = nfr;
474249e72919eb928e107d251b262c305a8fe531641Dylan Reid  rstream_get_readable_ptr = reinterpret_cast<uint8_t*>(0x4000);
475f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_get_readable_call.num_called = 0;
476249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.num_channels = 2;
477249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
478249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(nfr, dev_stream_mix(&dev_stream, &fmt, (uint8_t*)0x5000, nfr));
479f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ((int16_t*)0x5000, mix_add_call.dst);
480f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ((int16_t*)0x4000, mix_add_call.src);
481f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(200, mix_add_call.count);
482f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(1, mix_add_call.index);
483f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(dev_stream.stream, rstream_get_readable_call.rstream);
484f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(0, rstream_get_readable_call.offset);
485f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(1, rstream_get_readable_call.num_called);
486f65110045e7be552c75b5642e7c47b599824082aDylan Reid}
487f65110045e7be552c75b5642e7c47b599824082aDylan Reid
488f65110045e7be552c75b5642e7c47b599824082aDylan ReidTEST_F(CreateSuite, StreamMixNoConvTwoPass) {
489f65110045e7be552c75b5642e7c47b599824082aDylan Reid  struct dev_stream dev_stream;
490f65110045e7be552c75b5642e7c47b599824082aDylan Reid  const unsigned int nfr = 100;
491f65110045e7be552c75b5642e7c47b599824082aDylan Reid  const unsigned int bytes_per_sample = 2;
492f65110045e7be552c75b5642e7c47b599824082aDylan Reid  const unsigned int num_channels = 2;
493f65110045e7be552c75b5642e7c47b599824082aDylan Reid  const unsigned int bytes_per_frame = bytes_per_sample * num_channels;
494249e72919eb928e107d251b262c305a8fe531641Dylan Reid  struct cras_audio_format fmt;
495f65110045e7be552c75b5642e7c47b599824082aDylan Reid
496f65110045e7be552c75b5642e7c47b599824082aDylan Reid  dev_stream.conv = NULL;
497f65110045e7be552c75b5642e7c47b599824082aDylan Reid  dev_stream.stream = reinterpret_cast<cras_rstream*>(0x5446);
498f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_playable_frames_ret = nfr;
499f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_get_readable_num = nfr / 2;
500249e72919eb928e107d251b262c305a8fe531641Dylan Reid  rstream_get_readable_ptr = reinterpret_cast<uint8_t*>(0x4000);
501f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_get_readable_call.num_called = 0;
502249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.num_channels = 2;
503249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
504249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(nfr, dev_stream_mix(&dev_stream, &fmt, (uint8_t*)0x5000, nfr));
505f65110045e7be552c75b5642e7c47b599824082aDylan Reid  const unsigned int half_offset = nfr / 2 * bytes_per_frame;
506f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ((int16_t*)(0x5000 + half_offset), mix_add_call.dst);
507f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ((int16_t*)0x4000, mix_add_call.src);
508f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(nfr / 2 * num_channels, mix_add_call.count);
509f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(1, mix_add_call.index);
510f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(dev_stream.stream, rstream_get_readable_call.rstream);
511f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(nfr/2, rstream_get_readable_call.offset);
512f65110045e7be552c75b5642e7c47b599824082aDylan Reid  EXPECT_EQ(2, rstream_get_readable_call.num_called);
513f65110045e7be552c75b5642e7c47b599824082aDylan Reid}
514f65110045e7be552c75b5642e7c47b599824082aDylan Reid
5153b41592086092f885544f23b225d01a7371a2c9aHsin-Yu ChaoTEST_F(CreateSuite, StreamCanFetch) {
5163b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  struct dev_stream *dev_stream;
5173b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  unsigned int dev_id = 9;
5183b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao
5193b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
5203089a1acfbc21b35a548ec5bb2a45ed1bf87923aHsin-Yu Chao                                 (void *)0x55, &cb_ts);
5213b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao
5223b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  /* Verify stream cannot fetch when it's still pending. */
5233b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  cras_shm_set_callback_pending(&rstream_.shm, 1);
5243b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  EXPECT_EQ(0, dev_stream_can_fetch(dev_stream));
5253b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao
5263b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  /* Verify stream can fetch when buffer available. */
5273b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  cras_shm_set_callback_pending(&rstream_.shm, 0);
5283b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  rstream_.shm.area->write_offset[0] = 0;
5293b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  rstream_.shm.area->write_offset[1] = 0;
5303b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  EXPECT_EQ(1, dev_stream_can_fetch(dev_stream));
5313b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao
5323b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  /* Verify stream cannot fetch when there's still buffer. */
5333b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  rstream_.shm.area->write_offset[0] = kBufferFrames;
5343b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  rstream_.shm.area->write_offset[1] = kBufferFrames;
5353b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  EXPECT_EQ(0, dev_stream_can_fetch(dev_stream));
5363b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao  dev_stream_destroy(dev_stream);
5373b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao}
5383b41592086092f885544f23b225d01a7371a2c9aHsin-Yu Chao
539797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi ChiangTEST_F(CreateSuite, StreamCanSend) {
540797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  struct dev_stream *dev_stream;
541797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  unsigned int dev_id = 9;
542797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  int written_frames;
543797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  int rc;
544797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  struct timespec expected_next_cb_ts;
545797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
546797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.direction = CRAS_STREAM_INPUT;
547797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
548797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang                                 (void *)0x55, &cb_ts);
549797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
550797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Assume there is a next_cb_ts on rstream.
551797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.next_cb_ts.tv_sec = 1;
552797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.next_cb_ts.tv_nsec = 0;
553797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
554797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Case 1: Not enough samples. Time is not late enough.
555797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         Stream can not send data to client.
556797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_sec = 0;
557797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_nsec = 0;
558797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rc = dev_stream_capture_update_rstream(dev_stream);
559797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, cras_rstream_audio_ready_called);
560797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, rc);
561797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
562797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Case 2: Not enough samples. Time is late enough.
563797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         Stream can not send data to client.
564797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
565797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Assume time is greater than next_cb_ts.
566797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_sec = 1;
567797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_nsec = 500;
568797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // However, written frames is less than cb_threshold.
569797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Stream still can not send samples to client.
570797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rc = dev_stream_capture_update_rstream(dev_stream);
571797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, cras_rstream_audio_ready_called);
572797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, rc);
573797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
574797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Case 3: Enough samples. Time is not late enough.
575797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         Stream can not send data to client.
576797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
577797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Assume time is less than next_cb_ts.
578797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_sec = 0;
579797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_nsec = 0;
580797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Enough samples are written.
581797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  written_frames = rstream_.cb_threshold + 10;
582797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  cras_shm_buffer_written(&rstream_.shm, written_frames);
583797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Stream still can not send samples to client.
584797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rc = dev_stream_capture_update_rstream(dev_stream);
585797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, cras_rstream_audio_ready_called);
586797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, rc);
587797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
588797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Case 4: Enough samples. Time is late enough.
589797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         Stream should send one cb_threshold to client.
590797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_sec = 1;
591797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_nsec = 500;
592797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rc = dev_stream_capture_update_rstream(dev_stream);
593797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(1, cras_rstream_audio_ready_called);
594797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(rstream_.cb_threshold, cras_rstream_audio_ready_count);
595797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, rc);
596797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
597797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Check next_cb_ts is increased by one sleep interval.
598797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  expected_next_cb_ts.tv_sec = 1;
599797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  expected_next_cb_ts.tv_nsec = 0;
600797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  add_timespecs(&expected_next_cb_ts,
601797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang                &rstream_.sleep_interval_ts);
602797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(expected_next_cb_ts.tv_sec, rstream_.next_cb_ts.tv_sec);
603797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(expected_next_cb_ts.tv_nsec, rstream_.next_cb_ts.tv_nsec);
604797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
605797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Reset stub data of interest.
606797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  cras_rstream_audio_ready_called = 0;
607797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  cras_rstream_audio_ready_count = 0;
608797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.next_cb_ts.tv_sec = 1;
609797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.next_cb_ts.tv_nsec = 0;
610797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
611797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Case 5: Enough samples. Time is late enough and it is too late
612797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         such that a new next_cb_ts is in the past.
613797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         Stream should send one cb_threshold to client and reset schedule.
614797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_sec = 2;
615797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_nsec = 0;
616797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rc = dev_stream_capture_update_rstream(dev_stream);
617797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(1, cras_rstream_audio_ready_called);
618797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(rstream_.cb_threshold, cras_rstream_audio_ready_count);
619797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, rc);
620797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
621797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Check next_cb_ts is rest to be now plus one sleep interval.
622797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  expected_next_cb_ts.tv_sec = 2;
623797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  expected_next_cb_ts.tv_nsec = 0;
624797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  add_timespecs(&expected_next_cb_ts,
625797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang                &rstream_.sleep_interval_ts);
626797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(expected_next_cb_ts.tv_sec, rstream_.next_cb_ts.tv_sec);
627797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(expected_next_cb_ts.tv_nsec, rstream_.next_cb_ts.tv_nsec);
628797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
629797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  dev_stream_destroy(dev_stream);
630797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang}
631797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
632797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi ChiangTEST_F(CreateSuite, StreamCanSendBulkAudio) {
633797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  struct dev_stream *dev_stream;
634797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  unsigned int dev_id = 9;
635797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  int written_frames;
636797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  int rc;
637797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  struct timespec expected_next_cb_ts;
638797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
639797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.direction = CRAS_STREAM_INPUT;
640797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.flags |= BULK_AUDIO_OK;
641797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
642797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang                                 (void *)0x55, &cb_ts);
643797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
644797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Assume there is a next_cb_ts on rstream.
645797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.next_cb_ts.tv_sec = 1;
646797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.next_cb_ts.tv_nsec = 0;
647797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
648797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Case 1: Not enough samples. Time is not late enough.
649797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         Bulk audio stream can not send data to client.
650797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_sec = 0;
651797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_nsec = 0;
652797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rc = dev_stream_capture_update_rstream(dev_stream);
653797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, cras_rstream_audio_ready_called);
654797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, rc);
655797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
656797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Case 2: Not enough samples. Time is late enough.
657797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         Bulk audio stream can not send data to client.
658797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
659797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Assume time is greater than next_cb_ts.
660797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_sec = 1;
661797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_nsec = 500;
662797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // However, written frames is less than cb_threshold.
663797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Stream still can not send samples to client.
664797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rc = dev_stream_capture_update_rstream(dev_stream);
665797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, cras_rstream_audio_ready_called);
666797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, rc);
667797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
668797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Case 3: Enough samples. Time is not late enough.
669797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         Bulk audio stream CAN send data to client.
670797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
671797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Assume time is less than next_cb_ts.
672797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_sec = 0;
673797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_nsec = 0;
674797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Enough samples are written.
675797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  written_frames = rstream_.cb_threshold + 10;
676797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  cras_shm_buffer_written(&rstream_.shm, written_frames);
677797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Bulk audio stream can send all written samples to client.
678797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rc = dev_stream_capture_update_rstream(dev_stream);
679797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(1, cras_rstream_audio_ready_called);
680797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(written_frames, cras_rstream_audio_ready_count);
681797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, rc);
682797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
683797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Case 4: Enough samples. Time is late enough.
684797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  //         Bulk audio stream can send all written samples to client.
685797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
686797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Reset stub data of interest.
687797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  cras_rstream_audio_ready_called = 0;
688797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  cras_rstream_audio_ready_count = 0;
689797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.next_cb_ts.tv_sec = 1;
690797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rstream_.next_cb_ts.tv_nsec = 0;
691797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
692797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_sec = 1;
693797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  clock_gettime_retspec.tv_nsec = 500;
694797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  rc = dev_stream_capture_update_rstream(dev_stream);
695797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(1, cras_rstream_audio_ready_called);
696797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(written_frames, cras_rstream_audio_ready_count);
697797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(0, rc);
698797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
699797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  // Check next_cb_ts is increased by one sleep interval.
700797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  expected_next_cb_ts.tv_sec = 1;
701797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  expected_next_cb_ts.tv_nsec = 0;
702797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  add_timespecs(&expected_next_cb_ts,
703797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang                &rstream_.sleep_interval_ts);
704797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(expected_next_cb_ts.tv_sec, rstream_.next_cb_ts.tv_sec);
705797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  EXPECT_EQ(expected_next_cb_ts.tv_nsec, rstream_.next_cb_ts.tv_nsec);
706797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
707797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  dev_stream_destroy(dev_stream);
708797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang}
709797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang
7109903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi ChiangTEST_F(CreateSuite, InputDevStreamWakeTimeByNextCbTs) {
7119903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  struct dev_stream *dev_stream;
7129903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  unsigned int dev_id = 9;
7139903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  int rc;
7149903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  unsigned int curr_level = 0;
7159903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  int written_frames;
7169903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  struct timespec level_tstamp = {.tv_sec = 1, .tv_nsec = 0};
7179903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  struct timespec wake_time_out = {.tv_sec = 0, .tv_nsec = 0};
7189903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7199903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  rstream_.direction = CRAS_STREAM_INPUT;
7209903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
7219903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang                                 (void *)0x55, &cb_ts);
7229903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7239903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Assume there is a next_cb_ts on rstream.
7249903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  rstream_.next_cb_ts.tv_sec = 1;
7259903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  rstream_.next_cb_ts.tv_nsec = 500000;
7269903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7279903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Assume there are enough samples for stream.
7289903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  written_frames = rstream_.cb_threshold + 10;
7299903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  cras_shm_buffer_written(&rstream_.shm, written_frames);
7309903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7319903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  rc = dev_stream_wake_time(dev_stream, curr_level,
7329903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang                            &level_tstamp, &wake_time_out);
7339903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7349903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // The next wake up time is determined by next_cb_ts on dev_stream.
7359903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  EXPECT_EQ(rstream_.next_cb_ts.tv_sec, wake_time_out.tv_sec);
7369903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  EXPECT_EQ(rstream_.next_cb_ts.tv_nsec, wake_time_out.tv_nsec);
7379903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  EXPECT_EQ(0, rc);
7389903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang}
7399903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7409903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi ChiangTEST_F(CreateSuite, InputDevStreamWakeTimeByDevice) {
7419903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  struct dev_stream *dev_stream;
7429903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  unsigned int dev_id = 9;
7439903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  int rc;
7449903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  unsigned int curr_level = 100;
7459903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  int written_frames;
7469903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  struct timespec level_tstamp = {.tv_sec = 1, .tv_nsec = 0};
7479903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  struct timespec wake_time_out = {.tv_sec = 0, .tv_nsec = 0};
7489903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  struct timespec expected_tstamp = {.tv_sec = 0, .tv_nsec = 0};
7499903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  struct timespec needed_time_for_device = {.tv_sec = 0, .tv_nsec = 0};
7509903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  int needed_frames_from_device = 0;
7519903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7529903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  rstream_.direction = CRAS_STREAM_INPUT;
7539903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_48,
7549903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang                                 (void *)0x55, &cb_ts);
7559903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7569903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Assume there is a next_cb_ts on rstream, that is, 1.005 seconds.
7579903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  rstream_.next_cb_ts.tv_sec = 1;
7589903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  rstream_.next_cb_ts.tv_nsec = 5000000; // 5ms
7599903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7609903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Assume there are not enough samples for stream.
7619903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  written_frames = 123;
7629903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  cras_shm_buffer_written(&rstream_.shm, written_frames);
7639903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7649903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Compute wake up time for device level to reach enough samples
7659903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // for one cb_threshold:
7669903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Device has 100 samples (48K rate).
7679903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Stream has 123 samples (44.1K rate)
7689903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // cb_threshold = 512 samples.
7699903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Stream needs 512 - 123 = 389 samples.
7709903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Converted to device rate => 389 * 48000.0 / 44100 = 423.4 samples
7719903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // => 424 samples.
7729903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Device needs another 424 - 100 = 324 samples.
7739903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Time for 252 samples = 324 / 48000 = 0.00675 sec.
7749903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // So expected wake up time for samples is at level_tstamp + 0.00675 sec =
7759903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // 1.00675 seconds.
7769903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  needed_frames_from_device = cras_frames_at_rate(
7779903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang       44100, rstream_.cb_threshold - written_frames, 48000);
7789903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  needed_frames_from_device -= curr_level;
7799903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  cras_frames_to_time(needed_frames_from_device, 48000,
7809903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang                      &needed_time_for_device);
7819903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7829903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  expected_tstamp.tv_sec = level_tstamp.tv_sec;
7839903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  expected_tstamp.tv_nsec = level_tstamp.tv_nsec;
7849903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7859903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  add_timespecs(&expected_tstamp, &needed_time_for_device);
7869903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7879903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Set the stub data for cras_fmt_conv_out_frames_to_in.
7889903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  out_fmt.frame_rate = 44100;
7899903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  in_fmt.frame_rate = 48000;
7909903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7919903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  rc = dev_stream_wake_time(dev_stream, curr_level,
7929903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang                            &level_tstamp, &wake_time_out);
7939903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
7949903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // The next wake up time is determined by needed time for device level
7959903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // to reach enough samples for one cb_threshold.
7969903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  EXPECT_EQ(expected_tstamp.tv_sec, wake_time_out.tv_sec);
7979903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  EXPECT_EQ(expected_tstamp.tv_nsec, wake_time_out.tv_nsec);
7989903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  EXPECT_EQ(0, rc);
7999903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
8009903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // Assume current level is larger than cb_threshold.
8019903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  // The wake up time is determined by next_cb_ts.
8029903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  curr_level += rstream_.cb_threshold;
8039903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  rc = dev_stream_wake_time(dev_stream, curr_level,
8049903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang                            &level_tstamp, &wake_time_out);
8059903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  EXPECT_EQ(rstream_.next_cb_ts.tv_sec, wake_time_out.tv_sec);
8069903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  EXPECT_EQ(rstream_.next_cb_ts.tv_nsec, wake_time_out.tv_nsec);
8079903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang  EXPECT_EQ(0, rc);
8089903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang}
8099903383ab04a9154c6b73045906f84f8654dcf79Cheng-Yi Chiang
8109111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid//  Test set_playback_timestamp.
8119111a0544944a9d367f5e19b15e5f03340b4a808Dylan ReidTEST(DevStreamTimimg, SetPlaybackTimeStampSimple) {
8129111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  struct cras_timespec ts;
8139111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8149111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_sec = 1;
8159111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_nsec = 0;
8169111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  cras_set_playback_timestamp(48000, 24000, &ts);
8179111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_EQ(1, ts.tv_sec);
8189111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_GE(ts.tv_nsec, 499900000);
8199111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_LE(ts.tv_nsec, 500100000);
8209111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid}
8219111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8229111a0544944a9d367f5e19b15e5f03340b4a808Dylan ReidTEST(DevStreamTimimg, SetPlaybackTimeStampWrap) {
8239111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  struct cras_timespec ts;
8249111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8259111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_sec = 1;
8269111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_nsec = 750000000;
8279111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  cras_set_playback_timestamp(48000, 24000, &ts);
8289111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_EQ(2, ts.tv_sec);
8299111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
8309111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
8319111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid}
8329111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8339111a0544944a9d367f5e19b15e5f03340b4a808Dylan ReidTEST(DevStreamTimimg, SetPlaybackTimeStampWrapTwice) {
8349111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  struct cras_timespec ts;
8359111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8369111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_sec = 1;
8379111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_nsec = 750000000;
8389111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  cras_set_playback_timestamp(48000, 72000, &ts);
8399111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_EQ(3, ts.tv_sec);
8409111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
8419111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
8429111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid}
8439111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8449111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid//  Test set_capture_timestamp.
8459111a0544944a9d367f5e19b15e5f03340b4a808Dylan ReidTEST(DevStreamTimimg, SetCaptureTimeStampSimple) {
8469111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  struct cras_timespec ts;
8479111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8489111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_sec = 1;
8499111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_nsec = 750000000;
8509111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  cras_set_capture_timestamp(48000, 24000, &ts);
8519111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_EQ(1, ts.tv_sec);
8529111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
8539111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
8549111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid}
8559111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8569111a0544944a9d367f5e19b15e5f03340b4a808Dylan ReidTEST(DevStreamTimimg, SetCaptureTimeStampWrap) {
8579111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  struct cras_timespec ts;
8589111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8599111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_sec = 1;
8609111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_nsec = 0;
8619111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  cras_set_capture_timestamp(48000, 24000, &ts);
8629111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_EQ(0, ts.tv_sec);
8639111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_GE(ts.tv_nsec, 499900000);
8649111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_LE(ts.tv_nsec, 500100000);
8659111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid}
8669111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8679111a0544944a9d367f5e19b15e5f03340b4a808Dylan ReidTEST(DevStreamTimimg, SetCaptureTimeStampWrapPartial) {
8689111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  struct cras_timespec ts;
8699111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
8709111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_sec = 2;
8719111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  clock_gettime_retspec.tv_nsec = 750000000;
8729111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  cras_set_capture_timestamp(48000, 72000, &ts);
8739111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_EQ(1, ts.tv_sec);
8749111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
8759111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
8769111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid}
8779111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
878f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid/* Stubs */
879f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidextern "C" {
8807180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
881ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reidint cras_rstream_audio_ready(struct cras_rstream *stream, size_t count) {
882797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  cras_rstream_audio_ready_count = count;
883797b23b697f1ec051ab68843f23e3dd14bf8c01aCheng-Yi Chiang  cras_rstream_audio_ready_called++;
8847180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  return 0;
8857180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
886f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
887236cdf04f3b9544b0fa4b8b05e4313987574d483Hsin-Yu Chaoint cras_rstream_request_audio(struct cras_rstream *stream,
888236cdf04f3b9544b0fa4b8b05e4313987574d483Hsin-Yu Chao    const struct timespec *now) {
88921e764cb9f052a0a193a4c9ec9759117be21cd79Dylan Reid  return 0;
89021e764cb9f052a0a193a4c9ec9759117be21cd79Dylan Reid}
89121e764cb9f052a0a193a4c9ec9759117be21cd79Dylan Reid
892d08e074704529f63cffed728e446fd0790a7aeffHsin-Yu Chaovoid cras_rstream_record_fetch_interval(struct cras_rstream *rstream,
893d08e074704529f63cffed728e446fd0790a7aeffHsin-Yu Chao                                        const struct timespec *now) {
894d08e074704529f63cffed728e446fd0790a7aeffHsin-Yu Chao}
895d08e074704529f63cffed728e446fd0790a7aeffHsin-Yu Chao
89613beeb14ea0e93132f1764a5f7f8104b7f32a22eDylan Reidvoid cras_rstream_update_input_write_pointer(struct cras_rstream *rstream) {
897ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid}
898ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid
89913beeb14ea0e93132f1764a5f7f8104b7f32a22eDylan Reidvoid cras_rstream_update_output_read_pointer(struct cras_rstream *rstream) {
90013beeb14ea0e93132f1764a5f7f8104b7f32a22eDylan Reid}
90113beeb14ea0e93132f1764a5f7f8104b7f32a22eDylan Reid
90213beeb14ea0e93132f1764a5f7f8104b7f32a22eDylan Reidvoid cras_rstream_dev_offset_update(struct cras_rstream *rstream,
90313beeb14ea0e93132f1764a5f7f8104b7f32a22eDylan Reid					unsigned int frames,
90413beeb14ea0e93132f1764a5f7f8104b7f32a22eDylan Reid					unsigned int dev_id) {
905ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid}
906ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid
9079be8914ce3dfa203fa5132e26822ee68c625dc65Hsin-Yu Chaovoid cras_rstream_dev_attach(struct cras_rstream *rstream, unsigned int dev_id,
9089be8914ce3dfa203fa5132e26822ee68c625dc65Hsin-Yu Chao                             void *dev_ptr)
909ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid{
910ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid}
911ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid
912ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reidvoid cras_rstream_dev_detach(struct cras_rstream *rstream, unsigned int dev_id)
913ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid{
914ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid}
915ed0e3ba0dc54a1ddd192ae571e15c0acebacbc81Dylan Reid
91613beeb14ea0e93132f1764a5f7f8104b7f32a22eDylan Reidunsigned int cras_rstream_dev_offset(const struct cras_rstream *rstream,
91713beeb14ea0e93132f1764a5f7f8104b7f32a22eDylan Reid                                     unsigned int dev_id) {
9180b123a52b29a09c563535a576dcc6a6eb9497b2dDylan Reid  return 0;
9190b123a52b29a09c563535a576dcc6a6eb9497b2dDylan Reid}
9200b123a52b29a09c563535a576dcc6a6eb9497b2dDylan Reid
921e32902dfa32360f2ce099b8772e14d88113d61eaDylan Reidunsigned int cras_rstream_playable_frames(struct cras_rstream *rstream,
922e32902dfa32360f2ce099b8772e14d88113d61eaDylan Reid					  unsigned int dev_id) {
923f65110045e7be552c75b5642e7c47b599824082aDylan Reid  return rstream_playable_frames_ret;
924e32902dfa32360f2ce099b8772e14d88113d61eaDylan Reid}
925e32902dfa32360f2ce099b8772e14d88113d61eaDylan Reid
9261aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reidfloat cras_rstream_get_volume_scaler(struct cras_rstream *rstream) {
9271aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid  return 1.0;
9281aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid}
9291aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid
930249e72919eb928e107d251b262c305a8fe531641Dylan Reiduint8_t *cras_rstream_get_readable_frames(struct cras_rstream *rstream,
9311aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid                                          unsigned int offset,
9321aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid					  size_t *frames) {
933f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_get_readable_call.rstream = rstream;
934f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_get_readable_call.offset = offset;
935f65110045e7be552c75b5642e7c47b599824082aDylan Reid  rstream_get_readable_call.num_called++;
936f65110045e7be552c75b5642e7c47b599824082aDylan Reid  *frames = rstream_get_readable_num;
937f65110045e7be552c75b5642e7c47b599824082aDylan Reid  return rstream_get_readable_ptr;
9381aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid}
9391aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid
9401aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reidint cras_rstream_get_mute(const struct cras_rstream *rstream) {
9411aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid  return 0;
9421aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid}
9431aba4d9e480cb20cf82448e98a3eb68d81d1a337Dylan Reid
94446f7653dc735ddd594ecc1b6e174b399443c0438Hsin-Yu Chaovoid cras_rstream_update_queued_frames(struct cras_rstream *rstream)
94546f7653dc735ddd594ecc1b6e174b399443c0438Hsin-Yu Chao{
94646f7653dc735ddd594ecc1b6e174b399443c0438Hsin-Yu Chao}
94746f7653dc735ddd594ecc1b6e174b399443c0438Hsin-Yu Chao
948f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidint config_format_converter(struct cras_fmt_conv **conv,
94909635e9afff9e95e0287e775b2a7e5e9132f351aHsin-Yu Chao			    enum CRAS_STREAM_DIRECTION dir,
950f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid			    const struct cras_audio_format *from,
951f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid			    const struct cras_audio_format *to,
952f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid			    unsigned int frames) {
953f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  config_format_converter_called++;
954f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  *conv = config_format_converter_conv;
955f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  return 0;
956f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
957f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
958f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidvoid cras_fmt_conv_destroy(struct cras_fmt_conv *conv) {
959f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
960f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
961f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidsize_t cras_fmt_conv_convert_frames(struct cras_fmt_conv *conv,
962f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid				    uint8_t *in_buf,
963f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid				    uint8_t *out_buf,
9647180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid				    unsigned int *in_frames,
9657180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid				    unsigned int out_frames) {
9667180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  conv_frames_call.conv = conv;
9677180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  conv_frames_call.in_buf = in_buf;
9687180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  conv_frames_call.out_buf = out_buf;
9697180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  conv_frames_call.in_frames = *in_frames;
970eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  *in_frames = cras_fmt_conv_convert_frames_in_frames_val;
9717180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  conv_frames_call.out_frames = out_frames;
9727180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
9737180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  return conv_frames_ret;
974f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
975f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
9761efd30f3854ac69a6916bdeaa82dae3f01d18acaDylan Reidvoid cras_mix_add(snd_pcm_format_t fmt, uint8_t *dst, uint8_t *src,
9771efd30f3854ac69a6916bdeaa82dae3f01d18acaDylan Reid                  unsigned int count, unsigned int index,
9781efd30f3854ac69a6916bdeaa82dae3f01d18acaDylan Reid                  int mute, float mix_vol) {
9791efd30f3854ac69a6916bdeaa82dae3f01d18acaDylan Reid  mix_add_call.dst = (int16_t *)dst;
9801efd30f3854ac69a6916bdeaa82dae3f01d18acaDylan Reid  mix_add_call.src = (int16_t *)src;
981f65110045e7be552c75b5642e7c47b599824082aDylan Reid  mix_add_call.count = count;
982f65110045e7be552c75b5642e7c47b599824082aDylan Reid  mix_add_call.index = index;
983f65110045e7be552c75b5642e7c47b599824082aDylan Reid  mix_add_call.mute = mute;
984f65110045e7be552c75b5642e7c47b599824082aDylan Reid  mix_add_call.mix_vol = mix_vol;
985f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
986f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
9877180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidstruct cras_audio_area *cras_audio_area_create(int num_channels) {
988eb2c6a76a727a37340eca0830ad41fde97476856Hsin-Yu Chao  cras_audio_area_create_num_channels_val = num_channels;
9897180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  return NULL;
9907180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
9917180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
9927180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidvoid cras_audio_area_destroy(struct cras_audio_area *area) {
9937180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
9947180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
995f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidvoid cras_audio_area_config_buf_pointers(struct cras_audio_area *area,
996f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid                                         const struct cras_audio_format *fmt,
997f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid                                         uint8_t *base_buffer) {
998f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
999f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
10007180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidvoid cras_audio_area_config_channels(struct cras_audio_area *area,
10017180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid				     const struct cras_audio_format *fmt) {
10027180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
10037180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
1004bc0496defda90cdc6d4427d43bcbb04338400a0eDylan Reidunsigned int cras_audio_area_copy(const struct cras_audio_area *dst,
1005bc0496defda90cdc6d4427d43bcbb04338400a0eDylan Reid                                  unsigned int dst_offset,
1006a898c1799cd5780996cf73fa3f8c1397ba06fef2Hsin-Yu Chao                                  const struct cras_audio_format *dst_fmt,
1007bc0496defda90cdc6d4427d43bcbb04338400a0eDylan Reid                                  const struct cras_audio_area *src,
1008bc0496defda90cdc6d4427d43bcbb04338400a0eDylan Reid                                  unsigned int src_offset,
1009a7031f6452138ef6edd64f5ef75002299e2dd32aCheng-Yi Chiang                                  float software_gain_scaler) {
10107180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  copy_area_call.dst = dst;
10117180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  copy_area_call.dst_offset = dst_offset;
10128cd4a917e6cef477799245a4e81fe3709ceff6c9Dylan Reid  copy_area_call.dst_format_bytes = cras_get_format_bytes(dst_fmt);
10137180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  copy_area_call.src = src;
1014bc0496defda90cdc6d4427d43bcbb04338400a0eDylan Reid  copy_area_call.src_offset = src_offset;
1015a7031f6452138ef6edd64f5ef75002299e2dd32aCheng-Yi Chiang  copy_area_call.software_gain_scaler = software_gain_scaler;
1016bc0496defda90cdc6d4427d43bcbb04338400a0eDylan Reid  return src->frames;
1017f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
1018f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
1019f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidsize_t cras_fmt_conv_in_frames_to_out(struct cras_fmt_conv *conv,
1020f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid				      size_t in_frames)
1021f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid{
10227180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  return cras_frames_at_rate(in_fmt.frame_rate,
1023f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid                             in_frames,
10247180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                             out_fmt.frame_rate);
10257180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
10267180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
10277180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidsize_t cras_fmt_conv_out_frames_to_in(struct cras_fmt_conv *conv,
10287180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                                      size_t out_frames) {
10297180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  return cras_frames_at_rate(out_fmt.frame_rate,
10307180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                             out_frames,
10317180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid                             in_fmt.frame_rate);
10327180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
10337180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
10347180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidconst struct cras_audio_format *cras_fmt_conv_in_format(
10357180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid    const struct cras_fmt_conv *conv) {
10367180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  return &in_fmt;
10377180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid}
10387180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid
10397180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reidconst struct cras_audio_format *cras_fmt_conv_out_format(
10407180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid    const struct cras_fmt_conv *conv) {
10417180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid  return &out_fmt;
1042f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
1043f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
10444da40ffba6ec3485b8e0a341c12dc2ee1d9cdeb6Hsin-Yu Chaoint cras_fmt_conversion_needed(const struct cras_fmt_conv *conv)
10454da40ffba6ec3485b8e0a341c12dc2ee1d9cdeb6Hsin-Yu Chao{
10464da40ffba6ec3485b8e0a341c12dc2ee1d9cdeb6Hsin-Yu Chao  return cras_fmt_conversion_needed_val;
10474da40ffba6ec3485b8e0a341c12dc2ee1d9cdeb6Hsin-Yu Chao}
10484da40ffba6ec3485b8e0a341c12dc2ee1d9cdeb6Hsin-Yu Chao
1049fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chaovoid cras_fmt_conv_set_linear_resample_rates(struct cras_fmt_conv *conv,
1050084401521b297857987b2b3ece787c16cacdbbccHsin-Yu Chao                                             float from,
1051084401521b297857987b2b3ece787c16cacdbbccHsin-Yu Chao                                             float to)
1052fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao{
1053fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  cras_fmt_conv_set_linear_resample_rates_from = from;
1054fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  cras_fmt_conv_set_linear_resample_rates_to = to;
1055fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao  cras_fmt_conv_set_linear_resample_rates_called++;
1056fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao}
1057fbd2d15de5e0df9ba2d1144170f7b35cab4249f4Hsin-Yu Chao
10589111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid//  From librt.
10599111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reidint clock_gettime(clockid_t clk_id, struct timespec *tp) {
10609111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  tp->tv_sec = clock_gettime_retspec.tv_sec;
10619111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  tp->tv_nsec = clock_gettime_retspec.tv_nsec;
10629111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid  return 0;
10639111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid}
10649111a0544944a9d367f5e19b15e5f03340b4a808Dylan Reid
1065f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}  // extern "C"
1066f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
1067f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}  //  namespace
1068f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid
1069f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reidint main(int argc, char **argv) {
1070f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  ::testing::InitGoogleTest(&argc, argv);
1071f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid  return RUN_ALL_TESTS();
1072f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid}
1073