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"
1064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang#include "cras_ramp.h"
11838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid#include "cras_rstream.h"
1224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao#include "dev_stream.h"
13838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid#include "utlist.h"
14cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang#include "cras_audio_area.h"
15dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang#include "audio_thread_log.h"
165342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
175342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang// Mock software volume scalers.
185342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangfloat softvol_scalers[101];
19838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
20838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
21cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang#define BUFFER_SIZE 8192
22cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
23d4c8bcdbc8df5a1e6c0929e3747f39a9a89dd075Cheng-Yi Chiangstatic const float RAMP_UNMUTE_DURATION_SECS = 0.5;
24d4c8bcdbc8df5a1e6c0929e3747f39a9a89dd075Cheng-Yi Chiangstatic const float RAMP_NEW_STREAM_DURATION_SECS = 0.01;
25d4c8bcdbc8df5a1e6c0929e3747f39a9a89dd075Cheng-Yi Chiangstatic const float RAMP_MUTE_DURATION_SECS = 0.1;
2664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
27e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chaostatic int cras_iodev_list_disable_dev_called;
28ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changstatic int select_node_called;
29ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changstatic enum CRAS_STREAM_DIRECTION select_node_direction;
30ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changstatic cras_node_id_t select_node_id;
31f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Changstatic struct cras_ionode *node_selected;
32b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Changstatic size_t notify_nodes_changed_called;
33c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Changstatic size_t notify_active_node_changed_called;
34b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic size_t notify_node_volume_called;
35b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic size_t notify_node_capture_gain_called;
36ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Changstatic int dsp_context_new_sample_rate;
37ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Changstatic const char *dsp_context_new_purpose;
385fa790469656d3e093799329f814756600762a71Dylan Reidstatic int dsp_context_free_called;
39663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chaostatic int update_channel_layout_called;
40663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chaostatic int update_channel_layout_return_val;
413285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiangstatic int  set_swap_mode_for_node_called;
423285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiangstatic int  set_swap_mode_for_node_enable;
433ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiangstatic int notify_node_left_right_swapped_called;
44a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chaostatic int cras_audio_format_set_channel_layout_called;
455342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangstatic unsigned int cras_system_get_volume_return;
46d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_get_pipeline_called;
47d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_get_pipeline_ret;
48d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_put_pipeline_called;
49d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_get_source_buffer_called;
50d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_get_sink_buffer_called;
51d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic float cras_dsp_pipeline_source_buffer[2][DSP_BUFFER_SIZE];
52d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic float cras_dsp_pipeline_sink_buffer[2][DSP_BUFFER_SIZE];
53d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_get_delay_called;
54d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_apply_called;
55d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic int cras_dsp_pipeline_apply_sample_count;
56d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstatic unsigned int cras_mix_mute_count;
572db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reidstatic unsigned int cras_dsp_num_input_channels_return;
582db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reidstatic unsigned int cras_dsp_num_output_channels_return;
592db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reidstruct cras_dsp_context *cras_dsp_context_new_return;
601c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic unsigned int rate_estimator_add_frames_num_frames;
611c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic unsigned int rate_estimator_add_frames_called;
621c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic int cras_system_get_mute_return;
63249e72919eb928e107d251b262c305a8fe531641Dylan Reidstatic snd_pcm_format_t cras_scale_buffer_fmt;
641c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic float cras_scale_buffer_scaler;
6564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic int cras_scale_buffer_called;
6637048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic unsigned int pre_dsp_hook_called;
6737048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic const uint8_t *pre_dsp_hook_frames;
6864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
69081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chenstatic void *pre_dsp_hook_cb_data;
7037048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic unsigned int post_dsp_hook_called;
7137048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic const uint8_t *post_dsp_hook_frames;
72081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chenstatic void *post_dsp_hook_cb_data;
7324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chaostatic int iodev_buffer_size;
74034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiangstatic long cras_system_get_capture_gain_ret_value;
75cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiangstatic uint8_t audio_buffer[BUFFER_SIZE];
76cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiangstatic struct cras_audio_area *audio_area;
771bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiangstatic unsigned int put_buffer_nframes;
78016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int output_should_wake_ret;
79016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int no_stream_called;
80016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int no_stream_enable;
8139c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang// This will be used extensively in cras_iodev.
82dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstruct audio_thread_event_log *atlog;
83dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstatic unsigned int simple_no_stream_called;
84dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstatic int simple_no_stream_enable;
85dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstatic int dev_stream_playback_frames_ret;
86595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiangstatic int get_num_underruns_ret;
87ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiangstatic int device_monitor_reset_device_called;
885c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiangstatic int output_underrun_called;
89c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiangstatic int set_mute_called;
9064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic int cras_ramp_start_is_up;
9164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic int cras_ramp_start_duration_frames;
9264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic int cras_ramp_start_is_called;
9364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic int cras_ramp_reset_is_called;
9464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic struct cras_ramp_action cras_ramp_get_current_action_ret;
9564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic int cras_ramp_update_ramped_frames_num_frames;
9664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic cras_ramp_cb cras_ramp_start_cb;
9764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic void* cras_ramp_start_cb_data;
9864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic int cras_device_monitor_set_device_mute_state_called;
9964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic struct cras_iodev* cras_device_monitor_set_device_mute_state_dev;
10064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic snd_pcm_format_t cras_scale_buffer_increment_fmt;
10164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic uint8_t *cras_scale_buffer_increment_buff;
10264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic unsigned int cras_scale_buffer_increment_frame;
10364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic float cras_scale_buffer_increment_scaler;
10464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic float cras_scale_buffer_increment_increment;
10564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstatic int cras_scale_buffer_increment_channel;
106663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
107663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao// Iodev callback
108663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chaoint update_channel_layout(struct cras_iodev *iodev) {
109663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  update_channel_layout_called = 1;
110663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  return update_channel_layout_return_val;
111663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao}
1126f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
1133285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang// Iodev callback
1143285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiangint set_swap_mode_for_node(struct cras_iodev *iodev, struct cras_ionode *node,
1153285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang                           int enable)
1163285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang{
1173285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_called++;
1183285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_enable = enable;
1193285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  return 0;
1203285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang}
1213285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang
1226f0a5e6a967558105f37513801af573167890f67Chih-Chung Changvoid ResetStubData() {
123e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  cras_iodev_list_disable_dev_called = 0;
124ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_called = 0;
125b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  notify_nodes_changed_called = 0;
126c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  notify_active_node_changed_called = 0;
127b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  notify_node_volume_called = 0;
128b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  notify_node_capture_gain_called = 0;
129ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_sample_rate = 0;
130ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_purpose = NULL;
1315fa790469656d3e093799329f814756600762a71Dylan Reid  dsp_context_free_called = 0;
1323285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_called = 0;
1333285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  set_swap_mode_for_node_enable = 0;
1343ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  notify_node_left_right_swapped_called = 0;
135a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  cras_audio_format_set_channel_layout_called = 0;
136d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_get_pipeline_called = 0;
137d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_get_pipeline_ret = 0;
138d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_put_pipeline_called = 0;
139d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_source_buffer_called = 0;
140d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_sink_buffer_called = 0;
141d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  memset(&cras_dsp_pipeline_source_buffer, 0,
142d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid         sizeof(cras_dsp_pipeline_source_buffer));
143d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  memset(&cras_dsp_pipeline_sink_buffer, 0,
144d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid         sizeof(cras_dsp_pipeline_sink_buffer));
145d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_delay_called = 0;
146d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_called = 0;
147d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_sample_count = 0;
1482db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_input_channels_return = 2;
1492db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_output_channels_return = 2;
1502db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_context_new_return = NULL;
1511c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_num_frames = 0;
1521c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_called = 0;
1531c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_system_get_mute_return = 0;
154006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  cras_system_get_volume_return = 100;
1551c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_mix_mute_count = 0;
15637048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_called = 0;
15737048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_frames = NULL;
15837048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_called = 0;
15964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  post_dsp_hook_frames = NULL; iodev_buffer_size = 0;
160034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  cras_system_get_capture_gain_ret_value = 0;
161cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  // Assume there is some data in audio buffer.
162cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  memset(audio_buffer, 0xff, sizeof(audio_buffer));
163cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  if (audio_area) {
164cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    free(audio_area);
165cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    audio_area = NULL;
166cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  }
1671bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  put_buffer_nframes = 0;
168016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  output_should_wake_ret= 0;
169016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_called = 0;
170016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_enable = 0;
171dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  simple_no_stream_called = 0;
172dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  simple_no_stream_enable = 0;
173dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 0;
17439c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang  if (!atlog)
17539c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang    atlog = audio_thread_event_log_init();
176595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  get_num_underruns_ret = 0;
177ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  device_monitor_reset_device_called = 0;
1785c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  output_underrun_called = 0;
179c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  set_mute_called = 0;
18064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_is_up = 0;
18164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_duration_frames = 0;
18264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_cb = NULL;
18364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_cb_data = NULL;
18464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_is_called = 0;
18564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_reset_is_called = 0;
18664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.type = CRAS_RAMP_ACTION_NONE;
18764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_update_ramped_frames_num_frames = 0;
18864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_device_monitor_set_device_mute_state_called = 0;
18964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_device_monitor_set_device_mute_state_dev = NULL;
19064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_called = 0;
19164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_fmt = SND_PCM_FORMAT_UNKNOWN;
19264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_buff = NULL;
19364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_frame = 0;
19464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_scaler = 0;
19564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_increment = 0;
19664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_channel = 0;
1976f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
1986f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
199838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidnamespace {
200838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
201838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid//  Test fill_time_from_frames
202838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan ReidTEST(IoDevTestSuite, FillTimeFromFramesNormal) {
203838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  struct timespec ts;
204838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
205f880b868b8da1f20594ff271492f7055d4977bb6Dylan Reid  cras_iodev_fill_time_from_frames(12000, 48000, &ts);
206838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(0, ts.tv_sec);
207838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
208838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
209838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
210838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
211838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan ReidTEST(IoDevTestSuite, FillTimeFromFramesLong) {
212838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  struct timespec ts;
213838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
214f880b868b8da1f20594ff271492f7055d4977bb6Dylan Reid  cras_iodev_fill_time_from_frames(120000 - 12000, 48000, &ts);
215838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(2, ts.tv_sec);
216838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_GE(ts.tv_nsec, 249900000);
217838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_LE(ts.tv_nsec, 250100000);
218838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
219838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
220838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan ReidTEST(IoDevTestSuite, FillTimeFromFramesShort) {
221838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  struct timespec ts;
222838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
223f880b868b8da1f20594ff271492f7055d4977bb6Dylan Reid  cras_iodev_fill_time_from_frames(12000 - 12000, 48000, &ts);
224838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(0, ts.tv_sec);
225838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  EXPECT_EQ(0, ts.tv_nsec);
226838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
227838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
228045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Changclass IoDevSetFormatTestSuite : public testing::Test {
229045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  protected:
230045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    virtual void SetUp() {
2312db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid      ResetStubData();
232045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      sample_rates_[0] = 44100;
233045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      sample_rates_[1] = 48000;
234045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      sample_rates_[2] = 0;
235045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
236045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      channel_counts_[0] = 2;
237045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      channel_counts_[1] = 0;
238663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      channel_counts_[2] = 0;
239663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
240a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      pcm_formats_[0] = SND_PCM_FORMAT_S16_LE;
241a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      pcm_formats_[1] = SND_PCM_FORMAT_S32_LE;
242a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      pcm_formats_[2] = static_cast<snd_pcm_format_t>(0);
243a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid
244663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      update_channel_layout_called = 0;
245663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      update_channel_layout_return_val = 0;
246045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
247045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      memset(&iodev_, 0, sizeof(iodev_));
248663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao      iodev_.update_channel_layout = update_channel_layout;
249045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      iodev_.supported_rates = sample_rates_;
250045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang      iodev_.supported_channel_counts = channel_counts_;
251a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid      iodev_.supported_formats = pcm_formats_;
252aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid      iodev_.dsp_context = NULL;
253a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao
254a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao      cras_audio_format_set_channel_layout_called  = 0;
255045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    }
256045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
2575b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang    virtual void TearDown() {
2585b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang      cras_iodev_free_format(&iodev_);
2595b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang    }
2605b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
261045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    struct cras_iodev iodev_;
262045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang    size_t sample_rates_[3];
263663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao    size_t channel_counts_[3];
264a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid    snd_pcm_format_t pcm_formats_[3];
265045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang};
266045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
267045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatSecondary) {
268045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
269045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
270045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
271045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
272045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 48000;
273045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
274ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  iodev_.direction = CRAS_STREAM_OUTPUT;
275ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  ResetStubData();
276045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
277045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
278bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
279bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
280bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
281ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  EXPECT_EQ(dsp_context_new_sample_rate, 48000);
28229b418afbe347e21bf01e29c235919ed5d3035dbYunlian Jiang  EXPECT_STREQ(dsp_context_new_purpose, "playback");
283045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
284045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
285a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan ReidTEST_F(IoDevSetFormatTestSuite, SupportedFormat32bit) {
286a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  struct cras_audio_format fmt;
287a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  int rc;
288a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid
289a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  fmt.format = SND_PCM_FORMAT_S32_LE;
290a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  fmt.frame_rate = 48000;
291a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  fmt.num_channels = 2;
292a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  iodev_.direction = CRAS_STREAM_OUTPUT;
293a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  ResetStubData();
294a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
295a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  EXPECT_EQ(0, rc);
296bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S32_LE, iodev_.ext_format->format);
297bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
298bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
299a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  EXPECT_EQ(dsp_context_new_sample_rate, 48000);
300a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid  EXPECT_STREQ(dsp_context_new_purpose, "playback");
301a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid}
302a485ac04bdfc71e374a3a5d2fbcf4699999a2939Dylan Reid
303045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatPrimary) {
304045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
305045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
306045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
307045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
308045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 44100;
309045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
310ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  iodev_.direction = CRAS_STREAM_INPUT;
311ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  ResetStubData();
312045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
313045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
314bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
315bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(44100, iodev_.ext_format->frame_rate);
316bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
317ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  EXPECT_EQ(dsp_context_new_sample_rate, 44100);
31829b418afbe347e21bf01e29c235919ed5d3035dbYunlian Jiang  EXPECT_STREQ(dsp_context_new_purpose, "capture");
319045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
320045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
321045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatDivisor) {
322045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
323045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
324045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
325045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
326045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 96000;
327045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
328045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
329045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
330bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
331bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
332bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
333045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
334045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
33597d26e1687da4f38da88b868b6b827aeea50871aDylan ReidTEST_F(IoDevSetFormatTestSuite, Supported96k) {
33697d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  struct cras_audio_format fmt;
33797d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  int rc;
33897d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
33997d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[0] = 48000;
34097d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[1] = 96000;
34197d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[2] = 0;
34297d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
34397d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
34497d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.frame_rate = 96000;
34597d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.num_channels = 2;
34697d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
34797d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  EXPECT_EQ(0, rc);
348bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
349bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(96000, iodev_.ext_format->frame_rate);
350bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
35197d26e1687da4f38da88b868b6b827aeea50871aDylan Reid}
35297d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
35397d26e1687da4f38da88b868b6b827aeea50871aDylan ReidTEST_F(IoDevSetFormatTestSuite, LimitLowRate) {
35497d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  struct cras_audio_format fmt;
35597d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  int rc;
35697d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
35797d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[0] = 48000;
35897d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[1] = 8000;
35997d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  sample_rates_[2] = 0;
36097d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
36197d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
36297d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.frame_rate = 8000;
36397d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  fmt.num_channels = 2;
36497d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
36597d26e1687da4f38da88b868b6b827aeea50871aDylan Reid  EXPECT_EQ(0, rc);
366bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
367bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
368bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
36997d26e1687da4f38da88b868b6b827aeea50871aDylan Reid}
37097d26e1687da4f38da88b868b6b827aeea50871aDylan Reid
371045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, UnsupportedChannelCount) {
372045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
373045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
374045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
375045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
376045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 96000;
377045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 1;
378045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
379045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
380bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
381bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
382bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
383045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
384045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
385045156126f648a9f0910152a66572a13447bfdc6Chih-Chung ChangTEST_F(IoDevSetFormatTestSuite, SupportedFormatFallbackDefault) {
386045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  struct cras_audio_format fmt;
387045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  int rc;
388045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
389045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.format = SND_PCM_FORMAT_S16_LE;
390045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.frame_rate = 96008;
391045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  fmt.num_channels = 2;
392045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  rc = cras_iodev_set_format(&iodev_, &fmt);
393045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang  EXPECT_EQ(0, rc);
394bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
395bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(44100, iodev_.ext_format->frame_rate);
396bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
397045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang}
398045156126f648a9f0910152a66572a13447bfdc6Chih-Chung Chang
3992db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan ReidTEST_F(IoDevSetFormatTestSuite, OutputDSPChannleReduction) {
4002db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  struct cras_audio_format fmt;
4012db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  int rc;
4022db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
4032db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
4042db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.frame_rate = 48000;
4052db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.num_channels = 2;
4062db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
4072db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.direction = CRAS_STREAM_OUTPUT;
4082db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[0] = 1;
4092db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[1] = 0;
4102db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf00);
4112db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_get_pipeline_ret =  0xf01;
4122db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_input_channels_return = 2;
4132db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_output_channels_return = 1;
4142db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
4152db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  EXPECT_EQ(0, rc);
416bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
417bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
418bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
4192db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid}
4202db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
4212db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan ReidTEST_F(IoDevSetFormatTestSuite, InputDSPChannleReduction) {
4222db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  struct cras_audio_format fmt;
4232db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  int rc;
4242db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
4252db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
4262db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.frame_rate = 48000;
4272db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  fmt.num_channels = 2;
4282db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
4292db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.direction = CRAS_STREAM_INPUT;
4302db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[0] = 10;
4312db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  iodev_.supported_channel_counts[1] = 0;
4322db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf00);
4332db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_get_pipeline_ret =  0xf01;
4342db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_input_channels_return = 10;
4352db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  cras_dsp_num_output_channels_return = 2;
4362db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  rc = cras_iodev_set_format(&iodev_, &fmt);
4372db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  EXPECT_EQ(0, rc);
438bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
439bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
440bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
4412db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid}
4422db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid
443663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu ChaoTEST_F(IoDevSetFormatTestSuite, UpdateChannelLayoutSuccess) {
444663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  struct cras_audio_format fmt;
445663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  int rc;
446663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
447663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.format = SND_PCM_FORMAT_S16_LE;
448663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.frame_rate = 48000;
449663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.num_channels = 6;
450663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
451663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[0] = 6;
452663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[1] = 2;
453663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
454663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  rc = cras_iodev_set_format(&iodev_, &fmt);
455663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  EXPECT_EQ(0, rc);
456bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
457bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
458bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(6, iodev_.ext_format->num_channels);
459663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao}
460663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
461663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu ChaoTEST_F(IoDevSetFormatTestSuite, UpdateChannelLayoutFail) {
462a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  static const int8_t stereo_layout[] =
463a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao      {0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
464663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  struct cras_audio_format fmt;
465a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  int rc, i;
466663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
467663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.format = SND_PCM_FORMAT_S16_LE;
468663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  fmt.frame_rate = 48000;
4691609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.num_channels = 2;
470663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
4715fa790469656d3e093799329f814756600762a71Dylan Reid  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf0f);
4725fa790469656d3e093799329f814756600762a71Dylan Reid
473663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  update_channel_layout_return_val = -1;
474663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[0] = 6;
475663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  iodev_.supported_channel_counts[1] = 2;
476663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
477663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  rc = cras_iodev_set_format(&iodev_, &fmt);
478663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao  EXPECT_EQ(0, rc);
479bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
480bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
481bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, iodev_.ext_format->num_channels);
482bba7a4b0d07dbdc77f209025a032ce4c791e650aHsin-Yu Chao  EXPECT_EQ(2, cras_audio_format_set_channel_layout_called);
4835fa790469656d3e093799329f814756600762a71Dylan Reid  EXPECT_EQ(0, dsp_context_free_called);
484a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  for (i = 0; i < CRAS_CH_MAX; i++)
485a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao    EXPECT_EQ(iodev_.format->channel_layout[i], stereo_layout[i]);
486663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao}
487663a962502c7587d464fe555e836c5d70e1c7194Hsin-Yu Chao
4881609667463605b64a0849f6ae7f26adf698cf5b3Ben ZhangTEST_F(IoDevSetFormatTestSuite, UpdateChannelLayoutFail6ch) {
4891609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  static const int8_t default_6ch_layout[] =
4901609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang      {0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1};
4911609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  struct cras_audio_format fmt;
4921609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  int rc, i;
4931609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4941609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.format = SND_PCM_FORMAT_S16_LE;
4951609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.frame_rate = 48000;
4961609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  fmt.num_channels = 6;
4971609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
4981609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  cras_dsp_context_new_return = reinterpret_cast<cras_dsp_context *>(0xf0f);
4991609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
5001609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  update_channel_layout_return_val = -1;
5011609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  iodev_.supported_channel_counts[0] = 6;
5021609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  iodev_.supported_channel_counts[1] = 2;
5031609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
5041609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  rc = cras_iodev_set_format(&iodev_, &fmt);
5051609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(0, rc);
5061609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, iodev_.ext_format->format);
5071609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(48000, iodev_.ext_format->frame_rate);
5081609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(6, iodev_.ext_format->num_channels);
5091609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(2, cras_audio_format_set_channel_layout_called);
5101609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  EXPECT_EQ(0, dsp_context_free_called);
5111609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang  for (i = 0; i < CRAS_CH_MAX; i++)
5121609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang    EXPECT_EQ(iodev_.format->channel_layout[i], default_6ch_layout[i]);
5131609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang}
5141609667463605b64a0849f6ae7f26adf698cf5b3Ben Zhang
5151c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid// Put buffer tests
5161c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
517cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiangstatic int get_buffer(cras_iodev* iodev, struct cras_audio_area** area,
518cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang               unsigned int* num) {
519cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  size_t sz = sizeof(*audio_area) + sizeof(struct cras_channel_area) * 2;
520cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
521cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area = (cras_audio_area*)calloc(1, sz);
522cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->frames = *num;
523cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->num_channels = 2;
524cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[0].buf = audio_buffer;
525cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  channel_area_set_channel(&audio_area->channels[0], CRAS_CH_FL);
526cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[0].step_bytes = 4;
527cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[1].buf = audio_buffer + 2;
528cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  channel_area_set_channel(&audio_area->channels[1], CRAS_CH_FR);
529cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  audio_area->channels[1].step_bytes = 4;
530cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
531cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  *area = audio_area;
532cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  return 0;
533cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang}
534cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
5351c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reidstatic int put_buffer(struct cras_iodev *iodev, unsigned int nframes)
5361c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid{
5371c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  put_buffer_nframes = nframes;
538cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  if (audio_area) {
539cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    free(audio_area);
540cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang    audio_area = NULL;
541cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  }
5421c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  return 0;
5431c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
5441c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
545016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int no_stream(struct cras_iodev *odev, int enable)
546016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang{
547016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_called++;
548016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  no_stream_enable = enable;
549016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  // Use default no stream playback to test default behavior.
550016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  return cras_iodev_default_no_stream_playback(odev, enable);
551016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang}
552016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
553016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiangstatic int output_should_wake(const struct cras_iodev *odev)
554016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang{
555016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  return output_should_wake_ret;
556016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang}
557016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
55837048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic int pre_dsp_hook(const uint8_t *frames, unsigned int nframes,
559081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen			const struct cras_audio_format *fmt, void *cb_data)
56037048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid{
56137048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_called++;
56237048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  pre_dsp_hook_frames = frames;
563081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  pre_dsp_hook_cb_data = cb_data;
56437048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  return 0;
56537048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid}
56637048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid
56737048d8a04b223de7d47d9f049dcede7e5036066Dylan Reidstatic int post_dsp_hook(const uint8_t *frames, unsigned int nframes,
568081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen			 const struct cras_audio_format *fmt, void *cb_data)
56937048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid{
57037048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_called++;
57137048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  post_dsp_hook_frames = frames;
572081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  post_dsp_hook_cb_data = cb_data;
57337048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  return 0;
57437048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid}
57537048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid
5761c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, SystemMuted) {
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  cras_system_get_mute_return = 1;
5851c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5861c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
5871c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
5881c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
5891c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
5901c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
5911c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
5921c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 20);
5931c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
5941c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(20, cras_mix_mute_count);
5951c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(20, put_buffer_nframes);
5961c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(20, rate_estimator_add_frames_num_frames);
5971c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
5981c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
59982d5f064a97e622eba81ef503b632bac84692024Cheng-Yi ChiangTEST(IoDevPutOutputBuffer, MuteForVolume) {
60082d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  struct cras_iodev iodev;
60182d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  struct cras_ionode ionode;
60282d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang
60382d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  ResetStubData();
60482d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
60582d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
60682d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang
60782d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  iodev.nodes = &ionode;
60882d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  iodev.active_node = &ionode;
60982d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  iodev.active_node->dev = &iodev;
61082d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang
61182d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  // Case: System volume 100; Node volume 0. => Mute
61282d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  cras_system_get_volume_return = 100;
61382d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  iodev.active_node->volume = 0;
61482d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  EXPECT_EQ(1, cras_iodev_is_zero_volume(&iodev));
61582d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang
61682d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  // Case: System volume 100; Node volume 50. => Not mute
61782d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  cras_system_get_volume_return = 100;
61882d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  iodev.active_node->volume = 50;
61982d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  EXPECT_EQ(0, cras_iodev_is_zero_volume(&iodev));
62082d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang
62182d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  // Case: System volume 0; Node volume 50. => Mute
62282d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  cras_system_get_volume_return = 0;
62382d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  iodev.active_node->volume = 50;
62482d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  EXPECT_EQ(1, cras_iodev_is_zero_volume(&iodev));
62582d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang
62682d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  // Case: System volume 50; Node volume 50. => Mute
62782d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  cras_system_get_volume_return = 50;
62882d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  iodev.active_node->volume = 50;
62982d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang  EXPECT_EQ(1, cras_iodev_is_zero_volume(&iodev));
63082d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang}
63182d5f064a97e622eba81ef503b632bac84692024Cheng-Yi Chiang
632006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi ChiangTEST(IoDevPutOutputBuffer, NodeVolumeZeroShouldMute) {
633006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  struct cras_audio_format fmt;
634006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  struct cras_iodev iodev;
635006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  struct cras_ionode ionode;
636006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
637006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  int rc;
638006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang
639006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  ResetStubData();
640006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
641006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
642006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang
643006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.nodes = &ionode;
644006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.active_node = &ionode;
645006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.active_node->dev = &iodev;
646006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.active_node->volume = 0;
647006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang
648006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
649006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  fmt.frame_rate = 48000;
650006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  fmt.num_channels = 2;
651006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.format = &fmt;
652006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.put_buffer = put_buffer;
653006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang
654006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  rc = cras_iodev_put_output_buffer(&iodev, frames, 20);
655006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  EXPECT_EQ(0, rc);
656006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  EXPECT_EQ(20, cras_mix_mute_count);
657006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  EXPECT_EQ(20, put_buffer_nframes);
658006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  EXPECT_EQ(20, rate_estimator_add_frames_num_frames);
659006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang}
660006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang
66164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi ChiangTEST(IoDevPutOutputBuffer, SystemMutedWithRamp) {
66264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_audio_format fmt;
66364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_iodev iodev;
66464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
66564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  int rc;
66664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
66764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
66864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
66964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_system_get_mute_return = 1;
67064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
67164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
67264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.frame_rate = 48000;
67364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.num_channels = 2;
67464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.format = &fmt;
67564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.put_buffer = put_buffer;
67664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
67764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume device has ramp member.
67864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.ramp = reinterpret_cast<struct cras_ramp*>(0x1);
67964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
68064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume ramping is done.
68164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.type = CRAS_RAMP_ACTION_NONE;
68264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
68364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_put_output_buffer(&iodev, frames, 20);
68464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Output should be muted.
68564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
68664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, cras_mix_mute_count);
68764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, put_buffer_nframes);
68864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, rate_estimator_add_frames_num_frames);
68964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
69064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Test for the case where ramping is not done yet.
69164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
69264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.type = CRAS_RAMP_ACTION_PARTIAL;
69364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_put_output_buffer(&iodev, frames, 20);
69464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
69564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Output should not be muted.
69664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
69764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_mix_mute_count);
69864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Ramped frames should be increased by 20.
69964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, cras_ramp_update_ramped_frames_num_frames);
70064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, put_buffer_nframes);
70164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, rate_estimator_add_frames_num_frames);
70264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
70364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
70464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi ChiangTEST(IoDevPutOutputBuffer, NodeVolumeZeroShouldMuteWithRamp) {
70564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_audio_format fmt;
70664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_iodev iodev;
70764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_ionode ionode;
70864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
70964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  int rc;
71064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
71164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
71264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
71364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
71464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
71564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.nodes = &ionode;
71664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.active_node = &ionode;
71764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.active_node->dev = &iodev;
71864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.active_node->volume = 0;
71964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
72064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
72164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.frame_rate = 48000;
72264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.num_channels = 2;
72364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.format = &fmt;
72464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.put_buffer = put_buffer;
72564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
72664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume device has ramp member.
72764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.ramp = reinterpret_cast<struct cras_ramp*>(0x1);
72864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
72964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume ramping is done.
73064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.type = CRAS_RAMP_ACTION_NONE;
73164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
73264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_put_output_buffer(&iodev, frames, 20);
73364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
73464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, cras_mix_mute_count);
73564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, put_buffer_nframes);
73664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, rate_estimator_add_frames_num_frames);
73764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
73864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Test for the case where ramping is not done yet.
73964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
74064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.type = CRAS_RAMP_ACTION_PARTIAL;
74164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_put_output_buffer(&iodev, frames, 20);
74264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
74364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Output should not be muted.
74464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
74564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_mix_mute_count);
74664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Ramped frames should be increased by 20.
74764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, cras_ramp_update_ramped_frames_num_frames);
74864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, put_buffer_nframes);
74964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(20, rate_estimator_add_frames_num_frames);
75064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
7511c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, NoDSP) {
7521c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
7531c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
754006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  struct cras_ionode ionode;
7551c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
7561c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
7571c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
7581c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
7591c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
760006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
761006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang
762006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.nodes = &ionode;
763006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.active_node = &ionode;
764006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.active_node->dev = &iodev;
765006d362f3f3ceabd9c3910c285f1344f391938c8Cheng-Yi Chiang  iodev.active_node->volume = 100;
7661c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
7671c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
7681c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
7691c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
7701c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
7711c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
7721c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
7731c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 22);
7741c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
7751c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
7761c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(22, put_buffer_nframes);
7771c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(22, rate_estimator_add_frames_num_frames);
7781c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
7791c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
7801c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, DSP) {
7811c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
7821c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
7831c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
7841c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
7851c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
7861c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
7871c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
7881c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.dsp_context = reinterpret_cast<cras_dsp_context*>(0x15);
7891c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_dsp_get_pipeline_ret = 0x25;
7901c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
7911c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
7921c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
7931c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
7941c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
7951c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
796081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  cras_iodev_register_pre_dsp_hook(&iodev, pre_dsp_hook, (void *)0x1234);
797081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  cras_iodev_register_post_dsp_hook(&iodev, post_dsp_hook, (void *)0x5678);
7981c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
7991c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 32);
8001c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
8011c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
80237048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  EXPECT_EQ(1, pre_dsp_hook_called);
80337048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  EXPECT_EQ(frames, pre_dsp_hook_frames);
804081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  EXPECT_EQ((void *)0x1234, pre_dsp_hook_cb_data);
80537048d8a04b223de7d47d9f049dcede7e5036066Dylan Reid  EXPECT_EQ(1, post_dsp_hook_called);
806081f69891fbf2ebbdb6b74e6b9ff59cd23f3eea0Chinyue Chen  EXPECT_EQ((void *)0x5678, post_dsp_hook_cb_data);
8071c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(32, put_buffer_nframes);
8081c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(32, rate_estimator_add_frames_num_frames);
8091c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(32, cras_dsp_pipeline_apply_sample_count);
8101c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(cras_dsp_get_pipeline_called, cras_dsp_put_pipeline_called);
8111c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
8121c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
8131c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan ReidTEST(IoDevPutOutputBuffer, SoftVol) {
8141c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_audio_format fmt;
8151c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  struct cras_iodev iodev;
8161c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
8171c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  int rc;
8181c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
8191c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  ResetStubData();
8201c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  memset(&iodev, 0, sizeof(iodev));
8211c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.software_volume_needed = 1;
8221c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
8231c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.format = SND_PCM_FORMAT_S16_LE;
8241c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.frame_rate = 48000;
8251c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  fmt.num_channels = 2;
8261c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.format = &fmt;
8271c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  iodev.put_buffer = put_buffer;
8281c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
8291c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_system_get_volume_return = 13;
8301c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  softvol_scalers[13] = 0.435;
8311c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
8321c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 53);
8331c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, rc);
8341c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
8351c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(53, put_buffer_nframes);
8361c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(53, rate_estimator_add_frames_num_frames);
8371c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  EXPECT_EQ(softvol_scalers[13], cras_scale_buffer_scaler);
838249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, cras_scale_buffer_fmt);
839249e72919eb928e107d251b262c305a8fe531641Dylan Reid}
840249e72919eb928e107d251b262c305a8fe531641Dylan Reid
84164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi ChiangTEST(IoDevPutOutputBuffer, SoftVolWithRamp) {
84264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_audio_format fmt;
84364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_iodev iodev;
84464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
84564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  int rc;
84664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  int n_frames = 53;
84764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  float ramp_scaler = 0.2;
84864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  float increment = 0.001;
84964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  int volume = 13;
85064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  float volume_scaler = 0.435;
85164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
85264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
85364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
85464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.software_volume_needed = 1;
85564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
85664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
85764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.frame_rate = 48000;
85864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.num_channels = 2;
85964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.format = &fmt;
86064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.put_buffer = put_buffer;
86164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume device has ramp member.
86264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.ramp = reinterpret_cast<struct cras_ramp*>(0x1);
86364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
86464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume ramping is done.
86564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.type = CRAS_RAMP_ACTION_NONE;
86664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
86764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_system_get_volume_return = volume;
86864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  softvol_scalers[volume] = volume_scaler;
86964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
87064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_put_output_buffer(&iodev, frames, n_frames);
87164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
87264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_mix_mute_count);
87364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, put_buffer_nframes);
87464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, rate_estimator_add_frames_num_frames);
87564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(softvol_scalers[volume], cras_scale_buffer_scaler);
87664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(SND_PCM_FORMAT_S16_LE, cras_scale_buffer_fmt);
87764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
87864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
87964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume ramping is not done.
88064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.type = CRAS_RAMP_ACTION_PARTIAL;
88164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.scaler = ramp_scaler;
88264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.increment = increment;
88364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
88464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_system_get_volume_return = volume;
88564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  softvol_scalers[volume] = volume_scaler;
88664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
88764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_put_output_buffer(&iodev, frames, n_frames);
88864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
88964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_mix_mute_count);
89064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // cras_scale_buffer is not called.
89164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_scale_buffer_called);
89264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
89364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Verify the arguments passed to cras_scale_buffer_increment.
89464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(fmt.format, cras_scale_buffer_increment_fmt);
89564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(frames, cras_scale_buffer_increment_buff);
89664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, cras_scale_buffer_increment_frame);
89764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Initial scaler will be product of software volume scaler and
89864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // ramp scaler.
89964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_FLOAT_EQ(softvol_scalers[volume] * ramp_scaler,
90064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang                  cras_scale_buffer_increment_scaler);
90164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Increment scaler will be product of software volume scaler and
90264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // ramp increment.
90364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_FLOAT_EQ(softvol_scalers[volume] * increment,
90464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang                  cras_scale_buffer_increment_increment);
90564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(fmt.num_channels, cras_scale_buffer_increment_channel);
90664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
90764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, put_buffer_nframes);
90864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, rate_estimator_add_frames_num_frames);
90964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
91064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
91164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi ChiangTEST(IoDevPutOutputBuffer, NoSoftVolWithRamp) {
91264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_audio_format fmt;
91364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_iodev iodev;
91464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
91564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  int rc;
91664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  int n_frames = 53;
91764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  float ramp_scaler = 0.2;
91864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  float increment = 0.001;
91964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
92064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
92164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
92264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.software_volume_needed = 0;
92364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
92464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
92564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.frame_rate = 48000;
92664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.num_channels = 2;
92764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.format = &fmt;
92864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.put_buffer = put_buffer;
92964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume device has ramp member.
93064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.ramp = reinterpret_cast<struct cras_ramp*>(0x1);
93164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
93264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume ramping is done.
93364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.type = CRAS_RAMP_ACTION_NONE;
93464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
93564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_put_output_buffer(&iodev, frames, n_frames);
93664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
93764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_mix_mute_count);
93864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // cras_scale_buffer is not called.
93964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_scale_buffer_called);
94064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, put_buffer_nframes);
94164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, rate_estimator_add_frames_num_frames);
94264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
94364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
94464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume ramping is not done.
94564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.type = CRAS_RAMP_ACTION_PARTIAL;
94664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.scaler = ramp_scaler;
94764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_get_current_action_ret.increment = increment;
94864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
94964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_put_output_buffer(&iodev, frames, n_frames);
95064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
95164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_mix_mute_count);
95264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // cras_scale_buffer is not called.
95364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_scale_buffer_called);
95464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
95564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Verify the arguments passed to cras_scale_buffer_increment.
95664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(fmt.format, cras_scale_buffer_increment_fmt);
95764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(frames, cras_scale_buffer_increment_buff);
95864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, cras_scale_buffer_increment_frame);
95964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_FLOAT_EQ(ramp_scaler, cras_scale_buffer_increment_scaler);
96064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_FLOAT_EQ(increment, cras_scale_buffer_increment_increment);
96164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(fmt.num_channels, cras_scale_buffer_increment_channel);
96264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
96364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, put_buffer_nframes);
96464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(n_frames, rate_estimator_add_frames_num_frames);
96564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
96664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
967249e72919eb928e107d251b262c305a8fe531641Dylan ReidTEST(IoDevPutOutputBuffer, Scale32Bit) {
968249e72919eb928e107d251b262c305a8fe531641Dylan Reid  struct cras_audio_format fmt;
969249e72919eb928e107d251b262c305a8fe531641Dylan Reid  struct cras_iodev iodev;
970249e72919eb928e107d251b262c305a8fe531641Dylan Reid  uint8_t *frames = reinterpret_cast<uint8_t*>(0x44);
971249e72919eb928e107d251b262c305a8fe531641Dylan Reid  int rc;
972249e72919eb928e107d251b262c305a8fe531641Dylan Reid
973249e72919eb928e107d251b262c305a8fe531641Dylan Reid  ResetStubData();
974249e72919eb928e107d251b262c305a8fe531641Dylan Reid  memset(&iodev, 0, sizeof(iodev));
975249e72919eb928e107d251b262c305a8fe531641Dylan Reid  iodev.software_volume_needed = 1;
976249e72919eb928e107d251b262c305a8fe531641Dylan Reid
977249e72919eb928e107d251b262c305a8fe531641Dylan Reid  cras_system_get_volume_return = 13;
978249e72919eb928e107d251b262c305a8fe531641Dylan Reid  softvol_scalers[13] = 0.435;
979249e72919eb928e107d251b262c305a8fe531641Dylan Reid
980249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.format = SND_PCM_FORMAT_S32_LE;
981249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.frame_rate = 48000;
982249e72919eb928e107d251b262c305a8fe531641Dylan Reid  fmt.num_channels = 2;
983249e72919eb928e107d251b262c305a8fe531641Dylan Reid  iodev.format = &fmt;
984249e72919eb928e107d251b262c305a8fe531641Dylan Reid  iodev.put_buffer = put_buffer;
985249e72919eb928e107d251b262c305a8fe531641Dylan Reid
986249e72919eb928e107d251b262c305a8fe531641Dylan Reid  rc = cras_iodev_put_output_buffer(&iodev, frames, 53);
987249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(0, rc);
988249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(0, cras_mix_mute_count);
989249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(53, put_buffer_nframes);
990249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(53, rate_estimator_add_frames_num_frames);
991249e72919eb928e107d251b262c305a8fe531641Dylan Reid  EXPECT_EQ(SND_PCM_FORMAT_S32_LE, cras_scale_buffer_fmt);
9921c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid}
9931c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid
994cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao// frames queued/avail tests
995cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
996cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chaostatic unsigned fr_queued = 0;
997cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
998fa4cd9766aec6eae544b1078ed835687c4e74617John Muirstatic int frames_queued(const struct cras_iodev *iodev,
999fa4cd9766aec6eae544b1078ed835687c4e74617John Muir                         struct timespec *tstamp)
1000cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao{
1001fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
1002cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  return fr_queued;
1003cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao}
1004cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
1005cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu ChaoTEST(IoDevQueuedBuffer, ZeroMinBufferLevel) {
1006cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  struct cras_iodev iodev;
1007fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  struct timespec tstamp;
1008cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  int rc;
1009cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
1010cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  ResetStubData();
1011cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  memset(&iodev, 0, sizeof(iodev));
1012cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.direction = CRAS_STREAM_OUTPUT;
1013cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.frames_queued = frames_queued;
1014cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.min_buffer_level = 0;
1015cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.buffer_size = 200;
1016cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  fr_queued = 50;
1017cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
1018fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  rc = cras_iodev_frames_queued(&iodev, &tstamp);
1019cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(50, rc);
1020cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_buffer_avail(&iodev, rc);
1021cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(150, rc);
1022cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao}
1023cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
1024cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu ChaoTEST(IoDevQueuedBuffer, NonZeroMinBufferLevel) {
1025cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  struct cras_iodev iodev;
1026fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  struct timespec hw_tstamp;
1027cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  int rc;
1028cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
1029cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  ResetStubData();
1030cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  memset(&iodev, 0, sizeof(iodev));
1031cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.direction = CRAS_STREAM_OUTPUT;
1032cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.frames_queued = frames_queued;
1033cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.min_buffer_level = 100;
1034cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  iodev.buffer_size = 200;
1035cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  fr_queued = 180;
1036cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
1037fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  rc = cras_iodev_frames_queued(&iodev, &hw_tstamp);
1038cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(80, rc);
1039cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_buffer_avail(&iodev, rc);
1040cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(20, rc);
1041cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
1042cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  /* When fr_queued < min_buffer_level*/
1043cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  fr_queued = 80;
1044fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  rc = cras_iodev_frames_queued(&iodev, &hw_tstamp);
1045cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(0, rc);
1046cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  rc = cras_iodev_buffer_avail(&iodev, rc);
1047cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao  EXPECT_EQ(100, rc);
1048cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao}
1049cda2e426ddf2c20dddfdfa0e972a0963b3dc1d0bHsin-Yu Chao
1050bb28140f38fdf6627ec26696c943dfa4f9188450Hsin-Yu Chaostatic void update_active_node(struct cras_iodev *iodev,
10510def72b968591065f56e88d67e5c83234184811bHsin-Yu Chao                               unsigned node_idx,
10520def72b968591065f56e88d67e5c83234184811bHsin-Yu Chao                               unsigned dev_enabled)
10536f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang{
10546f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
10556f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
1056b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic void dev_set_volume(struct cras_iodev *iodev)
1057b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
1058b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
1059b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
1060b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidstatic void dev_set_capture_gain(struct cras_iodev *iodev)
1061b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
1062b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
1063b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
1064c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiangstatic void dev_set_mute(struct cras_iodev *iodev)
1065c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang{
1066c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  set_mute_called++;
1067c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang}
1068c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang
1069e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu ChaoTEST(IoNodePlug, PlugUnplugNode) {
10706f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  struct cras_iodev iodev;
10713b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  struct cras_ionode ionode, ionode2;
10726f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
1073b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&iodev, 0, sizeof(iodev));
1074b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&ionode, 0, sizeof(ionode));
10753b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  memset(&ionode2, 0, sizeof(ionode2));
10766f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  iodev.direction = CRAS_STREAM_INPUT;
10776f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  iodev.update_active_node = update_active_node;
10783b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  ionode.dev = &iodev;
10793b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_add_node(&iodev, &ionode);
10803b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  ionode2.dev = &iodev;
10813b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_add_node(&iodev, &ionode2);
10823b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_set_active_node(&iodev, &ionode);
10836f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang  ResetStubData();
1084786f9d1938966af8e1eb9f60559a3535b5c71ff8Chih-Chung Chang  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_PLUGGED, 1);
1085e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  EXPECT_EQ(0, cras_iodev_list_disable_dev_called);
1086e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_PLUGGED, 0);
1087e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
10883b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao
10893b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  /* Unplug non-active node shouldn't disable iodev. */
10903b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_set_node_attr(&ionode2, IONODE_ATTR_PLUGGED, 1);
10913b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
10923b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  cras_iodev_set_node_attr(&ionode2, IONODE_ATTR_PLUGGED, 0);
10933b90b36068e31abae3bd4a10ace86861c11c18b0Hsin-Yu Chao  EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
10946f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
10956f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
1096b2ad33424e21106930eb23db093746dc30926f27Chih-Chung ChangTEST(IoDev, AddRemoveNode) {
1097b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  struct cras_iodev iodev;
1098b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  struct cras_ionode ionode;
1099b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang
1100b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&iodev, 0, sizeof(iodev));
1101b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  memset(&ionode, 0, sizeof(ionode));
1102b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  ResetStubData();
1103b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  EXPECT_EQ(0, notify_nodes_changed_called);
1104b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  cras_iodev_add_node(&iodev, &ionode);
1105b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  EXPECT_EQ(1, notify_nodes_changed_called);
1106b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  cras_iodev_rm_node(&iodev, &ionode);
1107b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  EXPECT_EQ(2, notify_nodes_changed_called);
1108b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang}
1109b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang
1110c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung ChangTEST(IoDev, SetActiveNode) {
1111c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  struct cras_iodev iodev;
1112c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  struct cras_ionode ionode;
1113c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang
1114c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  memset(&iodev, 0, sizeof(iodev));
1115c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  memset(&ionode, 0, sizeof(ionode));
1116c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  ResetStubData();
1117c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  EXPECT_EQ(0, notify_active_node_changed_called);
1118c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  cras_iodev_set_active_node(&iodev, &ionode);
1119c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  EXPECT_EQ(1, notify_active_node_changed_called);
1120c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang}
1121c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang
1122b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan ReidTEST(IoDev, SetNodeVolume) {
1123b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  struct cras_iodev iodev;
1124b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  struct cras_ionode ionode;
1125b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
1126b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  memset(&iodev, 0, sizeof(iodev));
1127b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  memset(&ionode, 0, sizeof(ionode));
1128b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  iodev.set_volume = dev_set_volume;
1129b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  iodev.set_capture_gain = dev_set_capture_gain;
1130b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  ionode.dev = &iodev;
1131b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  ResetStubData();
1132b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_VOLUME, 10);
1133b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  EXPECT_EQ(1, notify_node_volume_called);
1134b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  iodev.direction = CRAS_STREAM_INPUT;
1135b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_CAPTURE_GAIN, 10);
1136b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid  EXPECT_EQ(1, notify_node_capture_gain_called);
1137b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
1138b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
11393285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi ChiangTEST(IoDev, SetNodeSwapLeftRight) {
11403285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  struct cras_iodev iodev;
11413285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  struct cras_ionode ionode;
11423285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang
11433285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
11443285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
11453285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  iodev.set_swap_mode_for_node = set_swap_mode_for_node;
11463285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  ionode.dev = &iodev;
11473285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  ResetStubData();
11483285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_SWAP_LEFT_RIGHT, 1);
11493285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(1, set_swap_mode_for_node_called);
11503285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(1, set_swap_mode_for_node_enable);
11513285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(1, ionode.left_right_swapped);
11523ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  EXPECT_EQ(1, notify_node_left_right_swapped_called);
11533285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  cras_iodev_set_node_attr(&ionode, IONODE_ATTR_SWAP_LEFT_RIGHT, 0);
11543285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(2, set_swap_mode_for_node_called);
11553285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(0, set_swap_mode_for_node_enable);
11563285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang  EXPECT_EQ(0, ionode.left_right_swapped);
11573ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  EXPECT_EQ(2, notify_node_left_right_swapped_called);
11583285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang}
11593285adee4a1cd81b2dbd22a60b15e5fd9bd33304Cheng-Yi Chiang
1160c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi ChiangTEST(IoDev, SetMute) {
1161c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  struct cras_iodev iodev;
1162c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  int rc;
1163c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang
1164c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1165c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  iodev.set_mute = dev_set_mute;
1166c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
1167c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang
1168c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  ResetStubData();
1169c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  rc = cras_iodev_set_mute(&iodev);
1170c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  EXPECT_EQ(0, rc);
1171c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  EXPECT_EQ(0, set_mute_called);
1172c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang
1173c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
1174c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  rc = cras_iodev_set_mute(&iodev);
1175c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  EXPECT_EQ(0, rc);
1176c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang  EXPECT_EQ(1, set_mute_called);
1177c921f933df5412b85da35d789a63000c44fe48ccCheng-Yi Chiang}
11785342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
11795342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang// Test software volume changes for default output.
11805342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi ChiangTEST(IoDev, SoftwareVolume) {
11815342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  struct cras_iodev iodev;
11825342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  struct cras_ionode ionode;
11835342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
11845342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
11855342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
11865342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  ResetStubData();
11875342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
11885342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.nodes = &ionode;
11895342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node = &ionode;
11905342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node->dev = &iodev;
11915342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
11925342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node->volume = 100;
11935342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.software_volume_needed = 0;
11945342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
11955342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
11965342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  softvol_scalers[80] = 0.5;
11975342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  softvol_scalers[70] = 0.3;
11985342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
11995342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // Check that system volume changes software volume if needed.
12005342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  cras_system_get_volume_return = 80;
12015342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // system_volume - 100 + node_volume = 80 - 100 + 100 = 80
12025342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  EXPECT_FLOAT_EQ(0.5, cras_iodev_get_software_volume_scaler(&iodev));
12035342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
12045342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // Check that node volume changes software volume if needed.
12055342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  iodev.active_node->volume = 90;
12065342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  // system_volume - 100 + node_volume = 80 - 100 + 90 = 70
12075342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  EXPECT_FLOAT_EQ(0.3, cras_iodev_get_software_volume_scaler(&iodev));
12085342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang}
12095342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
1210034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang// Test software gain scaler.
1211034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi ChiangTEST(IoDev, SoftwareGain) {
1212034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  struct cras_iodev iodev;
1213034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  struct cras_ionode ionode;
1214034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
1215034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1216034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  memset(&ionode, 0, sizeof(ionode));
1217034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ResetStubData();
1218034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
1219034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  iodev.nodes = &ionode;
1220034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  iodev.active_node = &ionode;
1221034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  iodev.active_node->dev = &iodev;
1222034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
1223034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.capture_gain= 400;
1224034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.software_volume_needed = 1;
1225034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.max_software_gain = 3000;
1226034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
1227034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // Check that system volume changes software volume if needed.
1228034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  cras_system_get_capture_gain_ret_value = 2000;
1229034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // system_gain + node_gain = 2000 + 400  = 2400
1230034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // 2400 dBm is 15.848931
1231034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(15.848931, cras_iodev_get_software_gain_scaler(&iodev));
1232034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(3000, cras_iodev_maximum_software_gain(&iodev));
1233034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
1234034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  // Software gain scaler should be 1.0 if software gain is not needed.
1235034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  ionode.software_volume_needed = 0;
1236034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(1.0, cras_iodev_get_software_gain_scaler(&iodev));
1237034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  EXPECT_FLOAT_EQ(0, cras_iodev_maximum_software_gain(&iodev));
1238034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang}
1239034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
1240b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// This get_buffer implementation set returned frames larger than requested
1241b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// frames.
1242b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiangstatic int bad_get_buffer(struct cras_iodev *iodev,
1243b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang                          struct cras_audio_area **area,
1244b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang                          unsigned *frames)
1245b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang{
1246b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  *frames = *frames + 1;
1247b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  return 0;
1248b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang}
1249b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
1250b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// Check that if get_buffer implementation returns invalid frames,
1251b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// cras_iodev_get_output_buffer and cras_iodev_get_input_buffer can return
1252b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang// error.
1253b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi ChiangTEST(IoDev, GetBufferInvalidFrames) {
1254b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  struct cras_iodev iodev;
1255b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  struct cras_audio_area **area = NULL;
1256b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  unsigned int frames = 512;
1257b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  struct cras_audio_format fmt;
1258b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
1259b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  // Format is used in cras_iodev_get_input_buffer;
1260b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
1261b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  fmt.frame_rate = 48000;
1262b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  fmt.num_channels = 2;
1263b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
1264b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1265b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
1266b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  ResetStubData();
1267b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
1268b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  iodev.format = &fmt;
1269b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  iodev.get_buffer = bad_get_buffer;
1270b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
1271b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  EXPECT_EQ(-EINVAL, cras_iodev_get_output_buffer(&iodev, area, &frames));
1272b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang  EXPECT_EQ(-EINVAL, cras_iodev_get_input_buffer(&iodev, area, &frames));
1273b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang}
1274b885bf3a81c5a47f7f059fec9c08a527c0a86e58Cheng-Yi Chiang
12752e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chenstatic int open_dev(struct cras_iodev *iodev) {
127624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev->buffer_size = iodev_buffer_size;
127724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  return 0;
127824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao}
127924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
128050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenOutputDeviceNoStart) {
128150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  struct cras_iodev iodev;
128250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
128350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
12842e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  iodev.open_dev = open_dev;
128550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
128650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  ResetStubData();
128750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
128850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
128950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
129050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev_buffer_size = 1024;
12912e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  cras_iodev_open(&iodev, 240);
129250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
129350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
129450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
129550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is no stream run when there is no start ops.
129650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
129750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
129850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
129950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiangint fake_start(const struct cras_iodev *iodev) {
130050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  return 0;
130150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
130250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
130350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenOutputDeviceWithStart) {
130450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  struct cras_iodev iodev;
130550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
130650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
13072e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  iodev.open_dev = open_dev;
130850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
130950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  ResetStubData();
131050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
131150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
131250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.start = fake_start;
131350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
131450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev_buffer_size = 1024;
13152e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  cras_iodev_open(&iodev, 240);
131650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
131750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
131850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
131950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is no stream run when there is start ops.
132050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_OPEN, iodev.state);
132150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
132250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
132350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenInputDeviceNoStart) {
132450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  struct cras_iodev iodev;
132550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
132650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
13272e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  iodev.open_dev = open_dev;
132850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
132950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  ResetStubData();
133050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
133150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
133250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
133350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev_buffer_size = 1024;
13342e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  cras_iodev_open(&iodev, 240);
133550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
133650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
133750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
133850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is normal run when there is start ops.
133950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
134050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang}
134150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
134250cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi ChiangTEST(IoDev, OpenInputDeviceWithStart) {
1343016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  struct cras_iodev iodev;
1344016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1345016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
13462e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  iodev.open_dev = open_dev;
134750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
1348016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  ResetStubData();
1349016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
135050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
135150cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.start = fake_start;
1352016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1353016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev_buffer_size = 1024;
13542e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  cras_iodev_open(&iodev, 240);
1355016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, iodev.max_cb_level);
1356016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(240, iodev.min_cb_level);
135750cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang
135850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  // Test that state is normal run even if there is start ops.
135950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
1360016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang}
1361016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1362dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangstatic int simple_no_stream(struct cras_iodev *dev, int enable)
1363dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang{
1364dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  simple_no_stream_enable = enable;
1365dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  simple_no_stream_called++;
1366dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  return 0;
1367dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
1368dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
136924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu ChaoTEST(IoDev, AddRmStream) {
137024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  struct cras_iodev iodev;
137124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  struct cras_rstream rstream1, rstream2;
137224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  struct dev_stream stream1, stream2;
137324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
137424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  memset(&iodev, 0, sizeof(iodev));
13752e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  iodev.open_dev = open_dev;
1376dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.no_stream = simple_no_stream;
1377dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
137824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  rstream1.cb_threshold = 800;
137924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  stream1.stream = &rstream1;
138024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  rstream2.cb_threshold = 400;
138124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  stream2.stream = &rstream2;
138224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  ResetStubData();
138324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
138424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  iodev_buffer_size = 1024;
13852e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  cras_iodev_open(&iodev, rstream1.cb_threshold);
138624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(0, iodev.max_cb_level);
138724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(512, iodev.min_cb_level);
138824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
138924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  /* min_cb_level should not exceed half the buffer size. */
139024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_add_stream(&iodev, &stream1);
139124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(800, iodev.max_cb_level);
139224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(512, iodev.min_cb_level);
139324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
139424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_add_stream(&iodev, &stream2);
139524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(800, iodev.max_cb_level);
139624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.min_cb_level);
139724cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
139824cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_rm_stream(&iodev, &rstream1);
139924cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.max_cb_level);
140024cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.min_cb_level);
1401dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, simple_no_stream_called);
140224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao
140324cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  /* When all streams are removed, keep the last min_cb_level for draining. */
140424cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  cras_iodev_rm_stream(&iodev, &rstream2);
140524cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(0, iodev.max_cb_level);
140624cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  EXPECT_EQ(400, iodev.min_cb_level);
140785502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang}
140885502b7eea8bb8b4e2b6842d93ca892c2ff10a5aCheng-Yi Chiang
1409cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi ChiangTEST(IoDev, FillZeros) {
1410cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  struct cras_iodev iodev;
1411cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  struct cras_audio_format fmt;
1412cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  unsigned int frames = 50;
1413cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  int16_t *zeros;
1414cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  int rc;
1415cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1416cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  ResetStubData();
1417cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1418cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1419cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
1420cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  fmt.frame_rate = 48000;
1421cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  fmt.num_channels = 2;
1422cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.ext_format = &fmt;
1423cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.get_buffer = get_buffer;
1424cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.put_buffer = put_buffer;
1425cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1426cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
1427cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  rc = cras_iodev_fill_odev_zeros(&iodev, frames);
1428cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(-EINVAL, rc);
1429cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1430cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
1431cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  rc = cras_iodev_fill_odev_zeros(&iodev, frames);
1432cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1433cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(0, rc);
1434cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(frames, put_buffer_nframes);
1435cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  zeros = (int16_t *)calloc(frames * 2, sizeof(*zeros));
1436cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  rc = memcmp(audio_buffer, zeros, frames * 2 * 2);
1437cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  free(zeros);
1438cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang  EXPECT_EQ(0, rc);
1439cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang}
1440cb9882489e765b30ee5318689b51f86648dfd5afCheng-Yi Chiang
1441dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi ChiangTEST(IoDev, DefaultNoStreamPlaybackRunning) {
14421bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  struct cras_iodev iodev;
14431bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  struct cras_audio_format fmt;
14441bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  unsigned int hw_level = 50;
14451bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  unsigned int min_cb_level = 240;
14461bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  unsigned int zeros_to_fill;
14471bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  int16_t *zeros;
14481bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  int rc;
14491bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
14501bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
14511bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
14521bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
14531bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fmt.frame_rate = 48000;
14541bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fmt.num_channels = 2;
14551bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.ext_format = &fmt;
14561bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.min_cb_level = min_cb_level;
14571bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.get_buffer = get_buffer;
14581bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.put_buffer = put_buffer;
14591bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.frames_queued = frames_queued;
14601bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.min_buffer_level = 0;
14611bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
14621bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  iodev.buffer_size = BUFFER_SIZE;
1463016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev.no_stream = no_stream;
1464016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1465016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  ResetStubData();
14661bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
14671bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // Device is running. hw_level is less than target.
14681bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // Need to fill to callback level * 2;
146950cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
14701bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fr_queued = hw_level;
14711bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  zeros_to_fill = min_cb_level * 2 - hw_level;
14721bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
1473dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_default_no_stream_playback(&iodev, 1);
14741bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
14751bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(0, rc);
147650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
14771bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(zeros_to_fill, put_buffer_nframes);
14781bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  zeros = (int16_t *)calloc(zeros_to_fill * 2, sizeof(*zeros));
14791bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(0, memcmp(audio_buffer, zeros, zeros_to_fill * 2 * 2));
14801bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  free(zeros);
14811bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
14821bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  ResetStubData();
14831bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
14841bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // Device is running. hw_level is not less than target.
14851bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  // No need to fill zeros.
148650cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
14871bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  hw_level = min_cb_level * 2;
14881bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  fr_queued = hw_level;
14891bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  zeros_to_fill = 0;
14901bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
1491dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_default_no_stream_playback(&iodev, 1);
14921bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(0, rc);
149350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
14941bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang  EXPECT_EQ(zeros_to_fill, put_buffer_nframes);
1495dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
1496dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1497dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi ChiangTEST(IoDev, PrepareOutputBeforeWriteSamples) {
1498dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct cras_iodev iodev;
1499dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct cras_audio_format fmt;
1500dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  unsigned int min_cb_level = 240;
1501dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  int rc;
1502dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct cras_rstream rstream1;
1503dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct dev_stream stream1;
1504dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  struct cras_iodev_info info;
1505016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1506016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  ResetStubData();
1507016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1508dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rstream1.cb_threshold = min_cb_level;
1509dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  stream1.stream = &rstream1;
1510dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1511dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1512dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1513dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
1514dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  fmt.frame_rate = 48000;
1515dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  fmt.num_channels = 2;
1516dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.ext_format = &fmt;
151764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.format = &fmt;
1518dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.min_cb_level = min_cb_level;
1519dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.get_buffer = get_buffer;
1520dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.put_buffer = put_buffer;
1521dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.frames_queued = frames_queued;
1522dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.min_buffer_level = 0;
1523dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
1524dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.buffer_size = BUFFER_SIZE;
1525dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.no_stream = no_stream;
15262e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  iodev.open_dev = open_dev;
1527dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.start = fake_start;
1528dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.info = info;
1529dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev_buffer_size = BUFFER_SIZE;
1530dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1531dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Open device.
15322e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  cras_iodev_open(&iodev, rstream1.cb_threshold);
1533dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1534dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Add one stream to device.
1535dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  cras_iodev_add_stream(&iodev, &stream1);
1536dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1537dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Case 1: Assume device is not started yet.
1538dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
1539dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Assume sample is not ready yet.
1540dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 0;
1541dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1542dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1543dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1544dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, rc);
1545dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should remain in open state.
1546dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_OPEN, iodev.state);
1547dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, no_stream_called);
1548dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1549dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Assume now sample is ready.
1550dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 100;
1551dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1552dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1553dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1554dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, rc);
1555dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should enter normal run state.
1556dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
1557dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, no_stream_called);
1558dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Need to fill 1 callback level of zeros;
1559dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(min_cb_level, put_buffer_nframes);
1560dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1561dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  ResetStubData();
1562dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1563dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Case 2: Assume device is started and is in no stream state.
156450cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
1565dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Sample is not ready yet.
1566dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 0;
1567dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1568dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1569dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1570016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1571dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should remain in no_stream state.
1572dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NO_STREAM_RUN, iodev.state);
1573dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device in no_stream state should call no_stream ops once.
1574016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(1, no_stream_called);
1575dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(1, no_stream_enable);
1576dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1577dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Assume now sample is ready.
1578dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  dev_stream_playback_frames_ret = 100;
1579dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1580dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1581dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1582dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, rc);
1583dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should enter normal run state.
1584dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
1585dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should call no_stream ops with enable=0 to leave no stream state.
1586dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(2, no_stream_called);
1587016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, no_stream_enable);
1588dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1589dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  ResetStubData();
1590dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1591dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Case 3: Assume device is started and is in normal run state.
1592dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
1593dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1594dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1595dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1596dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, rc);
1597dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device should remain in normal run state.
159850cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  EXPECT_EQ(CRAS_IODEV_STATE_NORMAL_RUN, iodev.state);
1599dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  // Device in no_stream state should call no_stream ops once.
1600dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  EXPECT_EQ(0, no_stream_called);
1601dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
1602dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  ResetStubData();
160364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
160464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Test for device with ramp. Device should start ramping
160564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // when sample is ready.
160664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
160764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume device has ramp member.
160864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.ramp = reinterpret_cast<struct cras_ramp*>(0x1);
160964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
1610f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Case 4.1: Assume device with ramp is started and is in no stream state.
161164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
161264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume sample is ready.
161364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  dev_stream_playback_frames_ret = 100;
161464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
161564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
161664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
161764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Device should start ramping up without setting mute callback.
161864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
161964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_ramp_start_is_called);
162064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_ramp_start_is_up);
1621d4c8bcdbc8df5a1e6c0929e3747f39a9a89dd075Cheng-Yi Chiang  EXPECT_EQ(fmt.frame_rate * RAMP_NEW_STREAM_DURATION_SECS,
162264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang            cras_ramp_start_duration_frames);
162364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(NULL, cras_ramp_start_cb);
162464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(NULL, cras_ramp_start_cb_data);
162564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
162664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
162764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
1628f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Case 4.2: Assume device with ramp is started and is in no stream state.
1629f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  //           But system is muted.
1630f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
1631f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Assume system is muted.
1632f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  cras_system_get_mute_return = 1;
1633f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Assume sample is ready.
1634f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  dev_stream_playback_frames_ret = 100;
1635f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang
1636f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1637f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang
1638f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Device should not start ramping up because system is muted.
1639f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  EXPECT_EQ(0, rc);
1640f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  EXPECT_EQ(0, cras_ramp_start_is_called);
1641f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang
1642f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  ResetStubData();
1643f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang
1644f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Case 5.1: Assume device with ramp is in open state.
164564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
164664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume sample is ready.
164764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  dev_stream_playback_frames_ret = 100;
164864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
164964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
165064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
165164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Device should start ramping up without setting mute callback.
165264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
165364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_ramp_start_is_called);
165464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_ramp_start_is_up);
1655d4c8bcdbc8df5a1e6c0929e3747f39a9a89dd075Cheng-Yi Chiang  EXPECT_EQ(fmt.frame_rate * RAMP_NEW_STREAM_DURATION_SECS,
165664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang            cras_ramp_start_duration_frames);
165764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(NULL, cras_ramp_start_cb);
165864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(NULL, cras_ramp_start_cb_data);
1659f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang
1660f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  ResetStubData();
1661f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang
1662f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Case 5.2: Assume device with ramp is in open state. But system is muted.
1663f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
1664f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Assume system is muted.
1665f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  cras_system_get_mute_return = 1;
1666f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Assume sample is ready.
1667f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  dev_stream_playback_frames_ret = 100;
1668f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang
1669f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  rc = cras_iodev_prepare_output_before_write_samples(&iodev);
1670f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang
1671f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  // Device should not start ramping up because system is muted.
1672f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  EXPECT_EQ(0, rc);
1673f39a21b14e8991554281d25997e44f5914a150bbCheng-Yi Chiang  EXPECT_EQ(0, cras_ramp_start_is_called);
167464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
167564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
167664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi ChiangTEST(IoDev, StartRampUp) {
167764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_iodev iodev;
167864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  int rc;
167964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_audio_format fmt;
168064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  enum CRAS_IODEV_RAMP_REQUEST req;
168164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
168264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
168364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Format will be used in cras_iodev_start_ramp to determine ramp duration.
168464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
168564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.frame_rate = 48000;
168664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.num_channels = 2;
168764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.format = &fmt;
168864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
168964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume device has ramp member.
169064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.ramp = reinterpret_cast<struct cras_ramp*>(0x1);
169164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
169264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Case 1: Device is not opened yet.
169364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
169464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
169564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  req = CRAS_IODEV_RAMP_REQUEST_UP_UNMUTE;
169664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
169764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_start_ramp(&iodev, req);
169864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
169964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Ramp request is ignored.
170064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
170164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_ramp_start_is_called);
170264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
170364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Case 2: Ramp up without mute.
170464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
170564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
170664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  req = CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK;
170764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
170864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_start_ramp(&iodev, req);
170964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
171064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Device should start ramping up without setting mute callback.
171164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
171264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_ramp_start_is_called);
171364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_ramp_start_is_up);
1714d4c8bcdbc8df5a1e6c0929e3747f39a9a89dd075Cheng-Yi Chiang  EXPECT_EQ(fmt.frame_rate * RAMP_NEW_STREAM_DURATION_SECS,
171564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang            cras_ramp_start_duration_frames);
171664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(NULL, cras_ramp_start_cb);
171764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(NULL, cras_ramp_start_cb_data);
171864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
171964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Case 3: Ramp up for unmute.
172064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
172164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
172264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  req = CRAS_IODEV_RAMP_REQUEST_UP_UNMUTE;
172364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
172464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_start_ramp(&iodev, req);
172564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
172664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Device should start ramping up.
172764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
172864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_ramp_start_is_called);
172964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_ramp_start_is_up);
1730d4c8bcdbc8df5a1e6c0929e3747f39a9a89dd075Cheng-Yi Chiang  EXPECT_EQ(fmt.frame_rate * RAMP_UNMUTE_DURATION_SECS,
173164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang            cras_ramp_start_duration_frames);
173264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Callback for unmute is not used.
173364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(NULL, cras_ramp_start_cb);
173464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Device mute state is set after ramping starts.
173564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_device_monitor_set_device_mute_state_called);
173664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(&iodev, cras_device_monitor_set_device_mute_state_dev);
173764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
173864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
173964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi ChiangTEST(IoDev, StartRampDown) {
174064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_iodev iodev;
174164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  int rc;
174264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  struct cras_audio_format fmt;
174364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  enum CRAS_IODEV_RAMP_REQUEST req;
174464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
174564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
174664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Format will be used in cras_iodev_start_ramp to determine ramp duration.
174764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
174864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.frame_rate = 48000;
174964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  fmt.num_channels = 2;
175064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.format = &fmt;
175164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
175264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume device has ramp member.
175364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.ramp = reinterpret_cast<struct cras_ramp*>(0x1);
175464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
175564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Case 1: Device is not opened yet.
175664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
175764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
175864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  req = CRAS_IODEV_RAMP_REQUEST_DOWN_MUTE;
175964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
176064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_start_ramp(&iodev, req);
176164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
176264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Ramp request is ignored.
176364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
176464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_ramp_start_is_called);
176564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
176664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Case 2: Ramp down for mute.
176764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  ResetStubData();
176864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
176964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  req = CRAS_IODEV_RAMP_REQUEST_DOWN_MUTE;
177064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
177164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  rc = cras_iodev_start_ramp(&iodev, req);
177264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
177364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Device should start ramping down with mute callback.
177464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, rc);
177564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_ramp_start_is_called);
177664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_ramp_start_is_up);
1777d4c8bcdbc8df5a1e6c0929e3747f39a9a89dd075Cheng-Yi Chiang  EXPECT_EQ(fmt.frame_rate * RAMP_MUTE_DURATION_SECS,
177864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang            cras_ramp_start_duration_frames);
177964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
178064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Device mute state is not set yet. It should wait for ramp to finish.
178164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(0, cras_device_monitor_set_device_mute_state_called);
178264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(NULL, cras_device_monitor_set_device_mute_state_dev);
178364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
178464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // Assume the callback is set, and it is later called after ramp is done.
178564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  // It should trigger cras_device_monitor_set_device_mute_state.
178664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_cb(cras_ramp_start_cb_data);
178764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(1, cras_device_monitor_set_device_mute_state_called);
178864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  EXPECT_EQ(&iodev, cras_device_monitor_set_device_mute_state_dev);
17891bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang}
17901bb02937ca9072624d74ff1032b63dc2e17a2229Cheng-Yi Chiang
1791103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi ChiangTEST(IoDev, OutputDeviceShouldWake) {
1792103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  struct cras_iodev iodev;
1793103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  int rc;
1794103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1795103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1796103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1797103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  ResetStubData();
1798103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1799103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is not running. No need to wake for this device.
180050cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_OPEN;
1801103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1802103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1803103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1804103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. Need to wake for this device.
180550cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
1806103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1807103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(1, rc);
1808103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1809016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  // Device is running. Device has output_should_wake ops.
1810016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  iodev.output_should_wake = output_should_wake;
1811016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  output_should_wake_ret = 0;
1812016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1813016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1814016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1815016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  // Device is running. Device has output_should_wake ops.
1816016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  output_should_wake_ret = 1;
1817016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1818016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang  EXPECT_EQ(1, rc);
1819016277914b2ab40298e86145a25f8cb3cd22b790Cheng-Yi Chiang
1820103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Ignore input device.
1821103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_INPUT;
1822103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  rc = cras_iodev_odev_should_wake(&iodev);
1823103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(0, rc);
1824103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang}
1825103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1826103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi ChiangTEST(IoDev, FramesToPlayInSleep) {
1827103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  struct cras_iodev iodev;
1828103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  unsigned int min_cb_level = 240, hw_level;
1829103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  unsigned int got_hw_level, got_frames;
1830fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  struct timespec hw_tstamp;
1831103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1832103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1833103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.frames_queued = frames_queued;
1834103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.min_buffer_level = 0;
1835103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
1836103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.buffer_size = BUFFER_SIZE;
1837103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.min_cb_level = min_cb_level;
1838103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1839103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  ResetStubData();
1840103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1841103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. There is at least one stream for this device.
1842103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // hw_level is greater than min_cb_level.
184350cf4aec95391fb7768d9a98e35e618edc7443f3Cheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
1844103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  hw_level = min_cb_level + 50;
1845103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  fr_queued = hw_level;
1846103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.streams = reinterpret_cast<struct dev_stream *>(0x1);
1847103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1848fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  got_frames = cras_iodev_frames_to_play_in_sleep(
1849fa4cd9766aec6eae544b1078ed835687c4e74617John Muir                   &iodev, &got_hw_level, &hw_tstamp);
1850103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_hw_level);
1851103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_frames);
1852103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1853103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. There is no stream for this device.
1854103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // hw_level is greater than min_cb_level.
1855103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.streams = NULL;
1856103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1857fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  got_frames = cras_iodev_frames_to_play_in_sleep(
1858fa4cd9766aec6eae544b1078ed835687c4e74617John Muir                   &iodev, &got_hw_level, &hw_tstamp);
1859103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_hw_level);
1860103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level - min_cb_level, got_frames);
1861103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1862103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // Device is running. There is no stream for this device.
1863103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  // hw_level is less than min_cb_level.
1864103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  iodev.streams = NULL;
1865103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  hw_level = min_cb_level - 50;
1866103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  fr_queued = hw_level;
1867103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1868fa4cd9766aec6eae544b1078ed835687c4e74617John Muir  got_frames = cras_iodev_frames_to_play_in_sleep(
1869fa4cd9766aec6eae544b1078ed835687c4e74617John Muir                   &iodev, &got_hw_level, &hw_tstamp);
1870103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(hw_level, got_hw_level);
1871103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang  EXPECT_EQ(0, got_frames);
1872103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang}
1873103c80cc42d08844f1918e6e394531cb86d94254Cheng-Yi Chiang
1874595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiangstatic unsigned int get_num_underruns(const struct cras_iodev *iodev) {
1875595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  return get_num_underruns_ret;
1876595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang}
1877595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang
1878595b415568beb0048c31e3111c5c935530be1032Cheng-Yi ChiangTEST(IoDev, GetNumUnderruns) {
1879595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  struct cras_iodev iodev;
1880595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1881595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang
1882595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  EXPECT_EQ(0, cras_iodev_get_num_underruns(&iodev));
1883595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang
1884595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  iodev.get_num_underruns = get_num_underruns;
1885595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  get_num_underruns_ret = 10;
1886595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang  EXPECT_EQ(10, cras_iodev_get_num_underruns(&iodev));
1887595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang}
1888595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang
1889ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi ChiangTEST(IoDev, RequestReset) {
1890ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  struct cras_iodev iodev;
1891ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
1892ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
1893ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  ResetStubData();
1894ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
18952e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  iodev.open_dev = open_dev;
1896ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
1897ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
1898ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  iodev.state = CRAS_IODEV_STATE_CLOSE;
1899ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  iodev_buffer_size = 1024;
1900ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
1901ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  // Open device.
19022e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  cras_iodev_open(&iodev, 240);
1903ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
1904ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  // The first reset request works.
1905ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  EXPECT_EQ(0, cras_iodev_reset_request(&iodev));
1906ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  EXPECT_EQ(1, device_monitor_reset_device_called);
1907ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
1908ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  // The second reset request will do nothing.
1909ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  EXPECT_EQ(0, cras_iodev_reset_request(&iodev));
1910ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  EXPECT_EQ(1, device_monitor_reset_device_called);
1911ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
1912ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  // Assume device is opened again.
19132e14c232763ac89fd9d2fa5e9b3fdcf6581b2db8Chinyue Chen  cras_iodev_open(&iodev, 240);
1914ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
1915ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  // The reset request works.
1916ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  EXPECT_EQ(0, cras_iodev_reset_request(&iodev));
1917ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  EXPECT_EQ(2, device_monitor_reset_device_called);
1918ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang}
1919ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
19205c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiangstatic int output_underrun(struct cras_iodev *iodev) {
19215c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  output_underrun_called++;
19225c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  return 0;
19235c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang}
19245c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang
19255c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang
19265c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi ChiangTEST(IoDev, HandleOutputUnderrun) {
19275c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  struct cras_iodev iodev;
19285c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  struct cras_audio_format fmt;
19295c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  unsigned int frames = 240;
19305c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  int16_t *zeros;
19315c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  int rc;
19325c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang
19335c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  ResetStubData();
19345c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang
19355c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  memset(&iodev, 0, sizeof(iodev));
19365c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  fmt.format = SND_PCM_FORMAT_S16_LE;
19375c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  fmt.frame_rate = 48000;
19385c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  fmt.num_channels = 2;
19395c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  iodev.ext_format = &fmt;
19405c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  iodev.get_buffer = get_buffer;
19415c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  iodev.put_buffer = put_buffer;
19425c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  iodev.direction = CRAS_STREAM_OUTPUT;
19435c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  iodev.min_cb_level = frames;
19445c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang
19455c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  // Default case, fill one block of zeros.
19465c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  EXPECT_EQ(0, cras_iodev_output_underrun(&iodev));
19475c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang
19485c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  EXPECT_EQ(frames, put_buffer_nframes);
19495c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  zeros = (int16_t *)calloc(frames * 2, sizeof(*zeros));
19505c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  rc = memcmp(audio_buffer, zeros, frames * 2 * 2);
19515c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  free(zeros);
19525c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  EXPECT_EQ(0, rc);
19535c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang
19545c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  // Test iodev has output_underrun ops.
19555c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  iodev.output_underrun = output_underrun;
19565c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  EXPECT_EQ(0, cras_iodev_output_underrun(&iodev));
19575c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang  EXPECT_EQ(1, output_underrun_called);
19585c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang}
19595c414105d8ec3c6db465ffa819da817747d9a379Cheng-Yi Chiang
1960838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidextern "C" {
1961838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1962838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid//  From libpthread.
1963838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidint pthread_create(pthread_t *thread, const pthread_attr_t *attr,
1964838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid                   void *(*start_routine)(void*), void *arg) {
1965838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  return 0;
1966838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
1967838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1968838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidint pthread_join(pthread_t thread, void **value_ptr) {
1969838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  return 0;
1970838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
1971838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
1972f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao// From audio_thread
1973f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chaostruct cras_fmt_conv *audio_thread_get_global_remix_converter()
1974f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao{
1975f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao  return NULL;
1976f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao}
1977f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao
1978f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao// Fromt fmt_conv
1979f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chaovoid cras_channel_remix_convert(struct cras_fmt_conv *conv,
1980f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao    uint8_t *in_buf,
1981f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao    size_t frames)
1982f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao{
1983f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao}
1984f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao
1985fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid// From buffer_share
1986fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidstruct buffer_share *buffer_share_create(unsigned int buf_sz) {
1987fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return NULL;
1988fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1989fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1990fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidvoid buffer_share_destroy(struct buffer_share *mix)
1991fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid{
1992fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1993fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1994fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidint buffer_share_offset_update(struct buffer_share *mix, unsigned int id,
1995fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid                               unsigned int frames) {
1996fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
1997fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
1998fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
1999fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidunsigned int buffer_share_get_new_write_point(struct buffer_share *mix) {
2000fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
2001fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
2002fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
2003fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidint buffer_share_add_id(struct buffer_share *mix, unsigned int id) {
2004fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
2005fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
2006fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
2007fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidint buffer_share_rm_id(struct buffer_share *mix, unsigned int id) {
2008fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
2009fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
2010fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
2011fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reidunsigned int buffer_share_id_offset(const struct buffer_share *mix,
2012fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid                                    unsigned int id)
2013fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid{
2014fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid  return 0;
2015fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid}
2016fd73a24e3fcb3de2efdf8fd0091b104c69fd62f4Dylan Reid
2017386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid// From cras_system_state.
201857852ea82d5f4c4491f4cfe9faafc5cbddfc4979Cheng-Yi Chiangvoid cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction) {
2019386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid}
2020386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid
202157852ea82d5f4c4491f4cfe9faafc5cbddfc4979Cheng-Yi Chiangvoid cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction) {
2022386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid}
2023386ab71e324831d632544f8bcecc8d0ba1890f01Dylan Reid
20245b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang// From cras_dsp
2025aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidstruct cras_dsp_context *cras_dsp_context_new(int sample_rate,
20265b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang                                              const char *purpose)
20275b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang{
2028ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_sample_rate = sample_rate;
2029ccff36a4576d4810784f0b0ae5fe32a5fbcbe3c4Chih-Chung Chang  dsp_context_new_purpose = purpose;
20302db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid  return cras_dsp_context_new_return;
20315b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang}
20325b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
20335b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Changvoid cras_dsp_context_free(struct cras_dsp_context *ctx)
20345b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang{
20355fa790469656d3e093799329f814756600762a71Dylan Reid  dsp_context_free_called++;
20365b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang}
20375b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
20385b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Changvoid cras_dsp_load_pipeline(struct cras_dsp_context *ctx)
20395b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang{
20405b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang}
20415b1717f92baa7ab7006e04431bd6b33a24d8a23fChih-Chung Chang
20424f86aad321250a527075476dac94241c24817521Cheng-Yi Chiangvoid cras_dsp_set_variable_string(struct cras_dsp_context *ctx, const char *key,
20434f86aad321250a527075476dac94241c24817521Cheng-Yi Chiang                                  const char *value)
20447057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang{
20457057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang}
20467057df0d12f641d9bd9aad64d3aa09127a4e84a3Chih-Chung Chang
2047c9f56d936f63f56186b6daaa3f0c9abed828531aCheng-Yi Chiangvoid cras_dsp_set_variable_boolean(struct cras_dsp_context *ctx,
2048c9f56d936f63f56186b6daaa3f0c9abed828531aCheng-Yi Chiang                                   const char *key,
2049c9f56d936f63f56186b6daaa3f0c9abed828531aCheng-Yi Chiang                                   char value)
2050c9f56d936f63f56186b6daaa3f0c9abed828531aCheng-Yi Chiang{
2051c9f56d936f63f56186b6daaa3f0c9abed828531aCheng-Yi Chiang}
2052c9f56d936f63f56186b6daaa3f0c9abed828531aCheng-Yi Chiang
2053d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidstruct pipeline *cras_dsp_get_pipeline(struct cras_dsp_context *ctx)
2054d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
2055d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_get_pipeline_called++;
2056d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return reinterpret_cast<struct pipeline *>(cras_dsp_get_pipeline_ret);
2057d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2058d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
2059d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidvoid cras_dsp_put_pipeline(struct cras_dsp_context *ctx)
2060d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
2061d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_put_pipeline_called++;
2062d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2063d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
2064d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidfloat *cras_dsp_pipeline_get_source_buffer(struct pipeline *pipeline,
2065d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid					   int index)
2066d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
2067d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_source_buffer_called++;
2068d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return cras_dsp_pipeline_source_buffer[index];
2069d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2070d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
2071d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidfloat *cras_dsp_pipeline_get_sink_buffer(struct pipeline *pipeline, int index)
2072d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
2073d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_sink_buffer_called++;
2074d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return cras_dsp_pipeline_sink_buffer[index];
2075d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2076d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
2077d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidint cras_dsp_pipeline_get_delay(struct pipeline *pipeline)
2078d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
2079d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_get_delay_called++;
2080d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return 0;
2081d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2082d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
2083aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidvoid cras_dsp_pipeline_apply(struct pipeline *pipeline,
2084d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid			     uint8_t *buf, unsigned int frames)
2085d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
2086d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_called++;
2087d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_dsp_pipeline_apply_sample_count = frames;
2088d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2089d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
2090d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidvoid cras_dsp_pipeline_add_statistic(struct pipeline *pipeline,
2091d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                                     const struct timespec *time_delta,
2092d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                                     int samples)
2093d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid{
2094d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2095d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
2096aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidunsigned int cras_dsp_num_output_channels(const struct cras_dsp_context *ctx)
2097aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid{
20982db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid	return cras_dsp_num_output_channels_return;
2099aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid}
2100aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid
2101aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reidunsigned int cras_dsp_num_input_channels(const struct cras_dsp_context *ctx)
2102aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid{
21032db05743bb5c0c626b49ea19f3b759c0351e98d7Dylan Reid	return cras_dsp_num_input_channels_return;
2104aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid}
2105aa66420d69c297eec83e1b5a17b0b2cf06cddfd5Dylan Reid
2106d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid// From audio thread
2107d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reidint audio_thread_post_message(struct audio_thread *thread,
2108d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid                              struct audio_thread_msg *msg) {
2109d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid  return 0;
2110d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid}
2111d6957a4d295e22b427af40ff4dd29c4d14514d7fDylan Reid
2112ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changvoid cras_iodev_list_select_node(enum CRAS_STREAM_DIRECTION direction,
2113ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang                                 cras_node_id_t node_id)
2114f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Chang{
2115ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_called++;
2116ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_direction = direction;
2117ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  select_node_id = node_id;
2118f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Chang}
2119f1a7e0c094f29c16f6aa9f97d328a93769e69e5cChih-Chung Chang
2120ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Changint cras_iodev_list_node_selected(struct cras_ionode *node)
21216f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang{
2122ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang  return node == node_selected;
21236f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang}
21246f0a5e6a967558105f37513801af573167890f67Chih-Chung Chang
2125e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chaovoid cras_iodev_list_disable_dev(struct cras_iodev *dev)
2126e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao{
2127e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao  cras_iodev_list_disable_dev_called++;
2128e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao}
2129e53b58efa0e284527ed48cd429b6c87c18cfd0bfHsin-Yu Chao
2130b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Changvoid cras_iodev_list_notify_nodes_changed()
2131b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang{
2132b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang  notify_nodes_changed_called++;
2133b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang}
2134b2ad33424e21106930eb23db093746dc30926f27Chih-Chung Chang
2135dc115f02e335a6d197b6ef4bf0516e4866a7fc6eDylan Reidvoid cras_iodev_list_notify_active_node_changed(
2136dc115f02e335a6d197b6ef4bf0516e4866a7fc6eDylan Reid				enum CRAS_STREAM_DIRECTION direction)
2137c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang{
2138c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang  notify_active_node_changed_called++;
2139c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang}
2140c732e27a905ddce9ccb4507bec7431b6406fdda4Chih-Chung Chang
2141b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidvoid cras_iodev_list_notify_node_volume(struct cras_ionode *node)
2142b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
2143b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid	notify_node_volume_called++;
2144b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
2145b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
2146b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reidvoid cras_iodev_list_notify_node_capture_gain(struct cras_ionode *node)
2147b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid{
2148b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid	notify_node_capture_gain_called++;
2149b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid}
2150b6670c0295704e171c518e7ae9fd9a2c6f88f535Dylan Reid
21513ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiangvoid cras_iodev_list_notify_node_left_right_swapped(struct cras_ionode *node)
21523ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang{
21533ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang  notify_node_left_right_swapped_called++;
21543ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang}
21553ac00e542de73e404423161a412b04b64fe7d847Cheng-Yi Chiang
21569690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chaostruct cras_audio_area *cras_audio_area_create(int num_channels) {
21579690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao	return NULL;
21589690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao}
21599690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao
21609690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chaovoid cras_audio_area_destroy(struct cras_audio_area *area) {
21619690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao}
21629690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao
21639690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chaovoid cras_audio_area_config_channels(struct cras_audio_area *area,
21649690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao                                     const struct cras_audio_format *fmt) {
21659690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao}
21669690a3281b7167e5a38368fd8db39375bea8a1f8Hsin-Yu Chao
21677b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chaoint cras_audio_format_set_channel_layout(struct cras_audio_format *format,
21687b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao					 const int8_t layout[CRAS_CH_MAX])
21697b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao{
2170a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  int i;
2171a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  cras_audio_format_set_channel_layout_called++;
2172a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao  for (i = 0; i < CRAS_CH_MAX; i++)
2173a8a86fe67e3cc98173c9bf4e219262a619c0670aHsin-Yu Chao    format->channel_layout[i] = layout[i];
21747b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao  return 0;
21757b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao}
21767b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao
21775342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangfloat softvol_get_scaler(unsigned int volume_index)
21785342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang{
21795342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang	return softvol_scalers[volume_index];
21805342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang}
21815342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang
21825342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiangsize_t cras_system_get_volume() {
21835342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang  return cras_system_get_volume_return;
21845342a08d8e1f5c3c6205e7c6d2d40ab47280f3a3Cheng-Yi Chiang}
21857b7d64a58cdc405c76b7df32c8042050b9c8bf4aHsin-Yu Chao
2186034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chianglong cras_system_get_capture_gain() {
2187034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang  return cras_system_get_capture_gain_ret_value;
2188034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang}
2189034f0437c330515bb73bbe6e13271f1e1572bbbaCheng-Yi Chiang
2190d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidint cras_system_get_mute() {
21911c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  return cras_system_get_mute_return;
2192d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2193d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
2194d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidint cras_system_get_capture_mute() {
2195d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return 0;
2196d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2197d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
2198249e72919eb928e107d251b262c305a8fe531641Dylan Reidvoid cras_scale_buffer(snd_pcm_format_t fmt, uint8_t *buffer,
21991efd30f3854ac69a6916bdeaa82dae3f01d18acaDylan Reid                       unsigned int count, float scaler) {
220064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_called++;
2201249e72919eb928e107d251b262c305a8fe531641Dylan Reid  cras_scale_buffer_fmt = fmt;
22021c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  cras_scale_buffer_scaler = scaler;
2203d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2204d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
220564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangvoid cras_scale_buffer_increment(snd_pcm_format_t fmt, uint8_t *buff,
220664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang                                 unsigned int frame, float scaler,
220764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang                                 float increment, int channel)
220864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang{
220964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_fmt = fmt;
221064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_buff = buff;
221164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_frame = frame;
221264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_scaler = scaler;
221364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_increment = increment;
221464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_scale_buffer_increment_channel = channel;
221564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
221664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
2217d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reidsize_t cras_mix_mute_buffer(uint8_t *dst,
2218d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                            size_t frame_bytes,
2219d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid                            size_t count) {
2220d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  cras_mix_mute_count = count;
2221d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid  return count;
2222d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid}
2223d3f0c13098e8c6373a6912f6e963ea460cacb432Dylan Reid
222465ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidstruct rate_estimator *rate_estimator_create(unsigned int rate,
222565ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid                                             const struct timespec *window_size,
222665ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid                                             double smooth_factor) {
222765ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid  return NULL;
222865ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
222965ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
223065ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidvoid rate_estimator_destroy(struct rate_estimator *re) {
223165ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
223265ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
223365ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidvoid rate_estimator_add_frames(struct rate_estimator *re, int fr) {
22341c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_called++;
22351c3dbf26145ecd84b58c27f934f0bdde0458fa38Dylan Reid  rate_estimator_add_frames_num_frames = fr;
223665ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
223765ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
223865ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidint rate_estimator_check(struct rate_estimator *re, int level,
223965ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid                         struct timespec *now) {
224065ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid  return 0;
224165ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
224265ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
224365ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reidvoid rate_estimator_reset_rate(struct rate_estimator *re, unsigned int rate) {
224465ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
224565ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
224665ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reiddouble rate_estimator_get_rate(struct rate_estimator *re) {
224765ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid  return 0.0;
224865ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid}
224965ee52aacc676ac2ecabadd6072a4dfffec61312Dylan Reid
2250c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chaounsigned int dev_stream_cb_threshold(const struct dev_stream *dev_stream) {
225124cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao  if (dev_stream->stream)
225224cd7e982a045254b20e9a84830072ffa8f18180Hsin-Yu Chao    return dev_stream->stream->cb_threshold;
2253c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chao  return 0;
2254c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chao}
2255c2c6a6e97e5534a4717ecec3ccb811e4af887279Hsin-Yu Chao
2256dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangint dev_stream_attached_devs(const struct dev_stream *dev_stream) {
2257dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  return 1;
2258dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
2259dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
2260dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangvoid dev_stream_update_frames(const struct dev_stream *dev_stream) {
2261dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
2262dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
2263dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiangint dev_stream_playback_frames(const struct dev_stream *dev_stream) {
2264dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang  return dev_stream_playback_frames_ret;
2265dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang}
2266dc3ecc8a040d22a32ca517af46792600e4340f0aCheng-Yi Chiang
2267ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiangint cras_device_monitor_reset_device(struct cras_iodev *iodev) {
2268ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  device_monitor_reset_device_called++;
2269ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang  return 0;
2270ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang}
2271ea4fbbbba357beeeba532949ef88295bdf1e221fCheng-Yi Chiang
227264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangvoid cras_ramp_destroy(struct cras_ramp* ramp) {
227364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  return;
227464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
227564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
227664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangint cras_ramp_start(struct cras_ramp *ramp, int is_up, int duration_frames,
227764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang                    cras_ramp_cb cb, void *cb_data)
227864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang{
227964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_is_called++;
228064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_is_up = is_up;
228164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_duration_frames = duration_frames;
228264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_cb = cb;
228364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_start_cb_data = cb_data;
228464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  return 0;
228564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
228664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
228764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangint cras_ramp_reset(struct cras_ramp *ramp) {
228864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_reset_is_called++;
228964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  return 0;
229064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
229164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
229264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangstruct cras_ramp_action cras_ramp_get_current_action(
229364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang    const struct cras_ramp *ramp) {
229464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  return cras_ramp_get_current_action_ret;
229564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
229664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
229764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangint cras_ramp_update_ramped_frames(
229864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang    struct cras_ramp *ramp, int num_frames) {
229964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_ramp_update_ramped_frames_num_frames = num_frames;
230064350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  return 0;
230164350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
230264350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
230364350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiangint cras_device_monitor_set_device_mute_state(struct cras_iodev *iodev)
230464350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang{
230564350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_device_monitor_set_device_mute_state_called++;
230664350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  cras_device_monitor_set_device_mute_state_dev = iodev;
230764350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang  return 0;
230864350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang}
230964350200f69f730bbb1eb33a648c8dd6c840da0bCheng-Yi Chiang
2310838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}  // extern "C"
2311838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}  //  namespace
2312838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid
2313838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reidint main(int argc, char **argv) {
2314838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid  ::testing::InitGoogleTest(&argc, argv);
231539c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang  int rc = RUN_ALL_TESTS();
231639c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang
231739c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang  audio_thread_event_log_deinit(atlog);
231839c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang  return rc;
2319838597c9ca04f19584c6fbcc78ee5f417c1528bfDylan Reid}
2320