iodev_unittest.cc revision 50cf4aec95391fb7768d9a98e35e618edc7443f3
1838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid// Use of this source code is governed by a BSD-style license that can be
3838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid// found in the LICENSE file.
4838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
5838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid#include <stdio.h>
6838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid#include <gtest/gtest.h>
7838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
8838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidextern "C" {
9838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid#include "cras_iodev.h"
10838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid#include "cras_rstream.h"
1124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao#include "dev_stream.h"
12838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid#include "utlist.h"
13cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang#include "cras_audio_area.h"
145342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
155342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang// Mock software volume scalers.
165342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangfloat softvol_scalers[101];
17838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
18838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
19cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang#define BUFFER_SIZE 8192
20cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
21e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chaostatic int cras_iodev_list_disable_dev_called;
22ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changstatic int select_node_called;
23ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changstatic enum CRAS_STREAM_DIRECTION select_node_direction;
24ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changstatic cras_node_id_t select_node_id;
25f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Changstatic struct cras_ionode *node_selected;
26b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Changstatic size_t notify_nodes_changed_called;
27c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Changstatic size_t notify_active_node_changed_called;
28b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic size_t notify_node_volume_called;
29b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic size_t notify_node_capture_gain_called;
30ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Changstatic int dsp_context_new_sample_rate;
31ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Changstatic const char *dsp_context_new_purpose;
325fa790469656d3e093799329f814756600762a71Dylan Reidstatic int dsp_context_free_called;
33663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chaostatic int update_channel_layout_called;
34663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chaostatic int update_channel_layout_return_val;
353285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiangstatic int  set_swap_mode_for_node_called;
363285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiangstatic int  set_swap_mode_for_node_enable;
373ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiangstatic int notify_node_left_right_swapped_called;
38a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chaostatic int cras_audio_format_set_channel_layout_called;
395342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangstatic unsigned int cras_system_get_volume_return;
40d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_get_pipeline_called;
41d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_get_pipeline_ret;
42d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_put_pipeline_called;
43d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_get_source_buffer_called;
44d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_get_sink_buffer_called;
45d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic float cras_dsp_pipeline_source_buffer[2][DSP_BUFFER_SIZE];
46d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic float cras_dsp_pipeline_sink_buffer[2][DSP_BUFFER_SIZE];
47d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_get_delay_called;
48d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_apply_called;
49d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_apply_sample_count;
50d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic unsigned int cras_mix_mute_count;
512db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reidstatic unsigned int cras_dsp_num_input_channels_return;
522db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reidstatic unsigned int cras_dsp_num_output_channels_return;
532db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reidstruct cras_dsp_context *cras_dsp_context_new_return;
541c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic unsigned int rate_estimator_add_frames_num_frames;
551c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic unsigned int rate_estimator_add_frames_called;
561c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic int cras_system_get_mute_return;
57249e72919eb928e107d251b262c305a8fe531641Dylan Reidstatic snd_pcm_format_t cras_scale_buffer_fmt;
581c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic float cras_scale_buffer_scaler;
5937048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic unsigned int pre_dsp_hook_called;
6037048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic const uint8_t *pre_dsp_hook_frames;
61081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chenstatic void *pre_dsp_hook_cb_data;
6237048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic unsigned int post_dsp_hook_called;
6337048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic const uint8_t *post_dsp_hook_frames;
64081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chenstatic void *post_dsp_hook_cb_data;
6524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chaostatic int iodev_buffer_size;
66034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiangstatic long cras_system_get_capture_gain_ret_value;
67cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiangstatic uint8_t audio_buffer[BUFFER_SIZE];
68cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiangstatic struct cras_audio_area *audio_area;
691bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiangstatic unsigned int put_buffer_nframes;
70016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int output_should_wake_ret;
71016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int no_stream_called;
72016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int no_stream_enable;
73663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
74663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao// Iodev callback
75663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chaoint update_channel_layout(struct cras_iodev *iodev) {
76663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  update_channel_layout_called = 1;
77663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  return update_channel_layout_return_val;
78663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao}
796f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
803285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang// Iodev callback
813285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiangint set_swap_mode_for_node(struct cras_iodev *iodev, struct cras_ionode *node,
823285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang                           int enable)
833285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang{
843285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_called++;
853285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_enable = enable;
863285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  return 0;
873285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang}
883285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang
896f0a5e6a967558105f37513801af573167890f67Chih-Chung Changvoid ResetStubData() {
90e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  cras_iodev_list_disable_dev_called = 0;
91ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_called = 0;
92b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  notify_nodes_changed_called = 0;
93c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  notify_active_node_changed_called = 0;
94b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  notify_node_volume_called = 0;
95b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  notify_node_capture_gain_called = 0;
96ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_sample_rate = 0;
97ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_purpose = NULL;
985fa790469656d3e093799329f814756600762a71Dylan Reid  dsp_context_free_called = 0;
993285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_called = 0;
1003285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_enable = 0;
1013ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  notify_node_left_right_swapped_called = 0;
102a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  cras_audio_format_set_channel_layout_called = 0;
103d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_get_pipeline_called = 0;
104d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_get_pipeline_ret = 0;
105d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_put_pipeline_called = 0;
106d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_source_buffer_called = 0;
107d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_sink_buffer_called = 0;
108d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  memset(&cras_dsp_pipeline_source_buffer, 0,
109d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid         sizeof(cras_dsp_pipeline_source_buffer));
110d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  memset(&cras_dsp_pipeline_sink_buffer, 0,
111d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid         sizeof(cras_dsp_pipeline_sink_buffer));
112d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_delay_called = 0;
113d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_called = 0;
114d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_sample_count = 0;
1152db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_input_channels_return = 2;
1162db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_output_channels_return = 2;
1172db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_context_new_return = NULL;
1181c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_num_frames = 0;
1191c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_called = 0;
1201c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_system_get_mute_return = 0;
1211c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_mix_mute_count = 0;
12237048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_called = 0;
12337048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_frames = NULL;
12437048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_called = 0;
12537048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_frames = NULL;
12624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev_buffer_size = 0;
127034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  cras_system_get_capture_gain_ret_value = 0;
128cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  // Assume there is some data in audio buffer.
129cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  memset(audio_buffer, 0xff, sizeof(audio_buffer));
130cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  if (audio_area) {
131cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    free(audio_area);
132cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    audio_area = NULL;
133cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  }
1341bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  put_buffer_nframes = 0;
135016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  output_should_wake_ret= 0;
136016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_called = 0;
137016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_enable = 0;
1386f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
1396f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
140838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidnamespace {
141838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
142838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid//  Test fill_time_from_frames
143838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan ReidTEST(IoDevTestSuite, FillTimeFromFramesNormal) {
144838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  struct timespec ts;
145838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
146f880b868b8da1f20594ff271492f7055d4977bb6Dylan Reid  cras_iodev_fill_time_from_frames(12000, 48000, &ts);
147838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(0, ts.tv_sec);
148838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
149838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
150838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
151838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
152838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan ReidTEST(IoDevTestSuite, FillTimeFromFramesLong) {
153838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  struct timespec ts;
154838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
155f880b868b8da1f20594ff271492f7055d4977bb6Dylan Reid  cras_iodev_fill_time_from_frames(120000 - 12000, 48000, &ts);
156838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(2, ts.tv_sec);
157838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
158838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
159838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
160838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
161838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan ReidTEST(IoDevTestSuite, FillTimeFromFramesShort) {
162838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  struct timespec ts;
163838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
164f880b868b8da1f20594ff271492f7055d4977bb6Dylan Reid  cras_iodev_fill_time_from_frames(12000 - 12000, 48000, &ts);
165838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(0, ts.tv_sec);
166838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(0, ts.tv_nsec);
167838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
168838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
169045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Changclass IoDevSetFormatTestSuite : public testing::Test {
170045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  protected:
171045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    virtual void SetUp() {
1722db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid      ResetStubData();
173045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      sample_rates_[0] = 44100;
174045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      sample_rates_[1] = 48000;
175045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      sample_rates_[2] = 0;
176045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
177045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      channel_counts_[0] = 2;
178045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      channel_counts_[1] = 0;
179663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      channel_counts_[2] = 0;
180663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
181a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      pcm_formats_[0] = SND_PCM_FORMAT_S16_LE;
182a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      pcm_formats_[1] = SND_PCM_FORMAT_S32_LE;
183a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      pcm_formats_[2] = static_cast<snd_pcm_format_t>(0);
184a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid
185663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      update_channel_layout_called = 0;
186663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      update_channel_layout_return_val = 0;
187045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
188045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      memset(&iodev_, 0, sizeof(iodev_));
189663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      iodev_.update_channel_layout = update_channel_layout;
190045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      iodev_.supported_rates = sample_rates_;
191045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      iodev_.supported_channel_counts = channel_counts_;
192a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      iodev_.supported_formats = pcm_formats_;
193aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid      iodev_.dsp_context = NULL;
194a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao
195a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao      cras_audio_format_set_channel_layout_called  = 0;
196045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    }
197045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
1985b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang    virtual void TearDown() {
1995b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang      cras_iodev_free_format(&iodev_);
2005b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang    }
2015b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
202045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    struct cras_iodev iodev_;
203045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    size_t sample_rates_[3];
204663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao    size_t channel_counts_[3];
205a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid    snd_pcm_format_t pcm_formats_[3];
206045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang};
207045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
208045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatSecondary) {
209045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
210045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
211045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
212045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
213045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 48000;
214045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
215ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  iodev_.direction = CRAS_STREAM_OUTPUT;
216ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  ResetStubData();
217045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
218045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
219bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
220bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
221bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
222ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  EXPECT_EQ(dsp_context_new_sample_rate, 48000);
22329b418afbe347e21bf01e29c235919ed5d3035dbYunlian Jiang  EXPECT_STREQ(dsp_context_new_purpose, "playback");
224045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
225045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
226a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan ReidTEST_F(IoDevSetFormatTestSuite, SupportedFormat32bit) {
227a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  struct cras_audio_format fmt;
228a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  int rc;
229a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid
230a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  fmt.format = SND_PCM_FORMAT_S32_LE;
231a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  fmt.frame_rate = 48000;
232a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  fmt.num_channels = 2;
233a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  iodev_.direction = CRAS_STREAM_OUTPUT;
234a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  ResetStubData();
235a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
236a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  EXPECT_EQ(0, rc);
237bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S32_LE, iodev_.ext_format->format);
238bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
239bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
240a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  EXPECT_EQ(dsp_context_new_sample_rate, 48000);
241a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  EXPECT_STREQ(dsp_context_new_purpose, "playback");
242a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid}
243a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid
244045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatPrimary) {
245045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
246045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
247045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
248045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
249045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 44100;
250045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
251ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  iodev_.direction = CRAS_STREAM_INPUT;
252ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  ResetStubData();
253045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
254045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
255bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
256bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(44100, iodev_.ext_format->frame_rate);
257bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
258ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  EXPECT_EQ(dsp_context_new_sample_rate, 44100);
25929b418afbe347e21bf01e29c235919ed5d3035dbYunlian Jiang  EXPECT_STREQ(dsp_context_new_purpose, "capture");
260045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
261045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
262045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatDivisor) {
263045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
264045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
265045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
266045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
267045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 96000;
268045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
269045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
270045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
271bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
272bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
273bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
274045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
275045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
27697d26e1687da4f38da88b868b6b827aeea50871aDylan ReidTEST_F(IoDevSetFormatTestSuite, Supported96k) {
27797d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  struct cras_audio_format fmt;
27897d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  int rc;
27997d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
28097d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[0] = 48000;
28197d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[1] = 96000;
28297d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[2] = 0;
28397d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
28497d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
28597d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.frame_rate = 96000;
28697d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.num_channels = 2;
28797d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
28897d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  EXPECT_EQ(0, rc);
289bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
290bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(96000, iodev_.ext_format->frame_rate);
291bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
29297d26e1687da4f38da88b868b6b827aeea50871aDylan Reid}
29397d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
29497d26e1687da4f38da88b868b6b827aeea50871aDylan ReidTEST_F(IoDevSetFormatTestSuite, LimitLowRate) {
29597d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  struct cras_audio_format fmt;
29697d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  int rc;
29797d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
29897d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[0] = 48000;
29997d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[1] = 8000;
30097d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[2] = 0;
30197d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
30297d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
30397d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.frame_rate = 8000;
30497d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.num_channels = 2;
30597d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
30697d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  EXPECT_EQ(0, rc);
307bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
308bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
309bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
31097d26e1687da4f38da88b868b6b827aeea50871aDylan Reid}
31197d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
312045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, UnsupportedChannelCount) {
313045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
314045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
315045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
316045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
317045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 96000;
318045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 1;
319045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
320045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
321bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
322bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
323bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
324045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
325045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
326045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatFallbackDefault) {
327045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
328045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
329045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
330045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
331045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 96008;
332045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
333045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
334045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
335bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
336bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(44100, iodev_.ext_format->frame_rate);
337bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
338045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
339045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
3402db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan ReidTEST_F(IoDevSetFormatTestSuite, OutputDSPChannleReduction) {
3412db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  struct cras_audio_format fmt;
3422db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  int rc;
3432db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3442db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
3452db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.frame_rate = 48000;
3462db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.num_channels = 2;
3472db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3482db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.direction = CRAS_STREAM_OUTPUT;
3492db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[0] = 1;
3502db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[1] = 0;
3512db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf00);
3522db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_get_pipeline_ret =  0xf01;
3532db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_input_channels_return = 2;
3542db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_output_channels_return = 1;
3552db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
3562db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  EXPECT_EQ(0, rc);
357bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
358bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
359bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
3602db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid}
3612db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3622db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan ReidTEST_F(IoDevSetFormatTestSuite, InputDSPChannleReduction) {
3632db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  struct cras_audio_format fmt;
3642db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  int rc;
3652db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3662db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
3672db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.frame_rate = 48000;
3682db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.num_channels = 2;
3692db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3702db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.direction = CRAS_STREAM_INPUT;
3712db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[0] = 10;
3722db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[1] = 0;
3732db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf00);
3742db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_get_pipeline_ret =  0xf01;
3752db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_input_channels_return = 10;
3762db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_output_channels_return = 2;
3772db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
3782db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  EXPECT_EQ(0, rc);
379bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
380bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
381bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
3822db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid}
3832db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
384663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu ChaoTEST_F(IoDevSetFormatTestSuite, UpdateChannelLayoutSuccess) {
385663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  struct cras_audio_format fmt;
386663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  int rc;
387663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
388663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.format = SND_PCM_FORMAT_S16_LE;
389663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.frame_rate = 48000;
390663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.num_channels = 6;
391663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
392663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[0] = 6;
393663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[1] = 2;
394663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
395663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  rc = cras_iodev_set_format(&iodev_, &fmt);
396663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  EXPECT_EQ(0, rc);
397bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
398bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
399bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(6, iodev_.ext_format->num_channels);
400663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao}
401663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
402663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu ChaoTEST_F(IoDevSetFormatTestSuite, UpdateChannelLayoutFail) {
403a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  static const int8_t stereo_layout[] =
404a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao      {0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
405663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  struct cras_audio_format fmt;
406a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  int rc, i;
407663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
408663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.format = SND_PCM_FORMAT_S16_LE;
409663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.frame_rate = 48000;
4101609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.num_channels = 2;
411663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
4125fa790469656d3e093799329f814756600762a71Dylan Reid  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf0f);
4135fa790469656d3e093799329f814756600762a71Dylan Reid
414663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  update_channel_layout_return_val = -1;
415663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[0] = 6;
416663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[1] = 2;
417663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
418663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  rc = cras_iodev_set_format(&iodev_, &fmt);
419663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  EXPECT_EQ(0, rc);
420bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
421bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
422bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
423bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, cras_audio_format_set_channel_layout_called);
4245fa790469656d3e093799329f814756600762a71Dylan Reid  EXPECT_EQ(0, dsp_context_free_called);
425a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  for (i = 0; i < CRAS_CH_MAX; i++)
426a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao    EXPECT_EQ(iodev_.format->channel_layout[i], stereo_layout[i]);
427663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao}
428663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
4291609667463605b64a0849f6ae7f26adf698cf5b3Ben ZhangTEST_F(IoDevSetFormatTestSuite, UpdateChannelLayoutFail6ch) {
4301609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  static const int8_t default_6ch_layout[] =
4311609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang      {0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1};
4321609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  struct cras_audio_format fmt;
4331609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  int rc, i;
4341609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4351609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.format = SND_PCM_FORMAT_S16_LE;
4361609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.frame_rate = 48000;
4371609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.num_channels = 6;
4381609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4391609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf0f);
4401609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4411609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  update_channel_layout_return_val = -1;
4421609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  iodev_.supported_channel_counts[0] = 6;
4431609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  iodev_.supported_channel_counts[1] = 2;
4441609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4451609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  rc = cras_iodev_set_format(&iodev_, &fmt);
4461609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(0, rc);
4471609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
4481609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
4491609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(6, iodev_.ext_format->num_channels);
4501609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(2, cras_audio_format_set_channel_layout_called);
4511609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(0, dsp_context_free_called);
4521609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  for (i = 0; i < CRAS_CH_MAX; i++)
4531609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang    EXPECT_EQ(iodev_.format->channel_layout[i], default_6ch_layout[i]);
4541609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang}
4551609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4561c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid// Put buffer tests
4571c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
458cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiangstatic int get_buffer(cras_iodev* iodev, struct cras_audio_area** area,
459cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang               unsigned int* num) {
460cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  size_t sz = sizeof(*audio_area) + sizeof(struct cras_channel_area) * 2;
461cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
462cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area = (cras_audio_area*)calloc(1, sz);
463cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->frames = *num;
464cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->num_channels = 2;
465cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[0].buf = audio_buffer;
466cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  channel_area_set_channel(&audio_area->channels[0], CRAS_CH_FL);
467cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[0].step_bytes = 4;
468cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[1].buf = audio_buffer + 2;
469cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  channel_area_set_channel(&audio_area->channels[1], CRAS_CH_FR);
470cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[1].step_bytes = 4;
471cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
472cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  *area = audio_area;
473cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  return 0;
474cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang}
475cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
4761c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic int put_buffer(struct cras_iodev *iodev, unsigned int nframes)
4771c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid{
4781c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  put_buffer_nframes = nframes;
479cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  if (audio_area) {
480cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    free(audio_area);
481cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    audio_area = NULL;
482cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  }
4831c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  return 0;
4841c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
4851c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
486016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int no_stream(struct cras_iodev *odev, int enable)
487016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang{
488016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_called++;
489016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_enable = enable;
490016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  // Use default no stream playback to test default behavior.
491016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  return cras_iodev_default_no_stream_playback(odev, enable);
492016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang}
493016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
494016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int output_should_wake(const struct cras_iodev *odev)
495016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang{
496016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  return output_should_wake_ret;
497016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang}
498016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
49937048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic int pre_dsp_hook(const uint8_t *frames, unsigned int nframes,
500081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen			const struct cras_audio_format *fmt, void *cb_data)
50137048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid{
50237048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_called++;
50337048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_frames = frames;
504081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  pre_dsp_hook_cb_data = cb_data;
50537048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  return 0;
50637048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid}
50737048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid
50837048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic int post_dsp_hook(const uint8_t *frames, unsigned int nframes,
509081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen			 const struct cras_audio_format *fmt, void *cb_data)
51037048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid{
51137048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_called++;
51237048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_frames = frames;
513081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  post_dsp_hook_cb_data = cb_data;
51437048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  return 0;
51537048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid}
51637048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid
5171c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, SystemMuted) {
5181c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
5191c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
5201c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
5211c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
5221c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5231c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
5241c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
5251c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_system_get_mute_return = 1;
5261c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5271c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
5281c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
5291c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
5301c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
5311c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
5321c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5331c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 20);
5341c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
5351c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(20, cras_mix_mute_count);
5361c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(20, put_buffer_nframes);
5371c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(20, rate_estimator_add_frames_num_frames);
5381c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
5391c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5401c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, NoDSP) {
5411c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
5421c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
5431c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
5441c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
5451c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5461c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
5471c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
5481c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5491c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
5501c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
5511c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
5521c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
5531c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
5541c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5551c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 22);
5561c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
5571c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
5581c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(22, put_buffer_nframes);
5591c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(22, rate_estimator_add_frames_num_frames);
5601c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
5611c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5621c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, DSP) {
5631c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
5641c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
5651c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
5661c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
5671c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5681c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
5691c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
5701c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.dsp_context = reinterpret_cast<cras_dsp_context*>(0x15);
5711c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_dsp_get_pipeline_ret = 0x25;
5721c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5731c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
5741c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
5751c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
5761c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
5771c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
578081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  cras_iodev_register_pre_dsp_hook(&iodev, pre_dsp_hook, (void *)0x1234);
579081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  cras_iodev_register_post_dsp_hook(&iodev, post_dsp_hook, (void *)0x5678);
5801c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5811c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 32);
5821c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
5831c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
58437048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  EXPECT_EQ(1, pre_dsp_hook_called);
58537048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  EXPECT_EQ(frames, pre_dsp_hook_frames);
586081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  EXPECT_EQ((void *)0x1234, pre_dsp_hook_cb_data);
58737048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  EXPECT_EQ(1, post_dsp_hook_called);
588081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  EXPECT_EQ((void *)0x5678, post_dsp_hook_cb_data);
5891c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(32, put_buffer_nframes);
5901c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(32, rate_estimator_add_frames_num_frames);
5911c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(32, cras_dsp_pipeline_apply_sample_count);
5921c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(cras_dsp_get_pipeline_called, cras_dsp_put_pipeline_called);
5931c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
5941c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5951c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, SoftVol) {
5961c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
5971c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
5981c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
5991c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
6001c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
6011c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
6021c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
6031c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.software_volume_needed = 1;
6041c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
6051c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
6061c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
6071c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
6081c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
6091c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
6101c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
6111c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_system_get_volume_return = 13;
6121c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  softvol_scalers[13] = 0.435;
6131c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
6141c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 53);
6151c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
6161c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
6171c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(53, put_buffer_nframes);
6181c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(53, rate_estimator_add_frames_num_frames);
6191c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(softvol_scalers[13], cras_scale_buffer_scaler);
620249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, cras_scale_buffer_fmt);
621249e72919eb928e107d251b262c305a8fe531641Dylan Reid}
622249e72919eb928e107d251b262c305a8fe531641Dylan Reid
623249e72919eb928e107d251b262c305a8fe531641Dylan ReidTEST(IoDevPutOutputBuffer, Scale32Bit) {
624249e72919eb928e107d251b262c305a8fe531641Dylan Reid  struct cras_audio_format fmt;
625249e72919eb928e107d251b262c305a8fe531641Dylan Reid  struct cras_iodev iodev;
626249e72919eb928e107d251b262c305a8fe531641Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
627249e72919eb928e107d251b262c305a8fe531641Dylan Reid  int rc;
628249e72919eb928e107d251b262c305a8fe531641Dylan Reid
629249e72919eb928e107d251b262c305a8fe531641Dylan Reid  ResetStubData();
630249e72919eb928e107d251b262c305a8fe531641Dylan Reid  memset(&iodev, 0, sizeof(iodev));
631249e72919eb928e107d251b262c305a8fe531641Dylan Reid  iodev.software_volume_needed = 1;
632249e72919eb928e107d251b262c305a8fe531641Dylan Reid
633249e72919eb928e107d251b262c305a8fe531641Dylan Reid  cras_system_get_volume_return = 13;
634249e72919eb928e107d251b262c305a8fe531641Dylan Reid  softvol_scalers[13] = 0.435;
635249e72919eb928e107d251b262c305a8fe531641Dylan Reid
636249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.format = SND_PCM_FORMAT_S32_LE;
637249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.frame_rate = 48000;
638249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.num_channels = 2;
639249e72919eb928e107d251b262c305a8fe531641Dylan Reid  iodev.format = &fmt;
640249e72919eb928e107d251b262c305a8fe531641Dylan Reid  iodev.put_buffer = put_buffer;
641249e72919eb928e107d251b262c305a8fe531641Dylan Reid
642249e72919eb928e107d251b262c305a8fe531641Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 53);
643249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(0, rc);
644249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
645249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(53, put_buffer_nframes);
646249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(53, rate_estimator_add_frames_num_frames);
647249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(SND_PCM_FORMAT_S32_LE, cras_scale_buffer_fmt);
6481c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
6491c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
650cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao// frames queued/avail tests
651cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
652cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chaostatic unsigned fr_queued = 0;
653cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
654cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chaostatic int frames_queued(const struct cras_iodev *iodev)
655cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao{
656cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  return fr_queued;
657cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao}
658cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
659cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu ChaoTEST(IoDevQueuedBuffer, ZeroMinBufferLevel) {
660cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  struct cras_iodev iodev;
661cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  int rc;
662cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
663cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  ResetStubData();
664cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  memset(&iodev, 0, sizeof(iodev));
665cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.direction = CRAS_STREAM_OUTPUT;
666cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.frames_queued = frames_queued;
667cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.min_buffer_level = 0;
668cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.buffer_size = 200;
669cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  fr_queued = 50;
670cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
671cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_frames_queued(&iodev);
672cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(50, rc);
673cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_buffer_avail(&iodev, rc);
674cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(150, rc);
675cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao}
676cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
677cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu ChaoTEST(IoDevQueuedBuffer, NonZeroMinBufferLevel) {
678cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  struct cras_iodev iodev;
679cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  int rc;
680cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
681cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  ResetStubData();
682cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  memset(&iodev, 0, sizeof(iodev));
683cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.direction = CRAS_STREAM_OUTPUT;
684cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.frames_queued = frames_queued;
685cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.min_buffer_level = 100;
686cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.buffer_size = 200;
687cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  fr_queued = 180;
688cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
689cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_frames_queued(&iodev);
690cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(80, rc);
691cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_buffer_avail(&iodev, rc);
692cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(20, rc);
693cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
694cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  /* When fr_queued < min_buffer_level*/
695cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  fr_queued = 80;
696cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_frames_queued(&iodev);
697cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(0, rc);
698cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_buffer_avail(&iodev, rc);
699cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(100, rc);
700cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao}
701cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
702bb28140f38fdf6627ec26696c943dfa4f9188450Hsin-Yu Chaostatic void update_active_node(struct cras_iodev *iodev,
7030def72b968591065f56e88d67e5c83234184811bHsin-Yu Chao                               unsigned node_idx,
7040def72b968591065f56e88d67e5c83234184811bHsin-Yu Chao                               unsigned dev_enabled)
7056f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang{
7066f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
7076f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
708b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic void dev_set_volume(struct cras_iodev *iodev)
709b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
710b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
711b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
712b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic void dev_set_capture_gain(struct cras_iodev *iodev)
713b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
714b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
715b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
716e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu ChaoTEST(IoNodePlug, PlugUnplugNode) {
7176f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  struct cras_iodev iodev;
7183b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  struct cras_ionode ionode, ionode2;
7196f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
720b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&iodev, 0, sizeof(iodev));
721b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&ionode, 0, sizeof(ionode));
7223b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  memset(&ionode2, 0, sizeof(ionode2));
7236f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  iodev.direction = CRAS_STREAM_INPUT;
7246f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  iodev.update_active_node = update_active_node;
7253b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  ionode.dev = &iodev;
7263b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_add_node(&iodev, &ionode);
7273b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  ionode2.dev = &iodev;
7283b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_add_node(&iodev, &ionode2);
7293b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_set_active_node(&iodev, &ionode);
7306f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  ResetStubData();
731786f9d1938966af8e1eb9f60559a3535b5c71ff8Chih-Chung Chang  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_PLUGGED, 1);
732e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  EXPECT_EQ(0, cras_iodev_list_disable_dev_called);
733e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_PLUGGED, 0);
734e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
7353b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao
7363b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  /* Unplug non-active node shouldn't disable iodev. */
7373b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_set_node_attr(&ionode2, IONODE_ATTR_PLUGGED, 1);
7383b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
7393b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_set_node_attr(&ionode2, IONODE_ATTR_PLUGGED, 0);
7403b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
7416f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
7426f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
743b2ad33424e21106930eb23db093746dc30926f27Chih-Chung ChangTEST(IoDev, AddRemoveNode) {
744b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  struct cras_iodev iodev;
745b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  struct cras_ionode ionode;
746b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang
747b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&iodev, 0, sizeof(iodev));
748b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&ionode, 0, sizeof(ionode));
749b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  ResetStubData();
750b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  EXPECT_EQ(0, notify_nodes_changed_called);
751b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  cras_iodev_add_node(&iodev, &ionode);
752b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  EXPECT_EQ(1, notify_nodes_changed_called);
753b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  cras_iodev_rm_node(&iodev, &ionode);
754b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  EXPECT_EQ(2, notify_nodes_changed_called);
755b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang}
756b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang
757c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung ChangTEST(IoDev, SetActiveNode) {
758c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  struct cras_iodev iodev;
759c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  struct cras_ionode ionode;
760c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang
761c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  memset(&iodev, 0, sizeof(iodev));
762c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  memset(&ionode, 0, sizeof(ionode));
763c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  ResetStubData();
764c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  EXPECT_EQ(0, notify_active_node_changed_called);
765c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  cras_iodev_set_active_node(&iodev, &ionode);
766c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  EXPECT_EQ(1, notify_active_node_changed_called);
767c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang}
768c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang
769b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan ReidTEST(IoDev, SetNodeVolume) {
770b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  struct cras_iodev iodev;
771b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  struct cras_ionode ionode;
772b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
773b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  memset(&iodev, 0, sizeof(iodev));
774b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  memset(&ionode, 0, sizeof(ionode));
775b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  iodev.set_volume = dev_set_volume;
776b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  iodev.set_capture_gain = dev_set_capture_gain;
777b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  ionode.dev = &iodev;
778b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  ResetStubData();
779b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_VOLUME, 10);
780b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  EXPECT_EQ(1, notify_node_volume_called);
781b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  iodev.direction = CRAS_STREAM_INPUT;
782b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_CAPTURE_GAIN, 10);
783b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  EXPECT_EQ(1, notify_node_capture_gain_called);
784b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
785b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
7863285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi ChiangTEST(IoDev, SetNodeSwapLeftRight) {
7873285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  struct cras_iodev iodev;
7883285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  struct cras_ionode ionode;
7893285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang
7903285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
7913285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
7923285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  iodev.set_swap_mode_for_node = set_swap_mode_for_node;
7933285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  ionode.dev = &iodev;
7943285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  ResetStubData();
7953285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_SWAP_LEFT_RIGHT, 1);
7963285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(1, set_swap_mode_for_node_called);
7973285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(1, set_swap_mode_for_node_enable);
7983285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(1, ionode.left_right_swapped);
7993ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  EXPECT_EQ(1, notify_node_left_right_swapped_called);
8003285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_SWAP_LEFT_RIGHT, 0);
8013285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(2, set_swap_mode_for_node_called);
8023285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(0, set_swap_mode_for_node_enable);
8033285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(0, ionode.left_right_swapped);
8043ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  EXPECT_EQ(2, notify_node_left_right_swapped_called);
8053285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang}
8063285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang
8075342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8085342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang// Test software volume changes for default output.
8095342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi ChiangTEST(IoDev, SoftwareVolume) {
8105342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  struct cras_iodev iodev;
8115342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  struct cras_ionode ionode;
8125342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8135342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
8145342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
8155342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  ResetStubData();
8165342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8175342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.nodes = &ionode;
8185342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node = &ionode;
8195342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node->dev = &iodev;
8205342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8215342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node->volume = 100;
8225342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.software_volume_needed = 0;
8235342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8245342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8255342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  softvol_scalers[80] = 0.5;
8265342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  softvol_scalers[70] = 0.3;
8275342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8285342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // Check that system volume changes software volume if needed.
8295342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  cras_system_get_volume_return = 80;
8305342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // system_volume - 100 + node_volume = 80 - 100 + 100 = 80
8315342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  EXPECT_FLOAT_EQ(0.5, cras_iodev_get_software_volume_scaler(&iodev));
8325342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8335342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // Check that node volume changes software volume if needed.
8345342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node->volume = 90;
8355342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // system_volume - 100 + node_volume = 80 - 100 + 90 = 70
8365342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  EXPECT_FLOAT_EQ(0.3, cras_iodev_get_software_volume_scaler(&iodev));
8375342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang}
8385342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
839034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang// Test software gain scaler.
840034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi ChiangTEST(IoDev, SoftwareGain) {
841034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  struct cras_iodev iodev;
842034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  struct cras_ionode ionode;
843034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
844034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
845034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
846034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ResetStubData();
847034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
848034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  iodev.nodes = &ionode;
849034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  iodev.active_node = &ionode;
850034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  iodev.active_node->dev = &iodev;
851034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
852034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.capture_gain= 400;
853034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.software_volume_needed = 1;
854034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.max_software_gain = 3000;
855034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
856034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // Check that system volume changes software volume if needed.
857034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  cras_system_get_capture_gain_ret_value = 2000;
858034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // system_gain + node_gain = 2000 + 400  = 2400
859034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // 2400 dBm is 15.848931
860034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(15.848931, cras_iodev_get_software_gain_scaler(&iodev));
861034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(3000, cras_iodev_maximum_software_gain(&iodev));
862034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
863034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // Software gain scaler should be 1.0 if software gain is not needed.
864034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.software_volume_needed = 0;
865034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(1.0, cras_iodev_get_software_gain_scaler(&iodev));
866034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(0, cras_iodev_maximum_software_gain(&iodev));
867034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang}
868034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
869b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// This get_buffer implementation set returned frames larger than requested
870b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// frames.
871b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiangstatic int bad_get_buffer(struct cras_iodev *iodev,
872b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang                          struct cras_audio_area **area,
873b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang                          unsigned *frames)
874b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang{
875b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  *frames = *frames + 1;
876b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  return 0;
877b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang}
878b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
879b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// Check that if get_buffer implementation returns invalid frames,
880b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// cras_iodev_get_output_buffer and cras_iodev_get_input_buffer can return
881b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// error.
882b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi ChiangTEST(IoDev, GetBufferInvalidFrames) {
883b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  struct cras_iodev iodev;
884b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  struct cras_audio_area **area = NULL;
885b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  unsigned int frames = 512;
886b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  struct cras_audio_format fmt;
887b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
888b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  // Format is used in cras_iodev_get_input_buffer;
889b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
890b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  fmt.frame_rate = 48000;
891b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  fmt.num_channels = 2;
892b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
893b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
894b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
895b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  ResetStubData();
896b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
897b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  iodev.format = &fmt;
898b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  iodev.get_buffer = bad_get_buffer;
899b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
900b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  EXPECT_EQ(-EINVAL, cras_iodev_get_output_buffer(&iodev, area, &frames));
901b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  EXPECT_EQ(-EINVAL, cras_iodev_get_input_buffer(&iodev, area, &frames));
902b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang}
903b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
90424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chaostatic int open_dev(struct cras_iodev *iodev) {
90524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev->buffer_size = iodev_buffer_size;
90624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  return 0;
90724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao}
90824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
90950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenOutputDeviceNoStart) {
91050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  struct cras_iodev iodev;
91150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
91250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
91350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.open_dev = open_dev;
91450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
91550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  ResetStubData();
91650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
91750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
91850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
91950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev_buffer_size = 1024;
92050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  cras_iodev_open(&iodev, 240);
92150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
92250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
92350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
92450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is no stream run when there is no start ops.
92550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
92650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
92750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
92850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiangint fake_start(const struct cras_iodev *iodev) {
92950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  return 0;
93050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
93150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
93250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenOutputDeviceWithStart) {
93350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  struct cras_iodev iodev;
93450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
93550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
93650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.open_dev = open_dev;
93750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
93850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  ResetStubData();
93950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
94050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
94150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.start = fake_start;
94250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
94350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev_buffer_size = 1024;
94450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  cras_iodev_open(&iodev, 240);
94550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
94650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
94750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
94850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is no stream run when there is start ops.
94950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_OPEN, iodev.state);
95050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
95150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
95250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenInputDeviceNoStart) {
95350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  struct cras_iodev iodev;
95450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
95550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
95650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.open_dev = open_dev;
95750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
95850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  ResetStubData();
95950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
96050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
96150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
96250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev_buffer_size = 1024;
96350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  cras_iodev_open(&iodev, 240);
96450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
96550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
96650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
96750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is normal run when there is start ops.
96850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
96950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
97050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
97150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenInputDeviceWithStart) {
972016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  struct cras_iodev iodev;
973016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
974016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
975016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev.open_dev = open_dev;
97650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
977016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  ResetStubData();
978016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
97950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
98050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.start = fake_start;
981016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
982016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev_buffer_size = 1024;
983016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  cras_iodev_open(&iodev, 240);
984016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
985016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
98650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
98750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is normal run even if there is start ops.
98850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
989016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang}
990016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
99124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu ChaoTEST(IoDev, AddRmStream) {
99224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  struct cras_iodev iodev;
99324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  struct cras_rstream rstream1, rstream2;
99424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  struct dev_stream stream1, stream2;
99524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
99624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  memset(&iodev, 0, sizeof(iodev));
99724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev.open_dev = open_dev;
99824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  rstream1.cb_threshold = 800;
99924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  stream1.stream = &rstream1;
100024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  rstream2.cb_threshold = 400;
100124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  stream2.stream = &rstream2;
100224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  ResetStubData();
100324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
100424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev_buffer_size = 1024;
100524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_open(&iodev, rstream1.cb_threshold);
100624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(0, iodev.max_cb_level);
100724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(512, iodev.min_cb_level);
100824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
100924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  /* min_cb_level should not exceed half the buffer size. */
101024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_add_stream(&iodev, &stream1);
101124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(800, iodev.max_cb_level);
101224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(512, iodev.min_cb_level);
101324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
101424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_add_stream(&iodev, &stream2);
101524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(800, iodev.max_cb_level);
101624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.min_cb_level);
101724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
101824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_rm_stream(&iodev, &rstream1);
101924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.max_cb_level);
102024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.min_cb_level);
102124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
102224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  /* When all streams are removed, keep the last min_cb_level for draining. */
102324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_rm_stream(&iodev, &rstream2);
102424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(0, iodev.max_cb_level);
102524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.min_cb_level);
102685502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang}
102785502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang
102885502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiangstatic int start(const struct cras_iodev *iodev) {
102985502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  return 0;
103085502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang}
103185502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang
103285502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi ChiangTEST(IoDev, StartDevice) {
103385502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  struct cras_iodev iodev;
103485502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang
103585502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
103685502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  iodev.start = start;
103785502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang
103885502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  // Start fails if it is called in closed state.
103950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
104085502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  ASSERT_TRUE(cras_iodev_start(&iodev));
104185502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang
104285502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  // Start can only be called in open state.
104350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
104485502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  EXPECT_EQ(0, cras_iodev_start(&iodev));
104550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
104650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // The state should be normal run.
104750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, cras_iodev_state(&iodev));
1048e91895c69bef2515b60d6e4514a5f8e8c53cb36fCheng-Yi Chiang}
1049e91895c69bef2515b60d6e4514a5f8e8c53cb36fCheng-Yi Chiang
1050cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi ChiangTEST(IoDev, FillZeros) {
1051cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  struct cras_iodev iodev;
1052cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  struct cras_audio_format fmt;
1053cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  unsigned int frames = 50;
1054cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  int16_t *zeros;
1055cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  int rc;
1056cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1057cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  ResetStubData();
1058cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1059cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1060cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
1061cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  fmt.frame_rate = 48000;
1062cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  fmt.num_channels = 2;
1063cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.ext_format = &fmt;
1064cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.get_buffer = get_buffer;
1065cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.put_buffer = put_buffer;
1066cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1067cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
1068cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  rc = cras_iodev_fill_odev_zeros(&iodev, frames);
1069cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(-EINVAL, rc);
1070cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1071cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
1072cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  rc = cras_iodev_fill_odev_zeros(&iodev, frames);
1073cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1074cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(0, rc);
1075cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(frames, put_buffer_nframes);
1076cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  zeros = (int16_t *)calloc(frames * 2, sizeof(*zeros));
1077cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  rc = memcmp(audio_buffer, zeros, frames * 2 * 2);
1078cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  free(zeros);
1079cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(0, rc);
1080cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang}
1081cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
108285502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi ChiangTEST(IoDev, NoStreamPlaybackRunning) {
10831bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  struct cras_iodev iodev;
10841bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  struct cras_audio_format fmt;
10851bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  unsigned int hw_level = 50;
10861bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  unsigned int min_cb_level = 240;
10871bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  unsigned int zeros_to_fill;
10881bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  int16_t *zeros;
10891bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  int rc;
10901bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
10911bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
10921bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
10931bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
10941bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fmt.frame_rate = 48000;
10951bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fmt.num_channels = 2;
10961bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.ext_format = &fmt;
10971bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.min_cb_level = min_cb_level;
10981bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.get_buffer = get_buffer;
10991bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.put_buffer = put_buffer;
11001bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.frames_queued = frames_queued;
11011bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.min_buffer_level = 0;
11021bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
11031bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.buffer_size = BUFFER_SIZE;
1104016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev.no_stream = no_stream;
1105016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1106016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  ResetStubData();
11071bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
11081bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // Device is running. hw_level is less than target.
11091bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // Need to fill to callback level * 2;
111050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
11111bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fr_queued = hw_level;
11121bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  zeros_to_fill = min_cb_level * 2 - hw_level;
11131bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
111485502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  rc = cras_iodev_no_stream_playback(&iodev, 1);
11151bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
11161bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(0, rc);
111785502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  EXPECT_EQ(1, no_stream_called);
111885502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  EXPECT_EQ(1, no_stream_enable);
111950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
11201bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(zeros_to_fill, put_buffer_nframes);
11211bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  zeros = (int16_t *)calloc(zeros_to_fill * 2, sizeof(*zeros));
11221bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(0, memcmp(audio_buffer, zeros, zeros_to_fill * 2 * 2));
11231bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  free(zeros);
11241bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
11251bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  ResetStubData();
11261bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
11271bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // Device is running. hw_level is not less than target.
11281bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // No need to fill zeros.
112950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
11301bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  hw_level = min_cb_level * 2;
11311bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fr_queued = hw_level;
11321bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  zeros_to_fill = 0;
11331bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
113485502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  rc = cras_iodev_no_stream_playback(&iodev, 1);
11351bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(0, rc);
113685502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  EXPECT_EQ(1, no_stream_called);
113785502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  EXPECT_EQ(1, no_stream_enable);
113850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
11391bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(zeros_to_fill, put_buffer_nframes);
1140016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1141016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  ResetStubData();
1142016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
114385502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  // Device is running. Resume normal playback.
114450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
114585502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang  rc = cras_iodev_no_stream_playback(&iodev, 0);
1146016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1147016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(1, no_stream_called);
1148016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, no_stream_enable);
114950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
11501bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang}
11511bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
1152103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi ChiangTEST(IoDev, OutputDeviceShouldWake) {
1153103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  struct cras_iodev iodev;
1154103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  int rc;
1155103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1156103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1157103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1158103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  ResetStubData();
1159103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1160103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is not running. No need to wake for this device.
116150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
1162103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1163103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1164103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1165103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. Need to wake for this device.
116650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
1167103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1168103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(1, rc);
1169103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1170016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  // Device is running. Device has output_should_wake ops.
1171016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev.output_should_wake = output_should_wake;
1172016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  output_should_wake_ret = 0;
1173016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1174016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1175016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1176016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  // Device is running. Device has output_should_wake ops.
1177016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  output_should_wake_ret = 1;
1178016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1179016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(1, rc);
1180016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1181103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Ignore input device.
1182103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
1183103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1184103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1185103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang}
1186103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1187103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi ChiangTEST(IoDev, FramesToPlayInSleep) {
1188103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  struct cras_iodev iodev;
1189103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  unsigned int min_cb_level = 240, hw_level;
1190103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  unsigned int got_hw_level, got_frames;
1191103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1192103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1193103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.frames_queued = frames_queued;
1194103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.min_buffer_level = 0;
1195103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
1196103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.buffer_size = BUFFER_SIZE;
1197103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.min_cb_level = min_cb_level;
1198103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1199103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  ResetStubData();
1200103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1201103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. There is at least one stream for this device.
1202103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // hw_level is greater than min_cb_level.
120350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
1204103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  hw_level = min_cb_level + 50;
1205103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  fr_queued = hw_level;
1206103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.streams = reinterpret_cast<struct dev_stream *>(0x1);
1207103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1208103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  got_frames = cras_iodev_frames_to_play_in_sleep(&iodev, &got_hw_level);
1209103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_hw_level);
1210103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_frames);
1211103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1212103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. There is no stream for this device.
1213103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // hw_level is greater than min_cb_level.
1214103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.streams = NULL;
1215103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1216103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  got_frames = cras_iodev_frames_to_play_in_sleep(&iodev, &got_hw_level);
1217103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_hw_level);
1218103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level - min_cb_level, got_frames);
1219103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1220103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. There is no stream for this device.
1221103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // hw_level is less than min_cb_level.
1222103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.streams = NULL;
1223103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  hw_level = min_cb_level - 50;
1224103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  fr_queued = hw_level;
1225103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1226103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  got_frames = cras_iodev_frames_to_play_in_sleep(&iodev, &got_hw_level);
1227103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_hw_level);
1228103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(0, got_frames);
1229103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang}
1230103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1231838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidextern "C" {
1232838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1233838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid//  From libpthread.
1234838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidint pthread_create(pthread_t *thread, const pthread_attr_t *attr,
1235838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid                   void *(*start_routine)(void*), void *arg) {
1236838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  return 0;
1237838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
1238838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1239838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidint pthread_join(pthread_t thread, void **value_ptr) {
1240838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  return 0;
1241838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
1242838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1243f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao// From audio_thread
1244f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chaostruct cras_fmt_conv *audio_thread_get_global_remix_converter()
1245f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao{
1246f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao  return NULL;
1247f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao}
1248f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao
1249f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao// Fromt fmt_conv
1250f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chaovoid cras_channel_remix_convert(struct cras_fmt_conv *conv,
1251f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao    uint8_t *in_buf,
1252f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao    size_t frames)
1253f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao{
1254f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao}
1255f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao
1256fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid// From buffer_share
1257fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidstruct buffer_share *buffer_share_create(unsigned int buf_sz) {
1258fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return NULL;
1259fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1260fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1261fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidvoid buffer_share_destroy(struct buffer_share *mix)
1262fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid{
1263fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1264fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1265fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidint buffer_share_offset_update(struct buffer_share *mix, unsigned int id,
1266fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid                               unsigned int frames) {
1267fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1268fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1269fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1270fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidunsigned int buffer_share_get_new_write_point(struct buffer_share *mix) {
1271fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1272fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1273fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1274fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidint buffer_share_add_id(struct buffer_share *mix, unsigned int id) {
1275fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1276fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1277fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1278fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidint buffer_share_rm_id(struct buffer_share *mix, unsigned int id) {
1279fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1280fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1281fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1282fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidunsigned int buffer_share_id_offset(const struct buffer_share *mix,
1283fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid                                    unsigned int id)
1284fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid{
1285fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1286fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1287fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1288386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid// From cras_system_state.
128957852ea82d5f4c4491f4cfe9faafc5cbddfc4979Cheng-Yi Chiangvoid cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction) {
1290386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid}
1291386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid
129257852ea82d5f4c4491f4cfe9faafc5cbddfc4979Cheng-Yi Chiangvoid cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction) {
1293386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid}
1294386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid
12955b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang// From cras_dsp
1296aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidstruct cras_dsp_context *cras_dsp_context_new(int sample_rate,
12975b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang                                              const char *purpose)
12985b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang{
1299ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_sample_rate = sample_rate;
1300ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_purpose = purpose;
13012db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  return cras_dsp_context_new_return;
13025b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang}
13035b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
13045b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Changvoid cras_dsp_context_free(struct cras_dsp_context *ctx)
13055b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang{
13065fa790469656d3e093799329f814756600762a71Dylan Reid  dsp_context_free_called++;
13075b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang}
13085b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
13095b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Changvoid cras_dsp_load_pipeline(struct cras_dsp_context *ctx)
13105b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang{
13115b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang}
13125b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
13137057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Changvoid cras_dsp_set_variable(struct cras_dsp_context *ctx, const char *key,
13147057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang                           const char *value)
13157057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang{
13167057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang}
13177057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang
1318d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstruct pipeline *cras_dsp_get_pipeline(struct cras_dsp_context *ctx)
1319d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1320d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_get_pipeline_called++;
1321d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return reinterpret_cast<struct pipeline *>(cras_dsp_get_pipeline_ret);
1322d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1323d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1324d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidvoid cras_dsp_put_pipeline(struct cras_dsp_context *ctx)
1325d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1326d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_put_pipeline_called++;
1327d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1328d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1329d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidfloat *cras_dsp_pipeline_get_source_buffer(struct pipeline *pipeline,
1330d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid					   int index)
1331d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1332d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_source_buffer_called++;
1333d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return cras_dsp_pipeline_source_buffer[index];
1334d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1335d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1336d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidfloat *cras_dsp_pipeline_get_sink_buffer(struct pipeline *pipeline, int index)
1337d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1338d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_sink_buffer_called++;
1339d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return cras_dsp_pipeline_sink_buffer[index];
1340d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1341d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1342d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidint cras_dsp_pipeline_get_delay(struct pipeline *pipeline)
1343d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1344d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_delay_called++;
1345d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return 0;
1346d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1347d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1348aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidvoid cras_dsp_pipeline_apply(struct pipeline *pipeline,
1349d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid			     uint8_t *buf, unsigned int frames)
1350d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1351d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_called++;
1352d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_sample_count = frames;
1353d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1354d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1355d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidvoid cras_dsp_pipeline_add_statistic(struct pipeline *pipeline,
1356d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                                     const struct timespec *time_delta,
1357d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                                     int samples)
1358d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1359d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1360d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1361aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidunsigned int cras_dsp_num_output_channels(const struct cras_dsp_context *ctx)
1362aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid{
13632db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid	return cras_dsp_num_output_channels_return;
1364aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid}
1365aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid
1366aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidunsigned int cras_dsp_num_input_channels(const struct cras_dsp_context *ctx)
1367aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid{
13682db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid	return cras_dsp_num_input_channels_return;
1369aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid}
1370aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid
1371d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid// From audio thread
1372d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reidint audio_thread_post_message(struct audio_thread *thread,
1373d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid                              struct audio_thread_msg *msg) {
1374d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid  return 0;
1375d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid}
1376d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid
1377ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changvoid cras_iodev_list_select_node(enum CRAS_STREAM_DIRECTION direction,
1378ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang                                 cras_node_id_t node_id)
1379f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Chang{
1380ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_called++;
1381ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_direction = direction;
1382ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_id = node_id;
1383f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Chang}
1384f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Chang
1385ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changint cras_iodev_list_node_selected(struct cras_ionode *node)
13866f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang{
1387ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  return node == node_selected;
13886f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
13896f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
1390e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chaovoid cras_iodev_list_disable_dev(struct cras_iodev *dev)
1391e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao{
1392e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  cras_iodev_list_disable_dev_called++;
1393e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao}
1394e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao
1395b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Changvoid cras_iodev_list_notify_nodes_changed()
1396b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang{
1397b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  notify_nodes_changed_called++;
1398b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang}
1399b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang
1400dc115f02e335a6d197b6ef4bf0516e4866a7fc6eDylan Reidvoid cras_iodev_list_notify_active_node_changed(
1401dc115f02e335a6d197b6ef4bf0516e4866a7fc6eDylan Reid				enum CRAS_STREAM_DIRECTION direction)
1402c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang{
1403c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  notify_active_node_changed_called++;
1404c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang}
1405c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang
1406b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidvoid cras_iodev_list_notify_node_volume(struct cras_ionode *node)
1407b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
1408b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid	notify_node_volume_called++;
1409b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
1410b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
1411b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidvoid cras_iodev_list_notify_node_capture_gain(struct cras_ionode *node)
1412b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
1413b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid	notify_node_capture_gain_called++;
1414b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
1415b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
14163ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiangvoid cras_iodev_list_notify_node_left_right_swapped(struct cras_ionode *node)
14173ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang{
14183ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  notify_node_left_right_swapped_called++;
14193ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang}
14203ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang
14219690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chaostruct cras_audio_area *cras_audio_area_create(int num_channels) {
14229690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao	return NULL;
14239690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao}
14249690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao
14259690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chaovoid cras_audio_area_destroy(struct cras_audio_area *area) {
14269690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao}
14279690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao
14289690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chaovoid cras_audio_area_config_channels(struct cras_audio_area *area,
14299690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao                                     const struct cras_audio_format *fmt) {
14309690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao}
14319690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao
14327b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chaoint cras_audio_format_set_channel_layout(struct cras_audio_format *format,
14337b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao					 const int8_t layout[CRAS_CH_MAX])
14347b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao{
1435a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  int i;
1436a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  cras_audio_format_set_channel_layout_called++;
1437a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  for (i = 0; i < CRAS_CH_MAX; i++)
1438a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao    format->channel_layout[i] = layout[i];
14397b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao  return 0;
14407b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao}
14417b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao
14425342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangfloat softvol_get_scaler(unsigned int volume_index)
14435342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang{
14445342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang	return softvol_scalers[volume_index];
14455342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang}
14465342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
14475342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangsize_t cras_system_get_volume() {
14485342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  return cras_system_get_volume_return;
14495342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang}
14507b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao
1451034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chianglong cras_system_get_capture_gain() {
1452034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  return cras_system_get_capture_gain_ret_value;
1453034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang}
1454034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
1455d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidint cras_system_get_mute() {
14561c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  return cras_system_get_mute_return;
1457d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1458d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1459d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidint cras_system_get_capture_mute() {
1460d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return 0;
1461d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1462d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1463249e72919eb928e107d251b262c305a8fe531641Dylan Reidvoid cras_scale_buffer(snd_pcm_format_t fmt, uint8_t *buffer,
14641efd30f3854ac69a6916bdeaa82dae3f01d18acaDylan Reid                       unsigned int count, float scaler) {
1465249e72919eb928e107d251b262c305a8fe531641Dylan Reid  cras_scale_buffer_fmt = fmt;
14661c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_scale_buffer_scaler = scaler;
1467d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1468d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1469d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidsize_t cras_mix_mute_buffer(uint8_t *dst,
1470d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                            size_t frame_bytes,
1471d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                            size_t count) {
1472d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_mix_mute_count = count;
1473d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return count;
1474d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1475d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
147665ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidstruct rate_estimator *rate_estimator_create(unsigned int rate,
147765ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid                                             const struct timespec *window_size,
147865ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid                                             double smooth_factor) {
147965ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid  return NULL;
148065ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
148165ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
148265ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidvoid rate_estimator_destroy(struct rate_estimator *re) {
148365ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
148465ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
148565ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidvoid rate_estimator_add_frames(struct rate_estimator *re, int fr) {
14861c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_called++;
14871c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_num_frames = fr;
148865ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
148965ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
149065ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidint rate_estimator_check(struct rate_estimator *re, int level,
149165ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid                         struct timespec *now) {
149265ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid  return 0;
149365ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
149465ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
149565ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidvoid rate_estimator_reset_rate(struct rate_estimator *re, unsigned int rate) {
149665ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
149765ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
149865ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reiddouble rate_estimator_get_rate(struct rate_estimator *re) {
149965ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid  return 0.0;
150065ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
150165ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
1502c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chaounsigned int dev_stream_cb_threshold(const struct dev_stream *dev_stream) {
150324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  if (dev_stream->stream)
150424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao    return dev_stream->stream->cb_threshold;
1505c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chao  return 0;
1506c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chao}
1507c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chao
1508838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}  // extern "C"
1509838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}  //  namespace
1510838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1511838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidint main(int argc, char **argv) {
1512838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  ::testing::InitGoogleTest(&argc, argv);
1513838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  return RUN_ALL_TESTS();
1514838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
1515