iodev_unittest.cc revision 4f86aad321250a527075476dac94241c24817521
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"
14dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang#include "audio_thread_log.h"
155342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
165342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang// Mock software volume scalers.
175342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangfloat softvol_scalers[101];
18838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
19838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
20cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang#define BUFFER_SIZE 8192
21cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
22e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chaostatic int cras_iodev_list_disable_dev_called;
23ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changstatic int select_node_called;
24ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changstatic enum CRAS_STREAM_DIRECTION select_node_direction;
25ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changstatic cras_node_id_t select_node_id;
26f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Changstatic struct cras_ionode *node_selected;
27b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Changstatic size_t notify_nodes_changed_called;
28c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Changstatic size_t notify_active_node_changed_called;
29b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic size_t notify_node_volume_called;
30b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic size_t notify_node_capture_gain_called;
31ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Changstatic int dsp_context_new_sample_rate;
32ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Changstatic const char *dsp_context_new_purpose;
335fa790469656d3e093799329f814756600762a71Dylan Reidstatic int dsp_context_free_called;
34663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chaostatic int update_channel_layout_called;
35663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chaostatic int update_channel_layout_return_val;
363285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiangstatic int  set_swap_mode_for_node_called;
373285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiangstatic int  set_swap_mode_for_node_enable;
383ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiangstatic int notify_node_left_right_swapped_called;
39a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chaostatic int cras_audio_format_set_channel_layout_called;
405342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangstatic unsigned int cras_system_get_volume_return;
41d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_get_pipeline_called;
42d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_get_pipeline_ret;
43d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_put_pipeline_called;
44d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_get_source_buffer_called;
45d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_get_sink_buffer_called;
46d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic float cras_dsp_pipeline_source_buffer[2][DSP_BUFFER_SIZE];
47d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic float cras_dsp_pipeline_sink_buffer[2][DSP_BUFFER_SIZE];
48d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_get_delay_called;
49d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_apply_called;
50d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_apply_sample_count;
51d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic unsigned int cras_mix_mute_count;
522db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reidstatic unsigned int cras_dsp_num_input_channels_return;
532db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reidstatic unsigned int cras_dsp_num_output_channels_return;
542db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reidstruct cras_dsp_context *cras_dsp_context_new_return;
551c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic unsigned int rate_estimator_add_frames_num_frames;
561c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic unsigned int rate_estimator_add_frames_called;
571c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic int cras_system_get_mute_return;
58249e72919eb928e107d251b262c305a8fe531641Dylan Reidstatic snd_pcm_format_t cras_scale_buffer_fmt;
591c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic float cras_scale_buffer_scaler;
6037048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic unsigned int pre_dsp_hook_called;
6137048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic const uint8_t *pre_dsp_hook_frames;
62081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chenstatic void *pre_dsp_hook_cb_data;
6337048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic unsigned int post_dsp_hook_called;
6437048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic const uint8_t *post_dsp_hook_frames;
65081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chenstatic void *post_dsp_hook_cb_data;
6624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chaostatic int iodev_buffer_size;
67034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiangstatic long cras_system_get_capture_gain_ret_value;
68cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiangstatic uint8_t audio_buffer[BUFFER_SIZE];
69cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiangstatic struct cras_audio_area *audio_area;
701bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiangstatic unsigned int put_buffer_nframes;
71016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int output_should_wake_ret;
72016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int no_stream_called;
73016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int no_stream_enable;
7439c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang// This will be used extensively in cras_iodev.
75dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstruct audio_thread_event_log *atlog;
76dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstatic unsigned int simple_no_stream_called;
77dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstatic int simple_no_stream_enable;
78dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstatic int dev_stream_playback_frames_ret;
79595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiangstatic int get_num_underruns_ret;
80dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
81663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
82663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao// Iodev callback
83663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chaoint update_channel_layout(struct cras_iodev *iodev) {
84663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  update_channel_layout_called = 1;
85663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  return update_channel_layout_return_val;
86663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao}
876f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
883285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang// Iodev callback
893285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiangint set_swap_mode_for_node(struct cras_iodev *iodev, struct cras_ionode *node,
903285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang                           int enable)
913285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang{
923285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_called++;
933285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_enable = enable;
943285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  return 0;
953285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang}
963285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang
976f0a5e6a967558105f37513801af573167890f67Chih-Chung Changvoid ResetStubData() {
98e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  cras_iodev_list_disable_dev_called = 0;
99ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_called = 0;
100b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  notify_nodes_changed_called = 0;
101c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  notify_active_node_changed_called = 0;
102b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  notify_node_volume_called = 0;
103b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  notify_node_capture_gain_called = 0;
104ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_sample_rate = 0;
105ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_purpose = NULL;
1065fa790469656d3e093799329f814756600762a71Dylan Reid  dsp_context_free_called = 0;
1073285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_called = 0;
1083285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_enable = 0;
1093ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  notify_node_left_right_swapped_called = 0;
110a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  cras_audio_format_set_channel_layout_called = 0;
111d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_get_pipeline_called = 0;
112d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_get_pipeline_ret = 0;
113d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_put_pipeline_called = 0;
114d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_source_buffer_called = 0;
115d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_sink_buffer_called = 0;
116d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  memset(&cras_dsp_pipeline_source_buffer, 0,
117d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid         sizeof(cras_dsp_pipeline_source_buffer));
118d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  memset(&cras_dsp_pipeline_sink_buffer, 0,
119d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid         sizeof(cras_dsp_pipeline_sink_buffer));
120d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_delay_called = 0;
121d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_called = 0;
122d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_sample_count = 0;
1232db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_input_channels_return = 2;
1242db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_output_channels_return = 2;
1252db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_context_new_return = NULL;
1261c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_num_frames = 0;
1271c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_called = 0;
1281c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_system_get_mute_return = 0;
1291c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_mix_mute_count = 0;
13037048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_called = 0;
13137048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_frames = NULL;
13237048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_called = 0;
13337048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_frames = NULL;
13424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev_buffer_size = 0;
135034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  cras_system_get_capture_gain_ret_value = 0;
136cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  // Assume there is some data in audio buffer.
137cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  memset(audio_buffer, 0xff, sizeof(audio_buffer));
138cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  if (audio_area) {
139cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    free(audio_area);
140cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    audio_area = NULL;
141cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  }
1421bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  put_buffer_nframes = 0;
143016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  output_should_wake_ret= 0;
144016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_called = 0;
145016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_enable = 0;
146dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  simple_no_stream_called = 0;
147dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  simple_no_stream_enable = 0;
148dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 0;
14939c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang  if (!atlog)
15039c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang    atlog = audio_thread_event_log_init();
151595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  get_num_underruns_ret = 0;
1526f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
1536f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
154838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidnamespace {
155838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
156838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid//  Test fill_time_from_frames
157838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan ReidTEST(IoDevTestSuite, FillTimeFromFramesNormal) {
158838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  struct timespec ts;
159838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
160f880b868b8da1f20594ff271492f7055d4977bb6Dylan Reid  cras_iodev_fill_time_from_frames(12000, 48000, &ts);
161838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(0, ts.tv_sec);
162838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
163838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
164838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
165838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
166838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan ReidTEST(IoDevTestSuite, FillTimeFromFramesLong) {
167838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  struct timespec ts;
168838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
169f880b868b8da1f20594ff271492f7055d4977bb6Dylan Reid  cras_iodev_fill_time_from_frames(120000 - 12000, 48000, &ts);
170838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(2, ts.tv_sec);
171838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
172838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
173838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
174838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
175838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan ReidTEST(IoDevTestSuite, FillTimeFromFramesShort) {
176838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  struct timespec ts;
177838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
178f880b868b8da1f20594ff271492f7055d4977bb6Dylan Reid  cras_iodev_fill_time_from_frames(12000 - 12000, 48000, &ts);
179838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(0, ts.tv_sec);
180838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(0, ts.tv_nsec);
181838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
182838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
183045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Changclass IoDevSetFormatTestSuite : public testing::Test {
184045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  protected:
185045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    virtual void SetUp() {
1862db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid      ResetStubData();
187045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      sample_rates_[0] = 44100;
188045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      sample_rates_[1] = 48000;
189045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      sample_rates_[2] = 0;
190045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
191045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      channel_counts_[0] = 2;
192045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      channel_counts_[1] = 0;
193663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      channel_counts_[2] = 0;
194663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
195a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      pcm_formats_[0] = SND_PCM_FORMAT_S16_LE;
196a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      pcm_formats_[1] = SND_PCM_FORMAT_S32_LE;
197a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      pcm_formats_[2] = static_cast<snd_pcm_format_t>(0);
198a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid
199663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      update_channel_layout_called = 0;
200663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      update_channel_layout_return_val = 0;
201045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
202045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      memset(&iodev_, 0, sizeof(iodev_));
203663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      iodev_.update_channel_layout = update_channel_layout;
204045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      iodev_.supported_rates = sample_rates_;
205045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      iodev_.supported_channel_counts = channel_counts_;
206a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      iodev_.supported_formats = pcm_formats_;
207aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid      iodev_.dsp_context = NULL;
208a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao
209a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao      cras_audio_format_set_channel_layout_called  = 0;
210045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    }
211045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
2125b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang    virtual void TearDown() {
2135b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang      cras_iodev_free_format(&iodev_);
2145b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang    }
2155b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
216045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    struct cras_iodev iodev_;
217045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    size_t sample_rates_[3];
218663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao    size_t channel_counts_[3];
219a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid    snd_pcm_format_t pcm_formats_[3];
220045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang};
221045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
222045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatSecondary) {
223045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
224045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
225045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
226045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
227045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 48000;
228045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
229ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  iodev_.direction = CRAS_STREAM_OUTPUT;
230ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  ResetStubData();
231045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
232045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
233bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
234bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
235bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
236ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  EXPECT_EQ(dsp_context_new_sample_rate, 48000);
23729b418afbe347e21bf01e29c235919ed5d3035dbYunlian Jiang  EXPECT_STREQ(dsp_context_new_purpose, "playback");
238045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
239045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
240a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan ReidTEST_F(IoDevSetFormatTestSuite, SupportedFormat32bit) {
241a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  struct cras_audio_format fmt;
242a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  int rc;
243a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid
244a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  fmt.format = SND_PCM_FORMAT_S32_LE;
245a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  fmt.frame_rate = 48000;
246a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  fmt.num_channels = 2;
247a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  iodev_.direction = CRAS_STREAM_OUTPUT;
248a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  ResetStubData();
249a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
250a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  EXPECT_EQ(0, rc);
251bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S32_LE, iodev_.ext_format->format);
252bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
253bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
254a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  EXPECT_EQ(dsp_context_new_sample_rate, 48000);
255a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  EXPECT_STREQ(dsp_context_new_purpose, "playback");
256a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid}
257a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid
258045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatPrimary) {
259045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
260045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
261045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
262045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
263045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 44100;
264045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
265ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  iodev_.direction = CRAS_STREAM_INPUT;
266ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  ResetStubData();
267045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
268045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
269bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
270bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(44100, iodev_.ext_format->frame_rate);
271bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
272ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  EXPECT_EQ(dsp_context_new_sample_rate, 44100);
27329b418afbe347e21bf01e29c235919ed5d3035dbYunlian Jiang  EXPECT_STREQ(dsp_context_new_purpose, "capture");
274045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
275045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
276045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatDivisor) {
277045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
278045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
279045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
280045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
281045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 96000;
282045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
283045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
284045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
285bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
286bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
287bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
288045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
289045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
29097d26e1687da4f38da88b868b6b827aeea50871aDylan ReidTEST_F(IoDevSetFormatTestSuite, Supported96k) {
29197d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  struct cras_audio_format fmt;
29297d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  int rc;
29397d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
29497d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[0] = 48000;
29597d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[1] = 96000;
29697d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[2] = 0;
29797d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
29897d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
29997d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.frame_rate = 96000;
30097d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.num_channels = 2;
30197d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
30297d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  EXPECT_EQ(0, rc);
303bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
304bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(96000, iodev_.ext_format->frame_rate);
305bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
30697d26e1687da4f38da88b868b6b827aeea50871aDylan Reid}
30797d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
30897d26e1687da4f38da88b868b6b827aeea50871aDylan ReidTEST_F(IoDevSetFormatTestSuite, LimitLowRate) {
30997d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  struct cras_audio_format fmt;
31097d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  int rc;
31197d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
31297d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[0] = 48000;
31397d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[1] = 8000;
31497d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[2] = 0;
31597d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
31697d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
31797d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.frame_rate = 8000;
31897d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.num_channels = 2;
31997d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
32097d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  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);
32497d26e1687da4f38da88b868b6b827aeea50871aDylan Reid}
32597d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
326045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, UnsupportedChannelCount) {
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 = 96000;
332045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 1;
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(48000, iodev_.ext_format->frame_rate);
337bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
338045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
339045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
340045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatFallbackDefault) {
341045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
342045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
343045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
344045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
345045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 96008;
346045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
347045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
348045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
349bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
350bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(44100, iodev_.ext_format->frame_rate);
351bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
352045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
353045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
3542db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan ReidTEST_F(IoDevSetFormatTestSuite, OutputDSPChannleReduction) {
3552db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  struct cras_audio_format fmt;
3562db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  int rc;
3572db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3582db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
3592db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.frame_rate = 48000;
3602db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.num_channels = 2;
3612db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3622db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.direction = CRAS_STREAM_OUTPUT;
3632db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[0] = 1;
3642db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[1] = 0;
3652db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf00);
3662db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_get_pipeline_ret =  0xf01;
3672db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_input_channels_return = 2;
3682db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_output_channels_return = 1;
3692db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
3702db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  EXPECT_EQ(0, rc);
371bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
372bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
373bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
3742db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid}
3752db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3762db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan ReidTEST_F(IoDevSetFormatTestSuite, InputDSPChannleReduction) {
3772db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  struct cras_audio_format fmt;
3782db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  int rc;
3792db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3802db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
3812db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.frame_rate = 48000;
3822db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.num_channels = 2;
3832db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
3842db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.direction = CRAS_STREAM_INPUT;
3852db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[0] = 10;
3862db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[1] = 0;
3872db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf00);
3882db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_get_pipeline_ret =  0xf01;
3892db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_input_channels_return = 10;
3902db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_output_channels_return = 2;
3912db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
3922db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  EXPECT_EQ(0, rc);
393bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
394bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
395bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
3962db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid}
3972db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
398663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu ChaoTEST_F(IoDevSetFormatTestSuite, UpdateChannelLayoutSuccess) {
399663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  struct cras_audio_format fmt;
400663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  int rc;
401663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
402663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.format = SND_PCM_FORMAT_S16_LE;
403663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.frame_rate = 48000;
404663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.num_channels = 6;
405663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
406663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[0] = 6;
407663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[1] = 2;
408663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
409663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  rc = cras_iodev_set_format(&iodev_, &fmt);
410663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  EXPECT_EQ(0, rc);
411bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
412bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
413bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(6, iodev_.ext_format->num_channels);
414663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao}
415663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
416663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu ChaoTEST_F(IoDevSetFormatTestSuite, UpdateChannelLayoutFail) {
417a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  static const int8_t stereo_layout[] =
418a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao      {0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
419663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  struct cras_audio_format fmt;
420a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  int rc, i;
421663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
422663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.format = SND_PCM_FORMAT_S16_LE;
423663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.frame_rate = 48000;
4241609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.num_channels = 2;
425663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
4265fa790469656d3e093799329f814756600762a71Dylan Reid  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf0f);
4275fa790469656d3e093799329f814756600762a71Dylan Reid
428663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  update_channel_layout_return_val = -1;
429663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[0] = 6;
430663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[1] = 2;
431663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
432663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  rc = cras_iodev_set_format(&iodev_, &fmt);
433663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  EXPECT_EQ(0, rc);
434bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
435bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
436bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
437bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, cras_audio_format_set_channel_layout_called);
4385fa790469656d3e093799329f814756600762a71Dylan Reid  EXPECT_EQ(0, dsp_context_free_called);
439a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  for (i = 0; i < CRAS_CH_MAX; i++)
440a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao    EXPECT_EQ(iodev_.format->channel_layout[i], stereo_layout[i]);
441663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao}
442663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
4431609667463605b64a0849f6ae7f26adf698cf5b3Ben ZhangTEST_F(IoDevSetFormatTestSuite, UpdateChannelLayoutFail6ch) {
4441609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  static const int8_t default_6ch_layout[] =
4451609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang      {0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1};
4461609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  struct cras_audio_format fmt;
4471609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  int rc, i;
4481609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4491609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.format = SND_PCM_FORMAT_S16_LE;
4501609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.frame_rate = 48000;
4511609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.num_channels = 6;
4521609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4531609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf0f);
4541609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4551609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  update_channel_layout_return_val = -1;
4561609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  iodev_.supported_channel_counts[0] = 6;
4571609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  iodev_.supported_channel_counts[1] = 2;
4581609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4591609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  rc = cras_iodev_set_format(&iodev_, &fmt);
4601609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(0, rc);
4611609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
4621609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
4631609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(6, iodev_.ext_format->num_channels);
4641609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(2, cras_audio_format_set_channel_layout_called);
4651609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(0, dsp_context_free_called);
4661609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  for (i = 0; i < CRAS_CH_MAX; i++)
4671609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang    EXPECT_EQ(iodev_.format->channel_layout[i], default_6ch_layout[i]);
4681609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang}
4691609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4701c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid// Put buffer tests
4711c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
472cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiangstatic int get_buffer(cras_iodev* iodev, struct cras_audio_area** area,
473cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang               unsigned int* num) {
474cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  size_t sz = sizeof(*audio_area) + sizeof(struct cras_channel_area) * 2;
475cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
476cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area = (cras_audio_area*)calloc(1, sz);
477cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->frames = *num;
478cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->num_channels = 2;
479cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[0].buf = audio_buffer;
480cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  channel_area_set_channel(&audio_area->channels[0], CRAS_CH_FL);
481cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[0].step_bytes = 4;
482cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[1].buf = audio_buffer + 2;
483cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  channel_area_set_channel(&audio_area->channels[1], CRAS_CH_FR);
484cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[1].step_bytes = 4;
485cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
486cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  *area = audio_area;
487cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  return 0;
488cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang}
489cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
4901c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic int put_buffer(struct cras_iodev *iodev, unsigned int nframes)
4911c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid{
4921c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  put_buffer_nframes = nframes;
493cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  if (audio_area) {
494cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    free(audio_area);
495cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    audio_area = NULL;
496cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  }
4971c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  return 0;
4981c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
4991c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
500016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int no_stream(struct cras_iodev *odev, int enable)
501016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang{
502016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_called++;
503016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_enable = enable;
504016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  // Use default no stream playback to test default behavior.
505016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  return cras_iodev_default_no_stream_playback(odev, enable);
506016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang}
507016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
508016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int output_should_wake(const struct cras_iodev *odev)
509016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang{
510016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  return output_should_wake_ret;
511016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang}
512016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
51337048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic int pre_dsp_hook(const uint8_t *frames, unsigned int nframes,
514081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen			const struct cras_audio_format *fmt, void *cb_data)
51537048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid{
51637048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_called++;
51737048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_frames = frames;
518081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  pre_dsp_hook_cb_data = cb_data;
51937048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  return 0;
52037048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid}
52137048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid
52237048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic int post_dsp_hook(const uint8_t *frames, unsigned int nframes,
523081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen			 const struct cras_audio_format *fmt, void *cb_data)
52437048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid{
52537048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_called++;
52637048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_frames = frames;
527081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  post_dsp_hook_cb_data = cb_data;
52837048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  return 0;
52937048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid}
53037048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid
5311c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, SystemMuted) {
5321c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
5331c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
5341c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
5351c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
5361c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5371c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
5381c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
5391c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_system_get_mute_return = 1;
5401c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5411c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
5421c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
5431c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
5441c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
5451c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
5461c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5471c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 20);
5481c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
5491c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(20, cras_mix_mute_count);
5501c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(20, put_buffer_nframes);
5511c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(20, rate_estimator_add_frames_num_frames);
5521c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
5531c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5541c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, NoDSP) {
5551c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
5561c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
5571c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
5581c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
5591c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5601c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
5611c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
5621c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5631c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
5641c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
5651c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
5661c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
5671c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
5681c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5691c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 22);
5701c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
5711c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
5721c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(22, put_buffer_nframes);
5731c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(22, rate_estimator_add_frames_num_frames);
5741c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
5751c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5761c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, DSP) {
5771c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
5781c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
5791c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
5801c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
5811c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5821c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
5831c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
5841c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.dsp_context = reinterpret_cast<cras_dsp_context*>(0x15);
5851c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_dsp_get_pipeline_ret = 0x25;
5861c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5871c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
5881c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
5891c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
5901c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
5911c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
592081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  cras_iodev_register_pre_dsp_hook(&iodev, pre_dsp_hook, (void *)0x1234);
593081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  cras_iodev_register_post_dsp_hook(&iodev, post_dsp_hook, (void *)0x5678);
5941c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5951c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 32);
5961c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
5971c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
59837048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  EXPECT_EQ(1, pre_dsp_hook_called);
59937048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  EXPECT_EQ(frames, pre_dsp_hook_frames);
600081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  EXPECT_EQ((void *)0x1234, pre_dsp_hook_cb_data);
60137048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  EXPECT_EQ(1, post_dsp_hook_called);
602081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  EXPECT_EQ((void *)0x5678, post_dsp_hook_cb_data);
6031c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(32, put_buffer_nframes);
6041c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(32, rate_estimator_add_frames_num_frames);
6051c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(32, cras_dsp_pipeline_apply_sample_count);
6061c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(cras_dsp_get_pipeline_called, cras_dsp_put_pipeline_called);
6071c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
6081c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
6091c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, SoftVol) {
6101c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
6111c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
6121c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
6131c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
6141c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
6151c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
6161c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
6171c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.software_volume_needed = 1;
6181c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
6191c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
6201c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
6211c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
6221c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
6231c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
6241c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
6251c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_system_get_volume_return = 13;
6261c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  softvol_scalers[13] = 0.435;
6271c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
6281c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 53);
6291c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
6301c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
6311c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(53, put_buffer_nframes);
6321c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(53, rate_estimator_add_frames_num_frames);
6331c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(softvol_scalers[13], cras_scale_buffer_scaler);
634249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, cras_scale_buffer_fmt);
635249e72919eb928e107d251b262c305a8fe531641Dylan Reid}
636249e72919eb928e107d251b262c305a8fe531641Dylan Reid
637249e72919eb928e107d251b262c305a8fe531641Dylan ReidTEST(IoDevPutOutputBuffer, Scale32Bit) {
638249e72919eb928e107d251b262c305a8fe531641Dylan Reid  struct cras_audio_format fmt;
639249e72919eb928e107d251b262c305a8fe531641Dylan Reid  struct cras_iodev iodev;
640249e72919eb928e107d251b262c305a8fe531641Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
641249e72919eb928e107d251b262c305a8fe531641Dylan Reid  int rc;
642249e72919eb928e107d251b262c305a8fe531641Dylan Reid
643249e72919eb928e107d251b262c305a8fe531641Dylan Reid  ResetStubData();
644249e72919eb928e107d251b262c305a8fe531641Dylan Reid  memset(&iodev, 0, sizeof(iodev));
645249e72919eb928e107d251b262c305a8fe531641Dylan Reid  iodev.software_volume_needed = 1;
646249e72919eb928e107d251b262c305a8fe531641Dylan Reid
647249e72919eb928e107d251b262c305a8fe531641Dylan Reid  cras_system_get_volume_return = 13;
648249e72919eb928e107d251b262c305a8fe531641Dylan Reid  softvol_scalers[13] = 0.435;
649249e72919eb928e107d251b262c305a8fe531641Dylan Reid
650249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.format = SND_PCM_FORMAT_S32_LE;
651249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.frame_rate = 48000;
652249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.num_channels = 2;
653249e72919eb928e107d251b262c305a8fe531641Dylan Reid  iodev.format = &fmt;
654249e72919eb928e107d251b262c305a8fe531641Dylan Reid  iodev.put_buffer = put_buffer;
655249e72919eb928e107d251b262c305a8fe531641Dylan Reid
656249e72919eb928e107d251b262c305a8fe531641Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 53);
657249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(0, rc);
658249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
659249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(53, put_buffer_nframes);
660249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(53, rate_estimator_add_frames_num_frames);
661249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(SND_PCM_FORMAT_S32_LE, cras_scale_buffer_fmt);
6621c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
6631c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
664cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao// frames queued/avail tests
665cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
666cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chaostatic unsigned fr_queued = 0;
667cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
668fa4cd9766aec6eae544b1078ed835687c4e74617John Muirstatic int frames_queued(const struct cras_iodev *iodev,
669fa4cd9766aec6eae544b1078ed835687c4e74617John Muir                         struct timespec *tstamp)
670cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao{
671fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
672cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  return fr_queued;
673cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao}
674cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
675cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu ChaoTEST(IoDevQueuedBuffer, ZeroMinBufferLevel) {
676cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  struct cras_iodev iodev;
677fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  struct timespec tstamp;
678cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  int rc;
679cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
680cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  ResetStubData();
681cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  memset(&iodev, 0, sizeof(iodev));
682cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.direction = CRAS_STREAM_OUTPUT;
683cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.frames_queued = frames_queued;
684cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.min_buffer_level = 0;
685cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.buffer_size = 200;
686cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  fr_queued = 50;
687cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
688fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  rc = cras_iodev_frames_queued(&iodev, &tstamp);
689cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(50, rc);
690cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_buffer_avail(&iodev, rc);
691cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(150, rc);
692cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao}
693cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
694cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu ChaoTEST(IoDevQueuedBuffer, NonZeroMinBufferLevel) {
695cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  struct cras_iodev iodev;
696fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  struct timespec hw_tstamp;
697cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  int rc;
698cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
699cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  ResetStubData();
700cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  memset(&iodev, 0, sizeof(iodev));
701cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.direction = CRAS_STREAM_OUTPUT;
702cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.frames_queued = frames_queued;
703cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.min_buffer_level = 100;
704cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.buffer_size = 200;
705cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  fr_queued = 180;
706cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
707fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  rc = cras_iodev_frames_queued(&iodev, &hw_tstamp);
708cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(80, rc);
709cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_buffer_avail(&iodev, rc);
710cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(20, rc);
711cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
712cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  /* When fr_queued < min_buffer_level*/
713cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  fr_queued = 80;
714fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  rc = cras_iodev_frames_queued(&iodev, &hw_tstamp);
715cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(0, rc);
716cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_buffer_avail(&iodev, rc);
717cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(100, rc);
718cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao}
719cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
720bb28140f38fdf6627ec26696c943dfa4f9188450Hsin-Yu Chaostatic void update_active_node(struct cras_iodev *iodev,
7210def72b968591065f56e88d67e5c83234184811bHsin-Yu Chao                               unsigned node_idx,
7220def72b968591065f56e88d67e5c83234184811bHsin-Yu Chao                               unsigned dev_enabled)
7236f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang{
7246f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
7256f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
726b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic void dev_set_volume(struct cras_iodev *iodev)
727b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
728b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
729b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
730b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic void dev_set_capture_gain(struct cras_iodev *iodev)
731b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
732b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
733b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
734e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu ChaoTEST(IoNodePlug, PlugUnplugNode) {
7356f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  struct cras_iodev iodev;
7363b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  struct cras_ionode ionode, ionode2;
7376f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
738b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&iodev, 0, sizeof(iodev));
739b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&ionode, 0, sizeof(ionode));
7403b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  memset(&ionode2, 0, sizeof(ionode2));
7416f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  iodev.direction = CRAS_STREAM_INPUT;
7426f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  iodev.update_active_node = update_active_node;
7433b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  ionode.dev = &iodev;
7443b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_add_node(&iodev, &ionode);
7453b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  ionode2.dev = &iodev;
7463b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_add_node(&iodev, &ionode2);
7473b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_set_active_node(&iodev, &ionode);
7486f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  ResetStubData();
749786f9d1938966af8e1eb9f60559a3535b5c71ff8Chih-Chung Chang  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_PLUGGED, 1);
750e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  EXPECT_EQ(0, cras_iodev_list_disable_dev_called);
751e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_PLUGGED, 0);
752e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
7533b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao
7543b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  /* Unplug non-active node shouldn't disable iodev. */
7553b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_set_node_attr(&ionode2, IONODE_ATTR_PLUGGED, 1);
7563b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
7573b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_set_node_attr(&ionode2, IONODE_ATTR_PLUGGED, 0);
7583b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
7596f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
7606f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
761b2ad33424e21106930eb23db093746dc30926f27Chih-Chung ChangTEST(IoDev, AddRemoveNode) {
762b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  struct cras_iodev iodev;
763b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  struct cras_ionode ionode;
764b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang
765b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&iodev, 0, sizeof(iodev));
766b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&ionode, 0, sizeof(ionode));
767b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  ResetStubData();
768b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  EXPECT_EQ(0, notify_nodes_changed_called);
769b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  cras_iodev_add_node(&iodev, &ionode);
770b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  EXPECT_EQ(1, notify_nodes_changed_called);
771b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  cras_iodev_rm_node(&iodev, &ionode);
772b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  EXPECT_EQ(2, notify_nodes_changed_called);
773b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang}
774b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang
775c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung ChangTEST(IoDev, SetActiveNode) {
776c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  struct cras_iodev iodev;
777c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  struct cras_ionode ionode;
778c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang
779c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  memset(&iodev, 0, sizeof(iodev));
780c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  memset(&ionode, 0, sizeof(ionode));
781c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  ResetStubData();
782c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  EXPECT_EQ(0, notify_active_node_changed_called);
783c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  cras_iodev_set_active_node(&iodev, &ionode);
784c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  EXPECT_EQ(1, notify_active_node_changed_called);
785c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang}
786c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang
787b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan ReidTEST(IoDev, SetNodeVolume) {
788b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  struct cras_iodev iodev;
789b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  struct cras_ionode ionode;
790b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
791b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  memset(&iodev, 0, sizeof(iodev));
792b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  memset(&ionode, 0, sizeof(ionode));
793b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  iodev.set_volume = dev_set_volume;
794b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  iodev.set_capture_gain = dev_set_capture_gain;
795b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  ionode.dev = &iodev;
796b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  ResetStubData();
797b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_VOLUME, 10);
798b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  EXPECT_EQ(1, notify_node_volume_called);
799b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  iodev.direction = CRAS_STREAM_INPUT;
800b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_CAPTURE_GAIN, 10);
801b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  EXPECT_EQ(1, notify_node_capture_gain_called);
802b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
803b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
8043285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi ChiangTEST(IoDev, SetNodeSwapLeftRight) {
8053285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  struct cras_iodev iodev;
8063285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  struct cras_ionode ionode;
8073285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang
8083285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
8093285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
8103285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  iodev.set_swap_mode_for_node = set_swap_mode_for_node;
8113285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  ionode.dev = &iodev;
8123285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  ResetStubData();
8133285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_SWAP_LEFT_RIGHT, 1);
8143285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(1, set_swap_mode_for_node_called);
8153285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(1, set_swap_mode_for_node_enable);
8163285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(1, ionode.left_right_swapped);
8173ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  EXPECT_EQ(1, notify_node_left_right_swapped_called);
8183285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_SWAP_LEFT_RIGHT, 0);
8193285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(2, set_swap_mode_for_node_called);
8203285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(0, set_swap_mode_for_node_enable);
8213285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(0, ionode.left_right_swapped);
8223ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  EXPECT_EQ(2, notify_node_left_right_swapped_called);
8233285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang}
8243285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang
8255342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8265342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang// Test software volume changes for default output.
8275342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi ChiangTEST(IoDev, SoftwareVolume) {
8285342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  struct cras_iodev iodev;
8295342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  struct cras_ionode ionode;
8305342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8315342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
8325342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
8335342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  ResetStubData();
8345342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8355342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.nodes = &ionode;
8365342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node = &ionode;
8375342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node->dev = &iodev;
8385342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8395342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node->volume = 100;
8405342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.software_volume_needed = 0;
8415342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8425342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8435342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  softvol_scalers[80] = 0.5;
8445342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  softvol_scalers[70] = 0.3;
8455342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8465342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // Check that system volume changes software volume if needed.
8475342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  cras_system_get_volume_return = 80;
8485342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // system_volume - 100 + node_volume = 80 - 100 + 100 = 80
8495342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  EXPECT_FLOAT_EQ(0.5, cras_iodev_get_software_volume_scaler(&iodev));
8505342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
8515342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // Check that node volume changes software volume if needed.
8525342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node->volume = 90;
8535342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // system_volume - 100 + node_volume = 80 - 100 + 90 = 70
8545342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  EXPECT_FLOAT_EQ(0.3, cras_iodev_get_software_volume_scaler(&iodev));
8555342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang}
8565342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
857034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang// Test software gain scaler.
858034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi ChiangTEST(IoDev, SoftwareGain) {
859034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  struct cras_iodev iodev;
860034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  struct cras_ionode ionode;
861034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
862034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
863034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
864034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ResetStubData();
865034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
866034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  iodev.nodes = &ionode;
867034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  iodev.active_node = &ionode;
868034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  iodev.active_node->dev = &iodev;
869034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
870034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.capture_gain= 400;
871034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.software_volume_needed = 1;
872034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.max_software_gain = 3000;
873034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
874034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // Check that system volume changes software volume if needed.
875034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  cras_system_get_capture_gain_ret_value = 2000;
876034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // system_gain + node_gain = 2000 + 400  = 2400
877034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // 2400 dBm is 15.848931
878034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(15.848931, cras_iodev_get_software_gain_scaler(&iodev));
879034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(3000, cras_iodev_maximum_software_gain(&iodev));
880034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
881034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // Software gain scaler should be 1.0 if software gain is not needed.
882034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.software_volume_needed = 0;
883034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(1.0, cras_iodev_get_software_gain_scaler(&iodev));
884034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(0, cras_iodev_maximum_software_gain(&iodev));
885034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang}
886034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
887b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// This get_buffer implementation set returned frames larger than requested
888b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// frames.
889b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiangstatic int bad_get_buffer(struct cras_iodev *iodev,
890b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang                          struct cras_audio_area **area,
891b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang                          unsigned *frames)
892b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang{
893b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  *frames = *frames + 1;
894b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  return 0;
895b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang}
896b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
897b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// Check that if get_buffer implementation returns invalid frames,
898b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// cras_iodev_get_output_buffer and cras_iodev_get_input_buffer can return
899b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// error.
900b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi ChiangTEST(IoDev, GetBufferInvalidFrames) {
901b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  struct cras_iodev iodev;
902b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  struct cras_audio_area **area = NULL;
903b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  unsigned int frames = 512;
904b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  struct cras_audio_format fmt;
905b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
906b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  // Format is used in cras_iodev_get_input_buffer;
907b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
908b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  fmt.frame_rate = 48000;
909b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  fmt.num_channels = 2;
910b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
911b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
912b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
913b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  ResetStubData();
914b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
915b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  iodev.format = &fmt;
916b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  iodev.get_buffer = bad_get_buffer;
917b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
918b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  EXPECT_EQ(-EINVAL, cras_iodev_get_output_buffer(&iodev, area, &frames));
919b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  EXPECT_EQ(-EINVAL, cras_iodev_get_input_buffer(&iodev, area, &frames));
920b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang}
921b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
92224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chaostatic int open_dev(struct cras_iodev *iodev) {
92324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev->buffer_size = iodev_buffer_size;
92424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  return 0;
92524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao}
92624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
92750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenOutputDeviceNoStart) {
92850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  struct cras_iodev iodev;
92950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
93050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
93150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.open_dev = open_dev;
93250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
93350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  ResetStubData();
93450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
93550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
93650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
93750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev_buffer_size = 1024;
93850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  cras_iodev_open(&iodev, 240);
93950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
94050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
94150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
94250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is no stream run when there is no start ops.
94350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
94450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
94550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
94650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiangint fake_start(const struct cras_iodev *iodev) {
94750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  return 0;
94850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
94950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
95050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenOutputDeviceWithStart) {
95150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  struct cras_iodev iodev;
95250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
95350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
95450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.open_dev = open_dev;
95550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
95650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  ResetStubData();
95750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
95850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
95950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.start = fake_start;
96050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
96150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev_buffer_size = 1024;
96250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  cras_iodev_open(&iodev, 240);
96350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
96450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
96550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
96650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is no stream run when there is start ops.
96750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_OPEN, iodev.state);
96850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
96950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
97050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenInputDeviceNoStart) {
97150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  struct cras_iodev iodev;
97250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
97350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
97450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.open_dev = open_dev;
97550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
97650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  ResetStubData();
97750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
97850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
97950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
98050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev_buffer_size = 1024;
98150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  cras_iodev_open(&iodev, 240);
98250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
98350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
98450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
98550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is normal run when there is start ops.
98650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
98750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
98850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
98950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenInputDeviceWithStart) {
990016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  struct cras_iodev iodev;
991016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
992016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
993016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev.open_dev = open_dev;
99450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
995016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  ResetStubData();
996016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
99750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
99850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.start = fake_start;
999016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1000016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev_buffer_size = 1024;
1001016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  cras_iodev_open(&iodev, 240);
1002016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
1003016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
100450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
100550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is normal run even if there is start ops.
100650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
1007016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang}
1008016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1009dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstatic int simple_no_stream(struct cras_iodev *dev, int enable)
1010dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang{
1011dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  simple_no_stream_enable = enable;
1012dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  simple_no_stream_called++;
1013dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  return 0;
1014dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
1015dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
101624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu ChaoTEST(IoDev, AddRmStream) {
101724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  struct cras_iodev iodev;
101824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  struct cras_rstream rstream1, rstream2;
101924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  struct dev_stream stream1, stream2;
102024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
102124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  memset(&iodev, 0, sizeof(iodev));
102224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev.open_dev = open_dev;
1023dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.no_stream = simple_no_stream;
1024dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
102524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  rstream1.cb_threshold = 800;
102624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  stream1.stream = &rstream1;
102724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  rstream2.cb_threshold = 400;
102824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  stream2.stream = &rstream2;
102924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  ResetStubData();
103024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
103124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev_buffer_size = 1024;
103224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_open(&iodev, rstream1.cb_threshold);
103324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(0, iodev.max_cb_level);
103424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(512, iodev.min_cb_level);
103524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
103624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  /* min_cb_level should not exceed half the buffer size. */
103724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_add_stream(&iodev, &stream1);
103824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(800, iodev.max_cb_level);
103924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(512, iodev.min_cb_level);
104024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
104124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_add_stream(&iodev, &stream2);
104224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(800, iodev.max_cb_level);
104324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.min_cb_level);
104424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
104524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_rm_stream(&iodev, &rstream1);
104624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.max_cb_level);
104724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.min_cb_level);
1048dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, simple_no_stream_called);
104924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
105024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  /* When all streams are removed, keep the last min_cb_level for draining. */
105124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_rm_stream(&iodev, &rstream2);
105224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(0, iodev.max_cb_level);
105324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.min_cb_level);
105485502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang}
105585502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang
1056cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi ChiangTEST(IoDev, FillZeros) {
1057cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  struct cras_iodev iodev;
1058cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  struct cras_audio_format fmt;
1059cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  unsigned int frames = 50;
1060cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  int16_t *zeros;
1061cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  int rc;
1062cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1063cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  ResetStubData();
1064cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1065cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1066cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
1067cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  fmt.frame_rate = 48000;
1068cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  fmt.num_channels = 2;
1069cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.ext_format = &fmt;
1070cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.get_buffer = get_buffer;
1071cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.put_buffer = put_buffer;
1072cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1073cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
1074cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  rc = cras_iodev_fill_odev_zeros(&iodev, frames);
1075cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(-EINVAL, rc);
1076cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1077cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
1078cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  rc = cras_iodev_fill_odev_zeros(&iodev, frames);
1079cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1080cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(0, rc);
1081cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(frames, put_buffer_nframes);
1082cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  zeros = (int16_t *)calloc(frames * 2, sizeof(*zeros));
1083cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  rc = memcmp(audio_buffer, zeros, frames * 2 * 2);
1084cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  free(zeros);
1085cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(0, rc);
1086cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang}
1087cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1088dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi ChiangTEST(IoDev, DefaultNoStreamPlaybackRunning) {
10891bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  struct cras_iodev iodev;
10901bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  struct cras_audio_format fmt;
10911bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  unsigned int hw_level = 50;
10921bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  unsigned int min_cb_level = 240;
10931bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  unsigned int zeros_to_fill;
10941bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  int16_t *zeros;
10951bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  int rc;
10961bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
10971bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
10981bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
10991bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
11001bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fmt.frame_rate = 48000;
11011bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fmt.num_channels = 2;
11021bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.ext_format = &fmt;
11031bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.min_cb_level = min_cb_level;
11041bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.get_buffer = get_buffer;
11051bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.put_buffer = put_buffer;
11061bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.frames_queued = frames_queued;
11071bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.min_buffer_level = 0;
11081bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
11091bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.buffer_size = BUFFER_SIZE;
1110016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev.no_stream = no_stream;
1111016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1112016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  ResetStubData();
11131bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
11141bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // Device is running. hw_level is less than target.
11151bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // Need to fill to callback level * 2;
111650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
11171bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fr_queued = hw_level;
11181bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  zeros_to_fill = min_cb_level * 2 - hw_level;
11191bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
1120dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_default_no_stream_playback(&iodev, 1);
11211bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
11221bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(0, rc);
112350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
11241bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(zeros_to_fill, put_buffer_nframes);
11251bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  zeros = (int16_t *)calloc(zeros_to_fill * 2, sizeof(*zeros));
11261bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(0, memcmp(audio_buffer, zeros, zeros_to_fill * 2 * 2));
11271bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  free(zeros);
11281bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
11291bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  ResetStubData();
11301bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
11311bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // Device is running. hw_level is not less than target.
11321bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // No need to fill zeros.
113350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
11341bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  hw_level = min_cb_level * 2;
11351bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fr_queued = hw_level;
11361bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  zeros_to_fill = 0;
11371bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
1138dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_default_no_stream_playback(&iodev, 1);
11391bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(0, rc);
114050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
11411bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(zeros_to_fill, put_buffer_nframes);
1142dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
1143dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1144dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi ChiangTEST(IoDev, PrepareOutputBeforeWriteSamples) {
1145dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct cras_iodev iodev;
1146dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct cras_audio_format fmt;
1147dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  unsigned int min_cb_level = 240;
1148dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  int rc;
1149dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct cras_rstream rstream1;
1150dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct dev_stream stream1;
1151dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct cras_iodev_info info;
1152016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1153016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  ResetStubData();
1154016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1155dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rstream1.cb_threshold = min_cb_level;
1156dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  stream1.stream = &rstream1;
1157dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1158dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1159dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1160dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
1161dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  fmt.frame_rate = 48000;
1162dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  fmt.num_channels = 2;
1163dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.ext_format = &fmt;
1164dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.min_cb_level = min_cb_level;
1165dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.get_buffer = get_buffer;
1166dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.put_buffer = put_buffer;
1167dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.frames_queued = frames_queued;
1168dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.min_buffer_level = 0;
1169dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
1170dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.buffer_size = BUFFER_SIZE;
1171dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.no_stream = no_stream;
1172dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.open_dev = open_dev;
1173dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.start = fake_start;
1174dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.info = info;
1175dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev_buffer_size = BUFFER_SIZE;
1176dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1177dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Open device.
1178dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  cras_iodev_open(&iodev, rstream1.cb_threshold);
1179dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1180dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Add one stream to device.
1181dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  cras_iodev_add_stream(&iodev, &stream1);
1182dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1183dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Case 1: Assume device is not started yet.
1184dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
1185dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Assume sample is not ready yet.
1186dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 0;
1187dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1188dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1189dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1190dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, rc);
1191dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should remain in open state.
1192dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_OPEN, iodev.state);
1193dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, no_stream_called);
1194dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1195dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Assume now sample is ready.
1196dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 100;
1197dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1198dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1199dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1200dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, rc);
1201dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should enter normal run state.
1202dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
1203dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, no_stream_called);
1204dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Need to fill 1 callback level of zeros;
1205dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(min_cb_level, put_buffer_nframes);
1206dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1207dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  ResetStubData();
1208dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1209dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Case 2: Assume device is started and is in no stream state.
121050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
1211dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Sample is not ready yet.
1212dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 0;
1213dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1214dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1215dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1216016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1217dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should remain in no_stream state.
1218dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
1219dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device in no_stream state should call no_stream ops once.
1220016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(1, no_stream_called);
1221dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(1, no_stream_enable);
1222dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1223dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Assume now sample is ready.
1224dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 100;
1225dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1226dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1227dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1228dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, rc);
1229dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should enter normal run state.
1230dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
1231dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should call no_stream ops with enable=0 to leave no stream state.
1232dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(2, no_stream_called);
1233016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, no_stream_enable);
1234dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1235dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  ResetStubData();
1236dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1237dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Case 3: Assume device is started and is in normal run state.
1238dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
1239dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1240dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1241dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1242dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, rc);
1243dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should remain in normal run state.
124450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
1245dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device in no_stream state should call no_stream ops once.
1246dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, no_stream_called);
1247dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1248dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  ResetStubData();
12491bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang}
12501bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
1251103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi ChiangTEST(IoDev, OutputDeviceShouldWake) {
1252103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  struct cras_iodev iodev;
1253103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  int rc;
1254103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1255103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1256103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1257103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  ResetStubData();
1258103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1259103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is not running. No need to wake for this device.
126050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
1261103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1262103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1263103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1264103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. Need to wake for this device.
126550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
1266103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1267103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(1, rc);
1268103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1269016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  // Device is running. Device has output_should_wake ops.
1270016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev.output_should_wake = output_should_wake;
1271016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  output_should_wake_ret = 0;
1272016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1273016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1274016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1275016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  // Device is running. Device has output_should_wake ops.
1276016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  output_should_wake_ret = 1;
1277016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1278016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(1, rc);
1279016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1280103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Ignore input device.
1281103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
1282103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1283103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1284103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang}
1285103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1286103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi ChiangTEST(IoDev, FramesToPlayInSleep) {
1287103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  struct cras_iodev iodev;
1288103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  unsigned int min_cb_level = 240, hw_level;
1289103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  unsigned int got_hw_level, got_frames;
1290fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  struct timespec hw_tstamp;
1291103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1292103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1293103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.frames_queued = frames_queued;
1294103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.min_buffer_level = 0;
1295103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
1296103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.buffer_size = BUFFER_SIZE;
1297103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.min_cb_level = min_cb_level;
1298103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1299103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  ResetStubData();
1300103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1301103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. There is at least one stream for this device.
1302103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // hw_level is greater than min_cb_level.
130350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
1304103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  hw_level = min_cb_level + 50;
1305103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  fr_queued = hw_level;
1306103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.streams = reinterpret_cast<struct dev_stream *>(0x1);
1307103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1308fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  got_frames = cras_iodev_frames_to_play_in_sleep(
1309fa4cd9766aec6eae544b1078ed835687c4e74617John Muir                   &iodev, &got_hw_level, &hw_tstamp);
1310103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_hw_level);
1311103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_frames);
1312103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1313103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. There is no stream for this device.
1314103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // hw_level is greater than min_cb_level.
1315103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.streams = NULL;
1316103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1317fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  got_frames = cras_iodev_frames_to_play_in_sleep(
1318fa4cd9766aec6eae544b1078ed835687c4e74617John Muir                   &iodev, &got_hw_level, &hw_tstamp);
1319103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_hw_level);
1320103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level - min_cb_level, got_frames);
1321103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1322103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. There is no stream for this device.
1323103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // hw_level is less than min_cb_level.
1324103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.streams = NULL;
1325103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  hw_level = min_cb_level - 50;
1326103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  fr_queued = hw_level;
1327103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1328fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  got_frames = cras_iodev_frames_to_play_in_sleep(
1329fa4cd9766aec6eae544b1078ed835687c4e74617John Muir                   &iodev, &got_hw_level, &hw_tstamp);
1330103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_hw_level);
1331103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(0, got_frames);
1332103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang}
1333103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1334595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiangstatic unsigned int get_num_underruns(const struct cras_iodev *iodev) {
1335595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  return get_num_underruns_ret;
1336595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang}
1337595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang
1338595b415568beb0048c31e3111c5c935530be1032Cheng-Yi ChiangTEST(IoDev, GetNumUnderruns) {
1339595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  struct cras_iodev iodev;
1340595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1341595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang
1342595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  EXPECT_EQ(0, cras_iodev_get_num_underruns(&iodev));
1343595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang
1344595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  iodev.get_num_underruns = get_num_underruns;
1345595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  get_num_underruns_ret = 10;
1346595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  EXPECT_EQ(10, cras_iodev_get_num_underruns(&iodev));
1347595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang}
1348595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang
1349838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidextern "C" {
1350838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1351838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid//  From libpthread.
1352838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidint pthread_create(pthread_t *thread, const pthread_attr_t *attr,
1353838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid                   void *(*start_routine)(void*), void *arg) {
1354838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  return 0;
1355838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
1356838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1357838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidint pthread_join(pthread_t thread, void **value_ptr) {
1358838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  return 0;
1359838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
1360838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1361f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao// From audio_thread
1362f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chaostruct cras_fmt_conv *audio_thread_get_global_remix_converter()
1363f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao{
1364f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao  return NULL;
1365f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao}
1366f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao
1367f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao// Fromt fmt_conv
1368f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chaovoid cras_channel_remix_convert(struct cras_fmt_conv *conv,
1369f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao    uint8_t *in_buf,
1370f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao    size_t frames)
1371f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao{
1372f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao}
1373f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao
1374fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid// From buffer_share
1375fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidstruct buffer_share *buffer_share_create(unsigned int buf_sz) {
1376fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return NULL;
1377fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1378fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1379fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidvoid buffer_share_destroy(struct buffer_share *mix)
1380fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid{
1381fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1382fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1383fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidint buffer_share_offset_update(struct buffer_share *mix, unsigned int id,
1384fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid                               unsigned int frames) {
1385fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1386fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1387fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1388fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidunsigned int buffer_share_get_new_write_point(struct buffer_share *mix) {
1389fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1390fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1391fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1392fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidint buffer_share_add_id(struct buffer_share *mix, unsigned int id) {
1393fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1394fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1395fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1396fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidint buffer_share_rm_id(struct buffer_share *mix, unsigned int id) {
1397fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1398fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1399fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1400fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidunsigned int buffer_share_id_offset(const struct buffer_share *mix,
1401fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid                                    unsigned int id)
1402fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid{
1403fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1404fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1405fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1406386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid// From cras_system_state.
140757852ea82d5f4c4491f4cfe9faafc5cbddfc4979Cheng-Yi Chiangvoid cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction) {
1408386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid}
1409386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid
141057852ea82d5f4c4491f4cfe9faafc5cbddfc4979Cheng-Yi Chiangvoid cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction) {
1411386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid}
1412386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid
14135b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang// From cras_dsp
1414aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidstruct cras_dsp_context *cras_dsp_context_new(int sample_rate,
14155b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang                                              const char *purpose)
14165b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang{
1417ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_sample_rate = sample_rate;
1418ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_purpose = purpose;
14192db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  return cras_dsp_context_new_return;
14205b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang}
14215b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
14225b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Changvoid cras_dsp_context_free(struct cras_dsp_context *ctx)
14235b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang{
14245fa790469656d3e093799329f814756600762a71Dylan Reid  dsp_context_free_called++;
14255b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang}
14265b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
14275b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Changvoid cras_dsp_load_pipeline(struct cras_dsp_context *ctx)
14285b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang{
14295b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang}
14305b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
14314f86aad321250a527075476dac94241c24817521Cheng-Yi Chiangvoid cras_dsp_set_variable_string(struct cras_dsp_context *ctx, const char *key,
14324f86aad321250a527075476dac94241c24817521Cheng-Yi Chiang                                  const char *value)
14337057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang{
14347057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang}
14357057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang
1436d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstruct pipeline *cras_dsp_get_pipeline(struct cras_dsp_context *ctx)
1437d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1438d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_get_pipeline_called++;
1439d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return reinterpret_cast<struct pipeline *>(cras_dsp_get_pipeline_ret);
1440d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1441d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1442d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidvoid cras_dsp_put_pipeline(struct cras_dsp_context *ctx)
1443d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1444d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_put_pipeline_called++;
1445d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1446d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1447d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidfloat *cras_dsp_pipeline_get_source_buffer(struct pipeline *pipeline,
1448d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid					   int index)
1449d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1450d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_source_buffer_called++;
1451d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return cras_dsp_pipeline_source_buffer[index];
1452d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1453d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1454d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidfloat *cras_dsp_pipeline_get_sink_buffer(struct pipeline *pipeline, int index)
1455d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1456d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_sink_buffer_called++;
1457d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return cras_dsp_pipeline_sink_buffer[index];
1458d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1459d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1460d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidint cras_dsp_pipeline_get_delay(struct pipeline *pipeline)
1461d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1462d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_delay_called++;
1463d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return 0;
1464d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1465d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1466aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidvoid cras_dsp_pipeline_apply(struct pipeline *pipeline,
1467d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid			     uint8_t *buf, unsigned int frames)
1468d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1469d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_called++;
1470d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_sample_count = frames;
1471d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1472d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1473d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidvoid cras_dsp_pipeline_add_statistic(struct pipeline *pipeline,
1474d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                                     const struct timespec *time_delta,
1475d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                                     int samples)
1476d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
1477d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1478d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1479aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidunsigned int cras_dsp_num_output_channels(const struct cras_dsp_context *ctx)
1480aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid{
14812db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid	return cras_dsp_num_output_channels_return;
1482aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid}
1483aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid
1484aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidunsigned int cras_dsp_num_input_channels(const struct cras_dsp_context *ctx)
1485aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid{
14862db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid	return cras_dsp_num_input_channels_return;
1487aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid}
1488aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid
1489d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid// From audio thread
1490d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reidint audio_thread_post_message(struct audio_thread *thread,
1491d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid                              struct audio_thread_msg *msg) {
1492d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid  return 0;
1493d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid}
1494d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid
1495ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changvoid cras_iodev_list_select_node(enum CRAS_STREAM_DIRECTION direction,
1496ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang                                 cras_node_id_t node_id)
1497f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Chang{
1498ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_called++;
1499ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_direction = direction;
1500ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_id = node_id;
1501f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Chang}
1502f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Chang
1503ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changint cras_iodev_list_node_selected(struct cras_ionode *node)
15046f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang{
1505ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  return node == node_selected;
15066f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
15076f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
1508e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chaovoid cras_iodev_list_disable_dev(struct cras_iodev *dev)
1509e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao{
1510e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  cras_iodev_list_disable_dev_called++;
1511e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao}
1512e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao
1513b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Changvoid cras_iodev_list_notify_nodes_changed()
1514b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang{
1515b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  notify_nodes_changed_called++;
1516b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang}
1517b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang
1518dc115f02e335a6d197b6ef4bf0516e4866a7fc6eDylan Reidvoid cras_iodev_list_notify_active_node_changed(
1519dc115f02e335a6d197b6ef4bf0516e4866a7fc6eDylan Reid				enum CRAS_STREAM_DIRECTION direction)
1520c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang{
1521c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  notify_active_node_changed_called++;
1522c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang}
1523c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang
1524b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidvoid cras_iodev_list_notify_node_volume(struct cras_ionode *node)
1525b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
1526b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid	notify_node_volume_called++;
1527b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
1528b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
1529b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidvoid cras_iodev_list_notify_node_capture_gain(struct cras_ionode *node)
1530b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
1531b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid	notify_node_capture_gain_called++;
1532b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
1533b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
15343ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiangvoid cras_iodev_list_notify_node_left_right_swapped(struct cras_ionode *node)
15353ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang{
15363ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  notify_node_left_right_swapped_called++;
15373ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang}
15383ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang
15399690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chaostruct cras_audio_area *cras_audio_area_create(int num_channels) {
15409690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao	return NULL;
15419690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao}
15429690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao
15439690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chaovoid cras_audio_area_destroy(struct cras_audio_area *area) {
15449690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao}
15459690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao
15469690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chaovoid cras_audio_area_config_channels(struct cras_audio_area *area,
15479690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao                                     const struct cras_audio_format *fmt) {
15489690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao}
15499690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao
15507b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chaoint cras_audio_format_set_channel_layout(struct cras_audio_format *format,
15517b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao					 const int8_t layout[CRAS_CH_MAX])
15527b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao{
1553a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  int i;
1554a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  cras_audio_format_set_channel_layout_called++;
1555a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  for (i = 0; i < CRAS_CH_MAX; i++)
1556a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao    format->channel_layout[i] = layout[i];
15577b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao  return 0;
15587b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao}
15597b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao
15605342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangfloat softvol_get_scaler(unsigned int volume_index)
15615342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang{
15625342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang	return softvol_scalers[volume_index];
15635342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang}
15645342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
15655342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangsize_t cras_system_get_volume() {
15665342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  return cras_system_get_volume_return;
15675342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang}
15687b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao
1569034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chianglong cras_system_get_capture_gain() {
1570034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  return cras_system_get_capture_gain_ret_value;
1571034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang}
1572034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
1573d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidint cras_system_get_mute() {
15741c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  return cras_system_get_mute_return;
1575d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1576d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1577d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidint cras_system_get_capture_mute() {
1578d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return 0;
1579d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1580d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1581249e72919eb928e107d251b262c305a8fe531641Dylan Reidvoid cras_scale_buffer(snd_pcm_format_t fmt, uint8_t *buffer,
15821efd30f3854ac69a6916bdeaa82dae3f01d18acaDylan Reid                       unsigned int count, float scaler) {
1583249e72919eb928e107d251b262c305a8fe531641Dylan Reid  cras_scale_buffer_fmt = fmt;
15841c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_scale_buffer_scaler = scaler;
1585d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1586d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
1587d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidsize_t cras_mix_mute_buffer(uint8_t *dst,
1588d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                            size_t frame_bytes,
1589d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                            size_t count) {
1590d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_mix_mute_count = count;
1591d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return count;
1592d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
1593d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
159465ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidstruct rate_estimator *rate_estimator_create(unsigned int rate,
159565ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid                                             const struct timespec *window_size,
159665ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid                                             double smooth_factor) {
159765ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid  return NULL;
159865ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
159965ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
160065ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidvoid rate_estimator_destroy(struct rate_estimator *re) {
160165ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
160265ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
160365ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidvoid rate_estimator_add_frames(struct rate_estimator *re, int fr) {
16041c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_called++;
16051c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_num_frames = fr;
160665ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
160765ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
160865ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidint rate_estimator_check(struct rate_estimator *re, int level,
160965ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid                         struct timespec *now) {
161065ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid  return 0;
161165ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
161265ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
161365ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidvoid rate_estimator_reset_rate(struct rate_estimator *re, unsigned int rate) {
161465ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
161565ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
161665ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reiddouble rate_estimator_get_rate(struct rate_estimator *re) {
161765ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid  return 0.0;
161865ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
161965ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
1620c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chaounsigned int dev_stream_cb_threshold(const struct dev_stream *dev_stream) {
162124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  if (dev_stream->stream)
162224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao    return dev_stream->stream->cb_threshold;
1623c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chao  return 0;
1624c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chao}
1625c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chao
1626dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangint dev_stream_attached_devs(const struct dev_stream *dev_stream) {
1627dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  return 1;
1628dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
1629dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1630dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangvoid dev_stream_update_frames(const struct dev_stream *dev_stream) {
1631dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
1632dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1633dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangint dev_stream_playback_frames(const struct dev_stream *dev_stream) {
1634dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  return dev_stream_playback_frames_ret;
1635dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
1636dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1637838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}  // extern "C"
1638838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}  //  namespace
1639838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1640838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidint main(int argc, char **argv) {
1641838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  ::testing::InitGoogleTest(&argc, argv);
164239c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang  int rc = RUN_ALL_TESTS();
164339c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang
164439c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang  audio_thread_event_log_deinit(atlog);
164539c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang  return rc;
1646838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
1647